Skip to content

Commit 879a1ae

Browse files
Technical review: Document anchored container queries (mdn#42710)
* Document anchored container queries * Correct descriptor name error on the @container page * Add list of descriptor links to @container link on module page * Apply suggestions from code review - fix links and obvious typos. Co-authored-by: Hamish Willee <hamishwillee@gmail.com> * Fixes for Hamish review comments * Add note, plus a couple of Claude fixes --------- Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
1 parent 73f3b26 commit 879a1ae

File tree

8 files changed

+567
-9
lines changed

8 files changed

+567
-9
lines changed

files/en-us/web/css/guides/anchor_positioning/anchored_container_queries/index.md

Lines changed: 440 additions & 0 deletions
Large diffs are not rendered by default.

files/en-us/web/css/guides/anchor_positioning/index.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ title: CSS anchor positioning
33
short-title: Anchor positioning
44
slug: Web/CSS/Guides/Anchor_positioning
55
page-type: css-module
6-
spec-urls: https://drafts.csswg.org/css-anchor-position-1/
6+
spec-urls:
7+
- https://drafts.csswg.org/css-anchor-position-1/
8+
- https://drafts.csswg.org/css-anchor-position-2/
79
sidebar: cssref
810
---
911

@@ -63,6 +65,9 @@ In addition, the specification provides CSS-only mechanisms to:
6365
- [Fallback options and conditional hiding for overflow](/en-US/docs/Web/CSS/Guides/Anchor_positioning/Try_options_hiding)
6466
- : A guide to the mechanisms CSS anchor positioning provides to prevent anchor-positioned elements from overflowing their containing elements or the viewport, including position try fallback options and conditionally hiding elements.
6567

68+
- [Using anchored container queries](/en-US/docs/Web/CSS/Guides/Anchor_positioning/Anchored_container_queries)
69+
- : Explains how to use anchored container queries to conditionally apply styles to anchor-positioned elements depending on what position try fallback options are active on them.
70+
6671
## Related concepts
6772

6873
- [CSS logical properties and values](/en-US/docs/Web/CSS/Guides/Logical_properties_and_values) module:

files/en-us/web/css/guides/anchor_positioning/try_options_hiding/index.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,39 @@ Scroll the page and check out the effect of these position-try fallback options
374374

375375
{{ EmbedLiveSample("Custom fallback options", "100%", "250") }}
376376

377+
## Styling anchor-positioned elements based on active fallback
378+
379+
One problem the above functionality doesn't solve is updating the styling of an anchor-positioned element to suit its different fallback options. For example, it is common to include a small arrow on a tooltip that points to the anchor element it is associated with, improving UX by making the visual association clearer. When the tooltip moves to a different position, you'll need to change the position and orientation of the arrow, otherwise it will look wrong.
380+
381+
To solve this problem, you can use anchored container queries. These extend the functionality of [CSS container queries](/en-US/docs/Web/CSS/Guides/Containment/Container_queries) to enable you to detect when a specific fallback option is applied to an anchor-positioned element, and apply CSS to its descendants as a result. Specifically, anchored container queries rely on two features:
382+
383+
- The {{cssxref("container-type")}} property `anchored` value: Apply this to the anchor-positioned element to start detecting when different fallback options are applied to it.
384+
- The {{cssxref("@container")}} at-rule `anchored` keyword: This is followed by a set of parentheses inside which the `fallback` descriptor is included. The descriptor's value is a `position-try-fallbacks` value.
385+
386+
For example, let's say we have an anchor-positioned tooltip element that is positioned above its anchor by default via a {{cssxref("position-area")}} value of `top`, but has a {{cssxref("position-try-fallbacks")}} value of `flip-block` specified. This will cause the tooltip to flip in the block direction to the bottom of its anchor when it starts to overflow the top of the viewport. If we want to detect when the fallback is applied to the tooltip, we first need to set `container-type: anchored` on it to turn it into an anchored query container.
387+
388+
```css
389+
.tooltip {
390+
position: absolute;
391+
position-anchor: --myAnchor;
392+
position-area: top;
393+
position-try-fallbacks: flip-block;
394+
container-type: anchored;
395+
}
396+
```
397+
398+
With this in place, we can now write a container query like so:
399+
400+
```css
401+
@container anchored(fallback: flip-block) {
402+
/* Descendant styles here */
403+
}
404+
```
405+
406+
The query test — `anchored(fallback: flip-block)` — will return true when the `flip-block` fallback option is applied to the tooltip, in which case the styles specified within the `@container` block will be applied. You might for example want to change the position and orientation of the arrow icon so that it continues to point towards the anchor, change the direction of a gradient, etc.
407+
408+
For more information on anchored container queries and some examples, see [Using anchored container queries](/en-US/docs/Web/CSS/Guides/Anchor_positioning/Anchored_container_queries).
409+
377410
## Using `position-try-order`
378411

379412
The {{cssxref("position-try-order")}} property has a slightly different focus to the rest of the position try functionality, in that it makes use of position try fallback options when the positioned element is first displayed, rather than when it is in the process of overflowing.

files/en-us/web/css/guides/conditional_rules/index.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,28 @@ There are plans to further extend possible queries by adding the generalized con
3333
### At-rules and descriptors
3434

3535
- {{cssxref("@container")}}
36+
- [`aspect-ratio`](/en-US/docs/Web/CSS/Reference/At-rules/@container#aspect-ratio)
37+
- [`block-size`](/en-US/docs/Web/CSS/Reference/At-rules/@container#block-size)
38+
- [`fallback`](/en-US/docs/Web/CSS/Reference/At-rules/@container#fallback)
39+
- [`height`](/en-US/docs/Web/CSS/Reference/At-rules/@container#height)
40+
- [`inline-size`](/en-US/docs/Web/CSS/Reference/At-rules/@container#inline-size)
41+
- [`orientation`](/en-US/docs/Web/CSS/Reference/At-rules/@container#orientation)
42+
- [`scrollable`](/en-US/docs/Web/CSS/Reference/At-rules/@container#scrollable)
43+
- [`snapped`](/en-US/docs/Web/CSS/Reference/At-rules/@container#snapped)
44+
- [`stuck`](/en-US/docs/Web/CSS/Reference/At-rules/@container#stuck)
45+
- [`width`](/en-US/docs/Web/CSS/Reference/At-rules/@container#width)
3646
- {{cssxref("@media")}}
3747
- {{cssxref("@supports")}}
3848

3949
The CSS conditional rules module also introduces the `@else` and `@when` at-rules. Currently, no browsers support these features.
4050

4151
### Functions
4252

53+
- [`anchored()`](/en-US/docs/Web/CSS/Reference/At-rules/@container#anchored_container_descriptors)
4354
- [`style()`](/en-US/docs/Web/CSS/Reference/At-rules/@container#container_style_queries)
4455
- [`font-tech()`](/en-US/docs/Web/CSS/Reference/At-rules/@supports#font-tech)
4556
- [`font-format()`](/en-US/docs/Web/CSS/Reference/At-rules/@supports#font-format)
57+
- [`scroll-state()`](/en-US/docs/Web/CSS/Reference/At-rules/@container#scroll-state_container_descriptors)
4658
- [`selector()`](/en-US/docs/Web/CSS/Reference/At-rules/@supports#function_syntax)
4759
- [`supports()`](/en-US/docs/Web/CSS/Reference/At-rules/@import#supports-condition)
4860

@@ -116,6 +128,9 @@ The CSS conditional rules module also introduces a `media()` CSS function. Curre
116128
- [CSS namespaces](/en-US/docs/Web/CSS/Guides/Namespaces) module
117129
- {{cssxref("@namespace")}} at-rule
118130

131+
- [CSS anchor positioning](/en-US/docs/Web/CSS/Guides/Anchor_positioning) module
132+
- [Using anchored container queries](/en-US/docs/Web/CSS/Guides/Anchor_positioning/Anchored_container_queries)
133+
119134
## Specifications
120135

121136
{{Specifications}}

files/en-us/web/css/guides/containment/container_queries/index.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ Container queries enable you to apply styles to an element based on certain attr
1111
- The container's size.
1212
- Styles applied to the container.
1313
- The container's scroll-state or that of its scrolling ancestor.
14+
- Whether the container is [anchor-positioned](/en-US/docs/Web/CSS/Guides/Anchor_positioning) and has a [position-try fallback option](/en-US/docs/Web/CSS/Guides/Anchor_positioning/Try_options_hiding) applied to it.
1415

1516
Container queries are an alternative to [media queries](/en-US/docs/Web/CSS/Guides/Media_queries), which apply styles to elements based on viewport size or other device characteristics.
1617

17-
This article provides an introduction to using container queries, specifically focusing on size container queries. Other guides discuss [style](/en-US/docs/Web/CSS/Guides/Containment/Container_size_and_style_queries#container_style_queries) and [scroll-state](/en-US/docs/Web/CSS/Guides/Conditional_rules/Container_scroll-state_queries) container queries in detail.
18+
This article provides an introduction to using container queries, specifically focusing on size container queries. Other guides discuss [style](/en-US/docs/Web/CSS/Guides/Containment/Container_size_and_style_queries#container_style_queries), [scroll-state](/en-US/docs/Web/CSS/Guides/Conditional_rules/Container_scroll-state_queries), and [anchored](/en-US/docs/Web/CSS/Guides/Anchor_positioning/Anchored_container_queries) container queries in detail.
1819

1920
![Two different query types. First, a media query based on the viewport's width, which is the full width of the browser. Second, a container query based on the width of a container element.](container-query.svg)
2021

@@ -174,6 +175,7 @@ If you want to use a single-column layout for devices with a smaller viewport, y
174175
- CSS {{cssxref("content-visibility")}} property
175176
- [Using container size and style queries](/en-US/docs/Web/CSS/Guides/Containment/Container_size_and_style_queries)
176177
- [Using container scroll-state queries](/en-US/docs/Web/CSS/Guides/Conditional_rules/Container_scroll-state_queries)
178+
- [Using anchored container queries](/en-US/docs/Web/CSS/Guides/Anchor_positioning/Anchored_container_queries)
177179
- [Say Hello to CSS Container Queries](https://ishadeed.com/article/say-hello-to-css-container-queries/) by Ahmad Shadeed
178180
- [Container Queries: a Quick Start Guide](https://www.oddbird.net/2021/04/05/containerqueries/)
179181
- [Collection of Container Queries articles](https://github.com/sturobson/Awesome-Container-Queries)

files/en-us/web/css/reference/at-rules/@container/index.md

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ title: "@container"
33
slug: Web/CSS/Reference/At-rules/@container
44
page-type: css-at-rule
55
browser-compat: css.at-rules.container
6+
spec-urls:
7+
- https://drafts.csswg.org/css-conditional-5/#container-type
8+
- https://drafts.csswg.org/css-anchor-position-2/#container-rule-anchored
69
sidebar: cssref
710
---
811

912
The **`@container`** [CSS](/en-US/docs/Web/CSS) [at-rule](/en-US/docs/Web/CSS/Guides/Syntax/At-rules) is a conditional group rule that applies styles to a [containment context](/en-US/docs/Web/CSS/Guides/Containment/Container_queries#naming_containment_contexts).
1013
Style declarations are filtered by a condition and applied to the container if the condition is true.
11-
The condition is evaluated when the queried container size, [`<style-feature>`](#container_style_queries), or scroll-state changes.
14+
The condition is evaluated when the queried container size, [`<style-feature>`](#container_style_queries), scroll-state, or state of the applied [position-try fallback](/en-US/docs/Web/CSS/Guides/Anchor_positioning/Try_options_hiding) (in the case of [anchor-positioned](/en-US/docs/Web/CSS/Guides/Anchor_positioning) containers) changes.
1215

1316
The condition must specify one or both of {{cssxref("container-name")}} and `<container-query>`.
1417

@@ -48,6 +51,15 @@ If no `<container-query>` is specified, named containers are selected.
4851
}
4952
}
5053

54+
/* With an anchored query */
55+
@container anchored(fallback: bottom) {
56+
.infobox::before {
57+
content: "";
58+
bottom: 100%;
59+
top: auto;
60+
}
61+
}
62+
5163
/* With a <container-name> and a <scroll-state> */
5264
@container sticky-heading scroll-state(stuck: top) {
5365
h2 {
@@ -79,7 +91,7 @@ If no `<container-query>` is specified, named containers are selected.
7991
- `<container-name>` {{optional_inline}}
8092
- : The name of the container that the styles will be applied to when the query evaluates to `true`, specified as an {{cssxref("ident")}}.
8193
- `<container-query>` {{optional_inline}}
82-
- : A set of features that are evaluated against the query container when the size, [`<style-feature>`](#container_style_queries), or scroll-state of the container changes.
94+
- : A set of features that are evaluated against the query container when the size, [`<style-feature>`](#container_style_queries), scroll-state, or applied position-try fallback of the container changes.
8395

8496
### Logical keywords in container queries
8597

@@ -134,7 +146,7 @@ Details about usage and naming restrictions are described in the {{cssxref("cont
134146

135147
### Descriptors
136148

137-
The `<container-condition>` queries include [size](#size_container_descriptors) and [scroll-state](#scroll-state_container_descriptors) container descriptors.
149+
The `<container-condition>` queries include [size](#size_container_descriptors), [scroll-state](#scroll-state_container_descriptors), and [anchored](#anchored_container_descriptors) container descriptors.
138150

139151
#### Size container descriptors
140152

@@ -172,7 +184,7 @@ The `<container-condition>` can include one or more boolean size queries, each w
172184

173185
#### Scroll-state container descriptors
174186

175-
Scroll-state container descriptors are specified inside the `<container-condition>` within a set of parentheses following the `scroll-state` keyword, for example:
187+
Scroll-state container descriptors are specified inside the `<container-condition>` as an argument for the `scroll-state()` function, for example:
176188

177189
```css
178190
@container scroll-state(scrollable: top) {
@@ -319,7 +331,7 @@ Supported keywords for scroll-state container descriptors include {{glossary("ph
319331

320332
To evaluate a container with a non-`none` `stuck` scroll-state query, it must have `position: sticky` set on it, and be inside a scroll container. If the test passes, the rules inside the `@container` block are applied to descendants of the `position: sticky` container.
321333

322-
It is possible for two values from opposite axes to match at the same time:
334+
It is possible for two values from adjacent axes to match at the same time:
323335

324336
```css
325337
@container scroll-state((stuck: top) and (stuck: left)) {
@@ -343,6 +355,27 @@ Supported keywords for scroll-state container descriptors include {{glossary("ph
343355
}
344356
```
345357

358+
#### Anchored container descriptors
359+
360+
Anchored container descriptors are specified inside the `<container-condition>` as an argument for the `anchored()` function, for example:
361+
362+
```css
363+
@container anchored(fallback: top) {
364+
/**/
365+
}
366+
@container anchored(fallback: flip-block flip-inline) {
367+
/**/
368+
}
369+
@container anchored(fallback: --custom-fallback) {
370+
/**/
371+
}
372+
```
373+
374+
- `fallback`
375+
- : Queries whether a specific position-try fallback is currently active on an anchor-positioned container, as specified via the {{cssxref("position-try-fallbacks")}} property. Valid `fallback` values include any component value that is valid for inclusion in a `position-try-fallbacks` property value.
376+
377+
If the `fallback` value named in the test is currently active on the anchor-positioned container, the test passes, and the rules inside the `@container` block are applied to descendants of the anchor-positioned container.
378+
346379
## Formal syntax
347380

348381
{{csssyntax}}
@@ -511,7 +544,11 @@ The global `revert` and `revert-layer` are invalid as values in a `<style-featur
511544

512545
### Scroll-state queries
513546

514-
See [Using container scroll-state queries](/en-US/docs/Web/CSS/Guides/Conditional_rules/Container_scroll-state_queries) for full walkthroughs of scroll-state query examples.
547+
See [Using container scroll-state queries](/en-US/docs/Web/CSS/Guides/Conditional_rules/Container_scroll-state_queries) for scroll-state query examples.
548+
549+
### Anchored queries
550+
551+
See [Using anchored container queries](/en-US/docs/Web/CSS/Guides/Anchor_positioning/Anchored_container_queries) for anchored query examples.
515552

516553
## Specifications
517554

@@ -526,6 +563,7 @@ See [Using container scroll-state queries](/en-US/docs/Web/CSS/Guides/Conditiona
526563
- [Using container queries](/en-US/docs/Web/CSS/Guides/Containment/Container_queries)
527564
- [Using container size and style queries](/en-US/docs/Web/CSS/Guides/Containment/Container_size_and_style_queries)
528565
- [Using container scroll-state queries](/en-US/docs/Web/CSS/Guides/Conditional_rules/Container_scroll-state_queries)
566+
- [Using anchored container queries](/en-US/docs/Web/CSS/Guides/Anchor_positioning/Anchored_container_queries)
529567
- {{Cssxref("container-name")}}
530568
- {{Cssxref("container-type")}}
531569
- {{Cssxref("contain")}}

0 commit comments

Comments
 (0)