Skip to content
Merged
Show file tree
Hide file tree
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 Nov 24, 2025
3ae1b84
Add CSS `@custom-media` at-rule
ramiy Nov 24, 2025
6935fdd
Add CSS `@custom-media` at-rule
ramiy Nov 24, 2025
4df88ca
Merge branch 'main' into custom-media
ramiy Nov 24, 2025
a0b79e7
Add CSS `@custom-media` at-rule
ramiy Nov 24, 2025
54a7f3f
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy Nov 26, 2025
ae8d414
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy Nov 26, 2025
2bc4149
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy Nov 26, 2025
0587e26
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy Nov 26, 2025
1065113
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy Nov 26, 2025
9c0db2d
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy Nov 26, 2025
c21a91e
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy Nov 26, 2025
ff0162f
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy Nov 26, 2025
670e381
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy Nov 26, 2025
19232bd
Update
ramiy Nov 26, 2025
56274d7
Update
ramiy Nov 26, 2025
7cf968b
Update
ramiy Nov 26, 2025
b39d94e
Update
ramiy Nov 27, 2025
1572b3b
Update
ramiy Nov 27, 2025
25c4c40
Update
ramiy Nov 30, 2025
85ac344
Update
ramiy Nov 30, 2025
68dfa79
Update
ramiy Nov 30, 2025
6955438
Update
ramiy Nov 30, 2025
0197069
Update
ramiy Nov 30, 2025
6a96383
Update
ramiy Nov 30, 2025
ebcf14a
Update files/en-us/web/css/reference/values/rule-list/index.md
ramiy Nov 30, 2025
0a1b00f
Update
ramiy Nov 30, 2025
c280f73
Update
ramiy Nov 30, 2025
6de6d98
Update
ramiy Nov 30, 2025
ae95f48
Update
ramiy Nov 30, 2025
1156bdd
Update
ramiy Nov 30, 2025
33f75a0
Update
ramiy Nov 30, 2025
0b73928
Merge branch 'main' into custom-media
ramiy Nov 30, 2025
8706498
Update files/en-us/mozilla/firefox/experimental_features/index.md
ramiy Dec 1, 2025
71f75fd
Update files/en-us/web/api/cssstylesheet/insertrule/index.md
ramiy Dec 1, 2025
6837f45
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy Dec 1, 2025
b7d4752
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy Dec 1, 2025
7269318
Update files/en-us/web/css/reference/at-rules/@custom-media/index.md
ramiy Dec 1, 2025
e25222b
Update files/en-us/web/css/reference/values/rule-list/index.md
ramiy Dec 1, 2025
3731efb
Apply suggestions from code review
ramiy Dec 1, 2025
ddd640e
Apply suggestions from code review
ramiy Dec 1, 2025
5764a78
Apply suggestions from code review
ramiy Dec 1, 2025
37f16ec
Merge branch 'main' into custom-media
ramiy Dec 1, 2025
c3ec19f
Apply suggestions from code review
ramiy Dec 1, 2025
acb5596
Merge branch 'main' into custom-media
caugner Dec 1, 2025
31efde1
Update
ramiy Dec 1, 2025
9c4ef79
Simplify the section about evaluating media queries with logical oper…
ramiy Dec 1, 2025
064d21a
Update logical operators
ramiy Dec 1, 2025
57d5b9a
Apply suggestions from code review
ramiy Dec 1, 2025
a81a489
Add another example - overriding existing rules
ramiy Dec 1, 2025
af66af2
Update the `or` operator
ramiy Dec 2, 2025
32c9df4
Update the `or` operator
ramiy Dec 2, 2025
51692d2
Update syntax values
ramiy Dec 2, 2025
14c08e5
Update syntax values
ramiy Dec 2, 2025
8794646
Merge branch 'main' into custom-media
ramiy Dec 2, 2025
d3199f2
Update files/en-us/mozilla/firefox/experimental_features/index.md
chrisdavidmills Dec 2, 2025
c509e03
Merge branch 'main' into custom-media
chrisdavidmills Dec 2, 2025
337b5fa
Small tweak
chrisdavidmills Dec 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions files/en-us/mozilla/firefox/experimental_features/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,20 @@ The CSS `text-decoration-trim` property allows you to specify {{cssxref("text-de
- `layout.css.text-decoration-trim.enabled`
- : Set to `true` to enable.

### `@custom-media` at-rule

The [`@custom-media`](/en-US/docs/Web/CSS/Reference/At-rules/@custom-media) CSS at-rule defines aliases for long or complex media queries. Instead of repeating the same hardcoded `<media-query-list>` in multiple `@media` at-rules, it can be defined once in a `@custom-media` at-rule and referenced throughout the stylesheet whenever needed. ([Firefox bug 1991105](https://bugzil.la/1744292)).

| Release channel | Version added | Enabled by default? |
| ----------------- | ------------- | ------------------- |
| Nightly | 146 | No |
| Developer Edition | 146 | No |
| Beta | 146 | No |
| Release | 146 | No |

- `layout.css.custom-media.enabled`
- : Set to `true` to enable.

## SVG

**No experimental features in this release cycle.**
Expand Down
4 changes: 4 additions & 0 deletions files/en-us/mozilla/firefox/releases/146/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,7 @@ You can find more such features on the [Experimental features](/en-US/docs/Mozil

Nightly builds now support the Navigation API, which provides the ability to initiate, intercept, and manage browser navigation actions. It can also examine an application's history entries. This is a successor to previous web platform features such as the {{domxref("History API", "", "", "nocode")}} and {{domxref("window.location")}}, which solves their shortcomings and is specifically aimed at the needs of {{glossary("SPA", "single-page applications (SPAs)")}}.
([Firefox bug 1979288](https://bugzil.la/1979288)).

- **Custom media queries**: `layout.css.custom-media.enabled`

The [`@custom-media`](/en-US/docs/Web/CSS/Reference/At-rules/@custom-media) CSS at-rule defines aliases for long or complex media queries. Instead of repeating the same hardcoded `<media-query-list>` in multiple `@media` at-rules, it can be defined once in a `@custom-media` at-rule and referenced throughout the stylesheet whenever needed. ([Firefox bug 1991105](https://bugzil.la/1744292)).
2 changes: 1 addition & 1 deletion files/en-us/web/api/cssstylesheet/insertrule/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ The newly inserted rule's index within the stylesheet's rule-list.
- `SyntaxError` {{domxref("DOMException")}}
- : Thrown if more than one rule is given in the `rule` parameter.
- `InvalidStateError` {{domxref("DOMException")}}
- : Thrown if `rule` is {{cssxref("@namespace")}} and the rule-list has more than just `@import` at-rules and/or `@namespace` at-rules.
- : Thrown if `rule` is {{cssxref("@namespace")}} and the [rule-list](/en-US/docs/Web/CSS/Reference/Values/rule-list) contains at-rules other than `@import` and `@namespace` at-rules.

## Examples

Expand Down
1 change: 1 addition & 0 deletions files/en-us/web/css/guides/media_queries/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ When designing reusable HTML components, you may also use [container queries](/e
### At-rules and descriptors

- {{cssxref("@import")}}
- {{cssxref("@custom-media")}}
- {{cssxref("@media")}}
- {{cssxref("@media/any-hover", "any-hover")}}
- {{cssxref("@media/any-pointer", "any-pointer")}}
Expand Down
2 changes: 1 addition & 1 deletion files/en-us/web/css/guides/media_queries/using/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ sidebar: cssref

Media queries are used for the following:

- To conditionally apply styles with the [CSS](/en-US/docs/Web/CSS) {{cssxref("@media")}} and {{cssxref("@import")}} [at-rules](/en-US/docs/Web/CSS/Guides/Syntax/At-rules).
- To conditionally apply styles with the [CSS](/en-US/docs/Web/CSS) {{cssxref("@media")}}, {{cssxref("@custom-media")}} and {{cssxref("@import")}} [at-rules](/en-US/docs/Web/CSS/Guides/Syntax/At-rules).
- To target specific media for the {{HTMLElement("style")}}, {{HTMLElement("link")}}, {{HTMLElement("source")}}, and other [HTML](/en-US/docs/Web/HTML) elements with the `media=` or `sizes="` attributes.
- To [test and monitor media states](/en-US/docs/Web/CSS/Guides/Media_queries/Testing) using the {{domxref("Window.matchMedia()")}} and {{domxref("EventTarget.addEventListener()")}} methods.

Expand Down
239 changes: 239 additions & 0 deletions files/en-us/web/css/reference/at-rules/@custom-media/index.md
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
1 change: 1 addition & 0 deletions files/en-us/web/css/reference/at-rules/@media/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,5 +290,6 @@ For more examples, please see [Using media queries](/en-US/docs/Web/CSS/Guides/M
- [CSS media queries](/en-US/docs/Web/CSS/Guides/Media_queries) module
- [Using media queries](/en-US/docs/Web/CSS/Guides/Media_queries/Using)
- {{domxref("CSSMediaRule")}} interface
- CSS [`@custom-media`](/en-US/docs/Web/CSS/Reference/At-rules/@custom-media) at-rule
- [Extended Mozilla media features](/en-US/docs/Web/CSS/Reference/Mozilla_extensions#media_features)
- [Extended WebKit media features](/en-US/docs/Web/CSS/Reference/Webkit_extensions#media_features)
1 change: 1 addition & 0 deletions files/en-us/web/css/reference/at-rules/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ sidebar: cssref
- {{cssxref("@counter-style/suffix")}}
- {{cssxref("@counter-style/symbols")}}
- {{cssxref("@counter-style/system")}}
- {{cssxref("@custom-media")}}
- {{cssxref("@document")}} {{non-standard_inline}} {{deprecated_inline}}
- {{cssxref("@font-face")}}
- {{cssxref("@font-face/ascent-override")}}
Expand Down
Loading