diff --git a/files/en-us/web/css/guides/containment/container_size_and_style_queries/index.md b/files/en-us/web/css/guides/containment/container_size_and_style_queries/index.md index e7363f49d09706c..866ee69d2ec2622 100644 --- a/files/en-us/web/css/guides/containment/container_size_and_style_queries/index.md +++ b/files/en-us/web/css/guides/containment/container_size_and_style_queries/index.md @@ -353,6 +353,100 @@ If you enter `unset` or `gibberish`, the JavaScript updates the `style` on the { > [!NOTE] > When declaring custom properties, consider using `@property` with the {{cssxref("@property/syntax","syntax")}} descriptor so the browser can properly compare computed values. +### Plain versus range syntax in style queries + +When a `` includes a value, you can express the comparison in two different ways. They look similar but behave very differently, and choosing the right one matters. + +The **plain syntax** uses a colon, the same syntax used in a CSS declaration: + +```css +@container style(--n: 3) { + /* … */ +} +``` + +This form is true if the [computed value](/en-US/docs/Web/CSS/Guides/Cascade/Property_value_processing#computed_value) of the property matches the value on the right. For an [unregistered](#unregistered_custom_properties) custom property, the computed value is the property's value as written: the browser doesn't evaluate `calc()` or other expressions inside it. The match is essentially a comparison of the two values' tokens. To match equivalent values (such as `blue` and `#0000ff`), [register the custom property](#registered_properties) with `@property` and a `syntax` descriptor. + +The **range syntax** uses a comparison operator (`=`, `<`, `<=`, `>`, or `>=`): + +```css +@container style(--n = 3) { + /* … */ +} +``` + +To evaluate this form, the browser: + +1. Resolves each side (custom property names are looked up as if used with [`var()`](/en-US/docs/Web/CSS/Reference/Values/var)). +2. Parses each side as one of {{cssxref("<number>")}}, {{cssxref("<percentage>")}}, {{cssxref("<length>")}}, {{cssxref("<angle>")}}, {{cssxref("<time>")}}, {{cssxref("<frequency>")}}, or {{cssxref("<resolution>")}}. If either side can't be parsed as one of those types, the query is false. +3. If both sides have the same type, computes each side (evaluating any `calc()` expressions) and performs the numeric comparison. Otherwise, the query is false. + +Consider the following example, where `--n` is set to a `calc()` expression: + +```css +.box { + --n: calc(6/2); +} + +/* Evaluates to FALSE: */ +/* the computed value of --n is the string `calc(6/2)`, which is */ +/* not equal to the string `3`. */ +@container style(--n: 3) { + /* … */ +} + +/* Evaluates to TRUE: */ +/* both sides are parsed as , calc(6/2) is computed to 3, */ +/* and 3 = 3. */ +@container style(--n = 3) { + /* … */ +} +``` + +The range syntax also supports a three-value form for testing whether a value falls within an interval. Both comparators must point the same way: + +```css +@container style(0 < --n < 10) { + /* true when --n is greater than 0 and less than 10 */ +} + +@container style(100px > --width > 50px) { + /* true when --width is less than 100px and greater than 50px */ +} +``` + +The range syntax is also more flexible in how each side is written. Either side can be a custom property name, a [`var()`](/en-US/docs/Web/CSS/Reference/Values/var) reference, a literal value, or a `calc()` expression, and the operands can appear in any order. The following are all valid: + +```css +@container style(3 = --n) { + /* … */ +} +@container style(var(--n) = 3) { + /* … */ +} +@container style(calc(6/2) = var(--n)) { + /* … */ +} +``` + +The plain syntax is more restrictive: the left-hand side must be the custom property name (without `var()`), and the value goes on the right. The following are all **invalid**: + +```css example-bad +@container style(var(--n): 3) { + /* … */ +} +@container style(3: --n) { + /* … */ +} +``` + +Because the range syntax requires both sides to parse as one of the listed numeric types, it can't be used to compare keyword-like values. For example, given `--s: new`, the query `style(--s = new)` is false (because `new` isn't a number, length, etc.), while `style(--s: new)` is true. + +In short: + +- Use **`style(--variable: value)`** for keyword-like or string-like matching, such as `style(--stock: low)` or `style(--theme: dark)`. +- Use **`style(--variable = value)`** (or `<`, `<=`, `>`, `>=`) for numeric comparisons, such as `style(--columns >= 3)` or `style(--gap = 1rem)`. + ### Nested queries Container queries can be nested within other container queries. The styles defined inside multiple nested container queries are applied when all of the wrapping container queries are true. diff --git a/files/en-us/web/css/reference/at-rules/@container/index.md b/files/en-us/web/css/reference/at-rules/@container/index.md index 903c9abe1cea4fa..0d9bbed2a98d8f8 100644 --- a/files/en-us/web/css/reference/at-rules/@container/index.md +++ b/files/en-us/web/css/reference/at-rules/@container/index.md @@ -560,6 +560,15 @@ Note that [`!important`](/en-US/docs/Web/CSS/Reference/Values/important) is allo The global `revert` and `revert-layer` are invalid as values in a `` and cause the container style query to be false. +#### Plain (`:`) versus range (`=`) syntax + +When a `` includes a value, you can write the comparison in two forms that look similar but behave differently: + +- `style(--n: 3)` (plain) matches the property's _computed value_ against the right-hand side. For an unregistered custom property, the computed value is the value as authored, so `style(--n: 3)` is false when `--n` is `calc(6/2)`. Use this form for keyword-like values, such as `style(--stock: low)`. +- `style(--n = 3)` (range) parses both sides as a number, length, percentage, etc., and compares numerically. With the same `--n: calc(6/2)`, `style(--n = 3)` is true. The range syntax also supports `<`, `<=`, `>`, `>=`, three-value intervals such as `style(0 < --n < 10)`, and flexible operand ordering. + +For the full rules and more examples, see [Plain versus range syntax in style queries](/en-US/docs/Web/CSS/Guides/Containment/Container_size_and_style_queries#plain_versus_range_syntax_in_style_queries) in the container style queries guide. + ### Scroll-state queries See [Using container scroll-state queries](/en-US/docs/Web/CSS/Guides/Conditional_rules/Container_scroll-state_queries) for scroll-state query examples.