-
Notifications
You must be signed in to change notification settings - Fork 23.1k
Add CSS @custom-media at-rule
#42075
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
58 commits
Select commit
Hold shift + click to select a range
17fc9de
Add CSS `@custom-media` at-rule
ramiy 3ae1b84
Add CSS `@custom-media` at-rule
ramiy 6935fdd
Add CSS `@custom-media` at-rule
ramiy 4df88ca
Merge branch 'main' into custom-media
ramiy a0b79e7
Add CSS `@custom-media` at-rule
ramiy 54a7f3f
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy ae8d414
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy 2bc4149
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy 0587e26
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy 1065113
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy 9c0db2d
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy c21a91e
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy ff0162f
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy 670e381
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy 19232bd
Update
ramiy 56274d7
Update
ramiy 7cf968b
Update
ramiy b39d94e
Update
ramiy 1572b3b
Update
ramiy 25c4c40
Update
ramiy 85ac344
Update
ramiy 68dfa79
Update
ramiy 6955438
Update
ramiy 0197069
Update
ramiy 6a96383
Update
ramiy ebcf14a
Update files/en-us/web/css/reference/values/rule-list/index.md
ramiy 0a1b00f
Update
ramiy c280f73
Update
ramiy 6de6d98
Update
ramiy ae95f48
Update
ramiy 1156bdd
Update
ramiy 33f75a0
Update
ramiy 0b73928
Merge branch 'main' into custom-media
ramiy 8706498
Update files/en-us/mozilla/firefox/experimental_features/index.md
ramiy 71f75fd
Update files/en-us/web/api/cssstylesheet/insertrule/index.md
ramiy 6837f45
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy b7d4752
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy 7269318
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy e25222b
Update files/en-us/web/css/reference/values/rule-list/index.md
ramiy 3731efb
Apply suggestions from code review
ramiy ddd640e
Apply suggestions from code review
ramiy 5764a78
Apply suggestions from code review
ramiy 37f16ec
Merge branch 'main' into custom-media
ramiy c3ec19f
Apply suggestions from code review
ramiy acb5596
Merge branch 'main' into custom-media
caugner 31efde1
Update
ramiy 9c4ef79
Simplify the section about evaluating media queries with logical oper…
ramiy 064d21a
Update logical operators
ramiy 57d5b9a
Apply suggestions from code review
ramiy a81a489
Add another example - overriding existing rules
ramiy af66af2
Update the `or` operator
ramiy 32c9df4
Update the `or` operator
ramiy 51692d2
Update syntax values
ramiy 14c08e5
Update syntax values
ramiy 8794646
Merge branch 'main' into custom-media
ramiy d3199f2
Update files/en-us/mozilla/firefox/experimental_features/index.md
chrisdavidmills c509e03
Merge branch 'main' into custom-media
chrisdavidmills 337b5fa
Small tweak
chrisdavidmills File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
239 changes: 239 additions & 0 deletions
239
files/en-us/web/css/reference/at-rules/@custom-media/index.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,239 @@ | ||
| --- | ||
| title: "@custom-media" | ||
| slug: Web/CSS/Reference/At-rules/@custom-media | ||
| page-type: css-at-rule | ||
| status: | ||
| - experimental | ||
| browser-compat: css.at-rules.custom-media | ||
| --- | ||
|
|
||
| {{CSSRef}}{{SeeCompatTable}} | ||
|
|
||
| The **`@custom-media`** CSS [at-rule](/en-US/docs/Web/CSS/Reference/At-rules) defines aliases for long or complex [media queries](/en-US/docs/Web/CSS/Guides/Media_queries). Instead of repeating the same hardcoded `<media-query-list>` in multiple [`@media`](/en-US/docs/Web/CSS/Reference/At-rules/@media) at-rules, it can be defined once in a `@custom-media` at-rule and referenced throughout the stylesheet whenever needed. | ||
|
|
||
| ## Syntax | ||
|
|
||
| ```css | ||
| @custom-media <extension-name> [<media-query-list> | true | false ]; | ||
|
|
||
| @custom-media --media-query-name (width < 1200px); | ||
| @custom-media --media-query-name (width < 1200px), (orientation: portrait); | ||
| ``` | ||
|
|
||
| ### Values | ||
|
|
||
| - `<extension-name>` | ||
| - : A [`<dashed-ident>`](/en-US/docs/Web/CSS/Reference/Values/dashed-ident); the name identifying the custom media query. | ||
| - Represented value | ||
| - : The value aliased by the custom media query. Possible values are: | ||
| - `<media-query-list>` | ||
| - : A comma-separated [list of `<media-query>` values](/en-US/docs/Web/CSS/Reference/At-rules/@media#description). | ||
| - `true` | ||
| - : The `@custom-media` value always evaluates to `true`. | ||
| - `false` | ||
| - : The `@custom-media` value always evaluates to `false`. | ||
|
|
||
| ## Description | ||
|
|
||
| When building responsive interfaces, the same media condition often needs to be repeated across multiple [`@media`](/en-US/docs/Web/CSS/Reference/At-rules/@media) at-rules, sometimes across different files and teams. Duplicating media queries increases the risk of mistakes, makes refactoring harder, and creates unnecessary maintenance overhead. Any time a media query changes, every instance must be found and updated manually — a process that can be both error-prone and difficult to track in large codebases. | ||
|
|
||
| The `@custom-media` at-rule solves this problem by letting you define **named aliases** for media queries. Instead of repeating the full media query everywhere, you declare the media condition once as a custom media query and reference its alias throughout your stylesheets. With this in place, updating the underlying media query requires a single change in one location. | ||
|
|
||
| Custom media queries can be composed from others by referencing their alias names inside the media query features. This enables building more expressive, layered conditions. However, a custom media query cannot refer to itself, nor can it form part of a circular chain of references. Any circular dependency — direct or indirect — invalidates all custom media queries involved in that loop. | ||
|
|
||
| If multiple `@custom-media` rules define the same `<dashed-ident>` name, only the last declaration in the source order applies. All earlier declarations are ignored. | ||
|
|
||
| ### Evaluating media queries with logical operators | ||
|
|
||
| Custom media queries accept the full range of CSS logical operators — `not`, `and`, and `or` (comma-separated or using the `or` keyword). | ||
|
|
||
| Because a `@custom-media` value is just a normal `<media-query-list>`, you can combine, invert, or group conditions exactly as you would in a regular `@media` rule. | ||
|
|
||
| #### Using the `not` operator | ||
|
|
||
| The `not` operator negates an entire media condition. This is useful when you want a rule to apply only when a specific condition is `false`. | ||
|
|
||
| ```css | ||
| @custom-media --no-script not (script); | ||
|
|
||
| @media (--no-script) { | ||
| } | ||
| ``` | ||
|
|
||
| #### Using the `and` operator | ||
|
|
||
| The `and` operator lets you combine multiple conditions that must all be `true`. | ||
|
|
||
| ```css | ||
| @custom-media --medium-screen (min-width: 40em) and (max-width: 60em); | ||
|
|
||
| @media (--medium-screen) { | ||
| } | ||
| ``` | ||
|
|
||
| This alias only matches when the viewport is within the specified width range. | ||
|
|
||
| #### Using the `or` operator | ||
|
|
||
| The logical `or` operator (or its comma alias) creates a media query that matches if any of the listed conditions are `true`. | ||
|
|
||
| ```css | ||
| @custom-media --screen-or-print-1 screen, print; | ||
| @custom-media --screen-or-print-2 screen or print; | ||
|
|
||
| @media (--screen-or-print-1) { | ||
| } | ||
|
|
||
| @media (--screen-or-print-2) { | ||
| } | ||
| ``` | ||
|
|
||
| The two aliases are identical. They are activated for both screen and print environments. | ||
|
|
||
| ## Formal syntax | ||
|
|
||
| {{csssyntax}} | ||
|
|
||
| ## Examples | ||
|
|
||
| ### Updating multiple media queries | ||
|
|
||
| In this example, the `@custom-media` at-rule is used on a responsive website that uses a particular breakpoint in several places: | ||
|
|
||
| ```css | ||
| @custom-media --narrow-window (width < 32em); | ||
|
|
||
| @media (--narrow-window) { | ||
| } | ||
|
|
||
| @media (--narrow-window) and (hover) { | ||
| } | ||
|
|
||
| @media (--narrow-window) and (orientation: portrait) { | ||
| } | ||
| ``` | ||
|
|
||
| If the breakpoint needs to be changed, it can be updated in one place to adjust all dependent media queries across the whole site. | ||
|
|
||
| ### Grouping multiple responsive breakpoints | ||
|
|
||
| Here, the `@custom-media` at-rule is used to set multiple breakpoints in a single place, improving maintainability and simplifying responsive design management across multiple stylesheets: | ||
|
|
||
| ```css | ||
| /* general.css */ | ||
|
|
||
| @custom-media --mobile-screen (width < 480px); | ||
| @custom-media --tablet-screen (width < 768px); | ||
| @custom-media --laptop-screen (width < 1024px); | ||
| @custom-media --desktop-screen (width < 1440px); | ||
| @custom-media --widescreen (width > 1441px); | ||
| ``` | ||
|
|
||
| ```css | ||
| /* layout.css */ | ||
|
|
||
| .container { | ||
| padding: 1rem; | ||
| } | ||
|
|
||
| @media (--mobile-screen) { | ||
| .container { | ||
| padding: 0.5rem; | ||
| } | ||
| } | ||
|
|
||
| @media (--laptop-screen) { | ||
| .container { | ||
| max-width: 1200px; | ||
| } | ||
| } | ||
|
|
||
| @media (--widescreen) { | ||
| .container { | ||
| max-width: 1400px; | ||
| padding: 2rem; | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ```css | ||
| /* typography.css */ | ||
|
|
||
| @media (--tablet-screen) { | ||
| .container { | ||
| font-size: 0.9rem; | ||
| } | ||
| } | ||
|
|
||
| @media (--laptop-screen) { | ||
| .container { | ||
| font-size: 1rem; | ||
| } | ||
| } | ||
|
|
||
| @media (--widescreen) { | ||
| .container { | ||
| font-size: 1.1rem; | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Grouping all the breakpoints in a single location makes it easier to maintain the responsive design. When a breakpoint needs adjustment, it only requires a single update to the associated `@custom-media` definition, ensuring consistency across all stylesheets. | ||
|
|
||
| ### Using `true` and `false` keywords | ||
|
|
||
| The following example shows how the `true` and `false` keywords can be used with `@custom-media` to create media queries that always or never match, respectively. | ||
|
|
||
| ```css | ||
| @custom-media --enabled true; | ||
| @custom-media --disabled false; | ||
|
|
||
| @media (--enabled) { | ||
| /* These styles always apply */ | ||
| body { | ||
| background-color: blue; | ||
| } | ||
| } | ||
|
|
||
| @media (--disabled) { | ||
| /* These styles never apply */ | ||
| body { | ||
| background-color: red; | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| This can be useful for feature flags or conditional logic within stylesheets. | ||
|
|
||
| ### Overriding existing `@custom-media` rules | ||
|
|
||
| In this example, one `@custom-media` rule is overriden by another `@custom-media` rule using the same `<dashed-ident>` name. | ||
|
|
||
| ```css | ||
| @custom-media --mobile-breakpoint (width < 320px); | ||
|
|
||
| @media (--mobile-breakpoint) { | ||
| .container { | ||
| grid-template-columns: 2fr 1fr; | ||
| } | ||
| } | ||
|
|
||
| @custom-media --mobile-breakpoint (width < 480px); | ||
| ``` | ||
|
|
||
| The initial definition of `--mobile-breakpoint` is overridden and therefore ignored. The final declaration becomes the active value used by all references to that custom media query. | ||
|
|
||
| ## Specifications | ||
|
|
||
| {{Specifications}} | ||
|
|
||
| ## Browser compatibility | ||
|
|
||
| {{Compat}} | ||
|
|
||
| ## See also | ||
|
|
||
| - CSS [`@media`](/en-US/docs/Web/CSS/Reference/At-rules/@media) at-rule | ||
| - CSS [`@import`](/en-US/docs/Web/CSS/Reference/At-rules/@import) at-rule | ||
| - [Responsive design](/en-US/docs/Learn/CSS/CSS_layout/Responsive_Design) | ||
| - [CSS media queries](/en-US/docs/Web/CSS/Guides/Media_queries) module | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.