Skip to content

Commit daffe81

Browse files
authored
Add an explainer for anchored container queries (w3c#12235)
1 parent f720b37 commit daffe81

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
# CSS Anchored Fallback Container Queries Explainer
2+
3+
## Introduction
4+
5+
CSS Anchor Positioning Level 1 introduced a way to position and size absolute
6+
positioned elements relative to a specific anchor element.
7+
8+
Note: This explainer currently does not explore the [`::tether` proposal]().
9+
10+
There have been multiple requests to support styling of anchored elements based
11+
on the chosen position.
12+
13+
Identified needs:
14+
15+
- Style a tether like arrows to match the direction of the anchored elements
16+
position relative to its anchor
17+
- Styling background gradients based on direction
18+
- Run different animations based on the position of the anchored element
19+
20+
See the filed github issues [[1](https://github.com/w3c/csswg-drafts/issues/8171)],
21+
[[2](https://github.com/w3c/csswg-drafts/issues/9332)]
22+
23+
24+
## Proposed solution
25+
26+
A declarative way of supporting this is through `@container` queries. An
27+
anchored element can be queried about its applied fallback styles and the
28+
descendant elements can be styled accordingly.
29+
30+
The caveat is that the anchored element itself cannot be styled with such
31+
queries. If it is possible to allow more properties than the ones currently
32+
allow in `@position-try` rules, the spec could instead extend that list and
33+
allow the queries outlined here to offer a more rich styling for the anchored
34+
element subtree.
35+
36+
37+
## Proposed syntax
38+
39+
### The `anchored` container-type
40+
41+
Apart from `style() `queries, container candidates need to be explicitly made
42+
so through the `container-type` property. For anchored elements there is no
43+
trivial way to identify that an element is anchored - it is a combination of
44+
computed values for several properties that makes it so. Therefore, the
45+
proposal is to introduce a new `container-type: anchored`. Setting this
46+
`container-type` makes the element an anchored container even if it is not
47+
anchored, nor even an absolute positioned element.
48+
49+
The new container type can be combined with existing container types.
50+
51+
### The `anchored(fallback)` query function
52+
53+
Container queries currently support size (just parentheses), `style()`, and
54+
`scroll-state()`.
55+
56+
The proposal here is to introduce a new `anchored()` function to match features
57+
of anchored elements along with a `fallback` feature to query which of the
58+
`position-try-fallbacks` is applied to the anchored element.
59+
60+
#### Index-based query
61+
62+
The simplest way of querying the fallback is an `<integer>` value where `0`
63+
means no fallback, and any other value is a 1-based index into the computed
64+
value of `position-try-fallbacks`. No applied fallbar (`0`) would evaluate to
65+
false in the boolean context.
66+
67+
This is the syntax that is implemented in the current prototype in Chrome.
68+
69+
#### Value-based query
70+
71+
A more author-friendly syntax is to instead match against the actual fallback
72+
value from the list of entried in `position-try-fallbacks`, where `none`
73+
matches when no fallback is applied.
74+
75+
The canonicalized order would be used for matching. That is,
76+
`@container anchored(fallback: flip-block --foo) {}` would match
77+
`position-try-fallbacks: --foo flip-block`.
78+
79+
Open question: Does the tree-scoped name lookup of `@position-try` need to
80+
match the exact same rule? The named lookup may result in different rules for
81+
`@container` and `position-try-fallbacks` if they origin from diferrent trees.
82+
83+
### Example
84+
85+
Here is an example based on the proposed synax above with value-based queries:
86+
87+
```html
88+
<style>
89+
@position-try --foo {
90+
position-area: top center;
91+
}
92+
93+
#anchored {
94+
container-type: anchored;
95+
position-anchor: --a;
96+
position-area: left center;
97+
position: absolute;
98+
position-try-fallbacks: --foo flip-block, --foo;
99+
}
100+
101+
/* Matches the first fallback */
102+
@container anchored(fallback: flip-block --foo) {
103+
#target { background: lime; }
104+
}
105+
/* Matches the second fallback */
106+
@container anchored(fallback: --foo) {
107+
#target { background: orange; }
108+
}
109+
</style>
110+
<div id="anchor"></div>
111+
<div id="anchored">
112+
<div id="target">Anchored</div>
113+
</div>
114+
```
115+
116+
117+
## Containment requirements and limitations
118+
119+
Anchor positioned elements depend on layout in order to compute anchor
120+
functions and select applied `position-try-fallbacks`. That means there might
121+
be containment requirements.
122+
123+
### Style containment
124+
125+
Incrementing or resetting CSS counters may affect generated content of any
126+
succeeding element regardless of layout mode, hence the layout of any element
127+
succeeding an anchored element. This may lead to circular dependencies if
128+
`anchored()` queries if counter changes are allowed to escape the anchored
129+
element subtree.
130+
131+
This can be remedied by applying style containment to `container-type:anchored`
132+
elements, similarly to what we do for size containers.
133+
134+
### Layout containment
135+
136+
Whatever layout containment is necessary for size container queries should be
137+
necessary, but also sufficient, for anchored queries. A size container currently
138+
[establishes an independent formatting context](https://drafts.csswg.org/css-conditional-5/#valdef-container-type-size),
139+
but does not apply layout containment.
140+
141+
### Styling the anchored element itself
142+
143+
As with other query containers, it is not possibly to change the style of the
144+
anchored element itself. This is also an implication of the layout dependency
145+
and the limited list of properties which can be applied by `@position-try` and
146+
other fallback rules. See
147+
[The @position-try Rule](https://drafts.csswg.org/css-anchor-position-1/#fallback-rule)
148+
149+
150+
## Use Cases and Author Requests
151+
152+
- https://github.com/w3c/csswg-drafts/issues/8171#issue-1472061771
153+
- https://github.com/w3c/csswg-drafts/issues/8171#issuecomment-2465816828
154+
- https://utilitybend.com/blog/lets-hang-an-intro-to-css-anchor-positioning-with-basic-examples
155+
156+
157+
## Chrome Prototype Demo
158+
159+
Chrome Canary 138.0.7194.0 and later has an experimental implementation behind a
160+
[flag](chrome://flags/#enable-experimental-web-platform-features) which uses the
161+
index-based syntax. A simple demo can be found on
162+
[codepen](https://codepen.io/lilles/pen/VYLZZqj).
163+

0 commit comments

Comments
 (0)