You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[css-contain-3] Provide a syntax to query a specific container-type #6393
container selection: Find the right container to query (nearest ancestor container, after optionally filtering by <<container-name>>)
query evaluation: Evaluate each feature in the <<container-query-list>>
If no eligible container is selected, the query evaluates to false.
If the selected container in step 1 is not a valid container type for the query features used in step 2, then the query evaluates to unknown. For example, if we try to query a block-size container-type about its inline dimensions, that measurement is unknown.
That means authors will likely also want to filter and select containers based on container type – eg find the nearest inline-size container in step 1, in order to query its width in step 2. And, since a <<container-query-list>> could combine multiple different features, we might need to select for more than one container type.
Since container-names are custom identifiers, and container types are built-in keywords (with potential for new additions later on) we'll need some way to distinguish them — either by requiring dashed-idents for names (not a great option), or by adding distinct syntax for selecting each one in the @container rule. Something like:
For the shorthand-like proposal, I assume it should be possible to only specify a name or only specify a type? In that case we would need to exclude size, inline-size etc from the <custom-ident>of <container-name>, and then we're back at the problem of magic keywords.
better approach than adding a type()
Validate its existence somewhat by also having name() for name-based selection? 🙂
clearer delineation
Maybe it helps to demand parens, i.e. make the grammar <media-in-parens> (or container-in-parens) rather than <container-query-list>:
Although one thing to watch out for here is that if fn() is valid for both the selection and the query, we get a problem with: @container fn() {}. So maybe <media-in-parens> is not enough.
I like the idea of keeping the name/type syntax in the container shorthand and in the @container rule consistent, as mentioned in #6393 (comment) . Maybe that means using the container syntax in @container or maybe it means shifting both to a new syntax that is a good fit for both contexts, but either way I think the consistency would benefit authors.
Our current container property syntax relies on consistent order, and the / divider (eg types / names). In order to make that work with both sides optional, the delimiter needs to be used for all names, even when no type is given. Either using punctuation or a keyword:
/* using the current `/` divider */@container inline-size / my-name ( width > 30em ) { … }
@container inline-size ( width > 30em ) { … }
@container/ my-name ( width > 30em ) { … }
/* using a single keyword, still ordered */@container inline-size as my-name ( width > 30em ) { … }
@container inline-size ( width > 30em ) { … }
@container as my-name ( width > 30em ) { … }
But that order was based on the assumption that a type is required, and names are optional in the shorthand. That assumption is clearly false in the @container rule, but it may also be wrong for the shorthand property. If we consider re-using named containers for something like a scroll-timeline (see #6674), it doesn't seem like types should be required in those situations. The same is likely true for style queries, which should work on any container. That makes me want a more flexible syntax, where the order is less important. That could be done with two keywords ('for' <types> || 'as' <names>):
@container for inline-size as my-name ( width > 30em ) { … }
@container as my-name for inline-size ( width > 30em ) { … }
@container for inline-size ( width > 30em ) { … }
@container as my-name ( width > 30em ) { … }
But the more I stare at this, the more tempted I am to just use dashed-idents for names, and allow the two values to mingle completely:
That might also allow us to express and/or combinations, maybe with the / divider between container-selection and query logic (if that division needs more clarity). Something like:
We don't really use preposition syntax markers outside of functions (at least not yet), and using --custom-property syntax here also feels kinda weird. What about:
I like this direction, giving container-name the primary slot — but we may want to combine that with a de-prioritizing of container-type. Right now we require a type in order to establish a container at all. I think, instead, we would want to say that every element(?) is a style container by default (maybe with a normal keyword as the initial value?), and then the type is only required when we want to query size? That maybe needs some more fleshing out, and could become a new issue, but I think it would help make this syntax work.
Perhaps all elements are style containers by default
If that were the case, that would solve Higher Level Custom Properties that were talked about late 2020, no? If I interpret things correctly, the there proposed @if (<style-query) { … } could be seen as syntactic sugar for @container / style (<style-query) { … }, right?
Furthermore, if all elements were style containers by default, is style still a necessary value for container-type? Reasoning: as all elements already are style containers, there's not need to define them manually as such, right?
Note that in this case, as a side-effect to that decision, setting container-type to, for example, inline-size would be something to apply on top of it already being a style container. I.e. container-type: inline-size; will result in the element being both a style and size container.
Regarding the syntax itself: I feel that there's some tight clinging onto the @container at-rule here. With all elements (possibly) being style containers, it — as an author — would feel more logical to write @style(<style-query>) { … } instead of @container / style (<style-query) { … } though.
IIRC there is discussion somewhere that warned/decided against introducing a lot of new at-rules, so I can definitely understand. From an author's POV however, it feels a bit weird though. I think this "weirdness" stems from the fact that viewport media queries (@media) always are size based queries, not style based ones.
My initial reaction to container queries is the same: using @container is about the size of the element. I understand that it's more than size only, but I can imagine a lot of authors will be confused about it or only get part of the message (the size part), missing out on style/state/x containers.
What I'm trying to say here: as an author, this piece of code would be highly readable, even if I wouldn't know the exact details about style or container queries:
A version that uses @container / style (…) instead would be harder to read and can confusing, as @container there targets a parent whereas @container / style targets the element itself.
Given this last confusion I'm raising here: yes, this could be seen as a plea for keeping @container reserved for only size based querying.
Apologies if I'm sidetracking here, or if I'm raising things in here that were already discussed. Feel free to ignore what's not relevant, I know you all will make the correct decisions in the end :)
Furthermore, if all elements were style containers by default, is style still a necessary value for container-type? … I.e. container-type: inline-size; will result in the element being both a style and size container.
That seems right to me.
it — as an author — would feel more logical to write @Style() { … } instead of @container / style (<style-query) { … } though.
Specifying the container-type isn't required in the current syntax, and (as you note) style might not even be needed as a type if we do make it a default everywhere. We also made the queries into functions. So the currently proposed syntax here for most cases would be:
I think that's already pretty readable? What I like about @container as a rule for both size and style is that it clarifies what element you are querying, before stating what feature to query – and then it allows you to optionally filter those elements by a container name:
If we say that every element is a style container, then there would be no reason to ever use / style in the preamble, since that would not filter out any elements.
My initial reaction to container queries is the same: using @container is about the size of the element. I understand that it's more than size only, but I can imagine a lot of authors will be confused about it or only get part of the message (the size part), missing out on style/state/x containers.
There is nothing about the word "container" that implies size, so this would only be true for authors with a strong historic attachment to "container queries" as an Idea. That seems to me like a very focused and temporary issue, easily overcome by some good resources.
(As long as this issue is still open, I can see why the examples aren't updated yet. No worries)
There is nothing about the word "container" that implies size, so this would only be true for authors with a strong historic attachment to "container queries" as an Idea.
I know what I'll be explicitly mentioning whenever I get to talk/write about them :)
The CSS Working Group just discussed CSS Conditional L3 : Syntax for container types, and agreed to the following:
RESOLVED: Boxes default to style containment, syntax of 'container' and @container preamble is name / type
The full IRC log of that discussion
<fantasai> Topic: CSS Conditional L3 : Syntax for container types
<fantasai> github: https://github.com//issues/6393
<fantasai> miriam: Really wanted a way to query which type of conainer
<fantasai> miriam: e.g. find nearest inline-size container
<fantasai> miriam: Already the query has two parts to it
<fantasai> miriam: can query a specific named container
<fantasai> miriam: and then main query list is what queries against that container
<fantasai> miriam: so adding to preamble ability to filter by container type
<fantasai> miriam: in the discussion fantasai suggested that we could matched the syntax of the container shorthand property
<fantasai> miriam: currently that syntax requires a type, and then slash, and then any number of names
<fantasai> miriam: that could work, but in our initial formulation the container type is required to establish a container
<fantasai> miriam: which is why it's first
<fantasai> miriam: but for queries, seems that putting name first makes sense
<fantasai> miriam: since most ppl will be querying name, not type
<fantasai> miriam: Also discussion that all boxes can be style containers
<fantasai> miriam: which would make type container
<fantasai> miriam: make a style conainer
<fantasai> miriam: in that case, we could start with names in container property
<fantasai> miriam: and if you wanted to make a type of container without a name, would have to start the value with a slash
<fantasai> Rossen_: Any opinions?
<miriam> this comment lays it out: https://github.com//issues/6393#issuecomment-988216116
<fantasai> miriam: Comment summarizes the proposal
<fantasai> miriam: 3 resolutions
<fantasai> miriam: 1. Make style as the default container type, all boxes can take
<fantasai> miriam: 2. Changing 'container' property syntax to name / type
<fantasai> miriam: 3. Changing @container preamble to match
<fantasai> florian: I think we shoud take all 3, only make sense if we take them all
<fantasai> Rossen_: Any objections to resolving on all 3?
<fantasai> RESOLVED: Boxes default to style containment, syntax of 'container' and @container preamble is name / type
<fantasai> Rossen_: Do we need to republish soon?
<fantasai> miriam: need to make some changes first
While having all elements default to style containers can cause issues for non-inherited properties (like @una's background-color example), I think it works out great for inherited properties: checking the parent font size, or current font-style, weight, color, etc. Those use-cases are very handy for solving style-toggle use cases (if parent is italic, child should be normal, and vice versa).
For use-cases where it's important to query a specific container (including user-defined container types like 'containers with backgrounds'), setting a container-name makes it much more robust against the possibility of accidental intervening containers. Whether or not we revisit this resolution, I would still push authors towards naming containers when that's important — as it is with background-color.
I'm happy to revisit this if we want to put it back on the agenda (or discuss it as a part of resolving #6644), but at this point I still think we made a reasonable decision.
My main issue with this is I just don't think it's a reasonable default to assume that a user wants to query the style of a direct parent in a container query. In my current experience with CQ, the majority of my demos and use cases do not query the direct parent. To help illustrate:
I split out the remaining questions here into a new issue #7066. Closing this issue as resolved, as we've decided to remove container-type selection syntax, and rely on automated container-type selection.
Activity
mirisuzanne commentedon Jun 17, 2021
Maybe something that reflects the container shorthand syntax?
andruud commentedon Jun 18, 2021
For the shorthand-like proposal, I assume it should be possible to only specify a name or only specify a type? In that case we would need to exclude
size,inline-sizeetc from the<custom-ident>of<container-name>, and then we're back at the problem of magic keywords.Validate its existence somewhat by also having
name()for name-based selection? 🙂Maybe it helps to demand parens, i.e. make the grammar
<media-in-parens>(or container-in-parens) rather than<container-query-list>:Although one thing to watch out for here is that if
fn()is valid for both the selection and the query, we get a problem with:@container fn() {}. So maybe<media-in-parens>is not enough.fantasai commentedon Sep 21, 2021
I like the idea of keeping the name/type syntax in the
containershorthand and in the@containerrule consistent, as mentioned in #6393 (comment) . Maybe that means using thecontainersyntax in@containeror maybe it means shifting both to a new syntax that is a good fit for both contexts, but either way I think the consistency would benefit authors.mirisuzanne commentedon Sep 24, 2021
A few options for a shared shorthand…
Our current
containerproperty syntax relies on consistent order, and the/divider (egtypes / names). In order to make that work with both sides optional, the delimiter needs to be used for all names, even when no type is given. Either using punctuation or a keyword:But that order was based on the assumption that a type is required, and names are optional in the shorthand. That assumption is clearly false in the
@containerrule, but it may also be wrong for the shorthand property. If we consider re-using named containers for something like a scroll-timeline (see #6674), it doesn't seem like types should be required in those situations. The same is likely true for style queries, which should work on any container. That makes me want a more flexible syntax, where the order is less important. That could be done with two keywords ('for' <types> || 'as' <names>):But the more I stare at this, the more tempted I am to just use dashed-idents for names, and allow the two values to mingle completely:
That might also allow us to express and/or combinations, maybe with the
/divider between container-selection and query logic (if that division needs more clarity). Something like:We could consider adding parenthesis around any of these options, if it helps.
fantasai commentedon Oct 15, 2021
We don't really use preposition syntax markers outside of functions (at least not yet), and using --custom-property syntax here also feels kinda weird. What about:
You'd get things like this:
which doesn't seem unreasonable.
mirisuzanne commentedon Oct 18, 2021
I like this direction, giving
container-namethe primary slot — but we may want to combine that with a de-prioritizing ofcontainer-type. Right now we require a type in order to establish a container at all. I think, instead, we would want to say that every element(?) is astylecontainer by default (maybe with anormalkeyword as the initial value?), and then the type is only required when we want to query size? That maybe needs some more fleshing out, and could become a new issue, but I think it would help make this syntax work.mirisuzanne commentedon Dec 7, 2021
I think there are two or three potential consecutive resolutions here:
container-typeoptional for establishing containers:bramus commentedon Dec 8, 2021
If that were the case, that would solve Higher Level Custom Properties that were talked about late 2020, no? If I interpret things correctly, the there proposed
@if (<style-query) { … }could be seen as syntactic sugar for@container / style (<style-query) { … }, right?Furthermore, if all elements were style containers by default, is
stylestill a necessary value forcontainer-type? Reasoning: as all elements already are style containers, there's not need to define them manually as such, right?Note that in this case, as a side-effect to that decision, setting
container-typeto, for example,inline-sizewould be something to apply on top of it already being a style container. I.e.container-type: inline-size;will result in the element being both a style and size container.Regarding the syntax itself: I feel that there's some tight clinging onto the
@containerat-rule here. With all elements (possibly) being style containers, it — as an author — would feel more logical to write@style(<style-query>) { … }instead of@container / style (<style-query) { … }though.IIRC there is discussion somewhere that warned/decided against introducing a lot of new at-rules, so I can definitely understand. From an author's POV however, it feels a bit weird though. I think this "weirdness" stems from the fact that viewport media queries (
@media) always are size based queries, not style based ones.My initial reaction to container queries is the same: using
@containeris about the size of the element. I understand that it's more than size only, but I can imagine a lot of authors will be confused about it or only get part of the message (the size part), missing out on style/state/x containers.What I'm trying to say here: as an author, this piece of code would be highly readable, even if I wouldn't know the exact details about style or container queries:
A version that uses
@container / style (…)instead would be harder to read and can confusing, as@containerthere targets a parent whereas@container / styletargets the element itself.Given this last confusion I'm raising here: yes, this could be seen as a plea for keeping
@containerreserved for only size based querying.Apologies if I'm sidetracking here, or if I'm raising things in here that were already discussed. Feel free to ignore what's not relevant, I know you all will make the correct decisions in the end :)
(Congrats on hitting FPWD BTW! 🎉)
mirisuzanne commentedon Dec 9, 2021
That seems right to me.
Specifying the container-type isn't required in the current syntax, and (as you note)
stylemight not even be needed as a type if we do make it a default everywhere. We also made the queries into functions. So the currently proposed syntax here for most cases would be:I think that's already pretty readable? What I like about
@containeras a rule for both size and style is that it clarifies what element you are querying, before stating what feature to query – and then it allows you to optionally filter those elements by a container name:If we say that every element is a style container, then there would be no reason to ever use
/ stylein the preamble, since that would not filter out any elements.There is nothing about the word "container" that implies size, so this would only be true for authors with a strong historic attachment to "container queries" as an Idea. That seems to me like a very focused and temporary issue, easily overcome by some good resources.
bramus commentedon Dec 9, 2021
Thanks for clarifying, Miriam.
I was a bit confused about the functions part because the examples in the ED don't use it. For example, I see:
The definition for
<container-query>does already include this changeSo if I understand correctly, and if this change gets accepted, the snippet above would become this:
That's correct?
(As long as this issue is still open, I can see why the examples aren't updated yet. No worries)
I know what I'll be explicitly mentioning whenever I get to talk/write about them :)
mirisuzanne commentedon Dec 11, 2021
Yes, that's correct. I'll make sure to update the examples at some point here.
haha, great!
css-meeting-bot commentedon Jan 12, 2022
The CSS Working Group just discussed
CSS Conditional L3 : Syntax for container types, and agreed to the following:RESOLVED: Boxes default to style containment, syntax of 'container' and @container preamble is name / typeThe full IRC log of that discussion
<fantasai> Topic: CSS Conditional L3 : Syntax for container types<fantasai> github: https://github.com//issues/6393
<fantasai> miriam: Really wanted a way to query which type of conainer
<fantasai> miriam: e.g. find nearest inline-size container
<fantasai> miriam: Already the query has two parts to it
<fantasai> miriam: can query a specific named container
<fantasai> miriam: and then main query list is what queries against that container
<fantasai> miriam: so adding to preamble ability to filter by container type
<fantasai> miriam: in the discussion fantasai suggested that we could matched the syntax of the container shorthand property
<fantasai> miriam: currently that syntax requires a type, and then slash, and then any number of names
<fantasai> miriam: that could work, but in our initial formulation the container type is required to establish a container
<fantasai> miriam: which is why it's first
<fantasai> miriam: but for queries, seems that putting name first makes sense
<fantasai> miriam: since most ppl will be querying name, not type
<fantasai> miriam: Also discussion that all boxes can be style containers
<fantasai> miriam: which would make type container
<fantasai> miriam: make a style conainer
<fantasai> miriam: in that case, we could start with names in container property
<fantasai> miriam: and if you wanted to make a type of container without a name, would have to start the value with a slash
<fantasai> Rossen_: Any opinions?
<miriam> this comment lays it out: https://github.com//issues/6393#issuecomment-988216116
<fantasai> miriam: Comment summarizes the proposal
<fantasai> miriam: 3 resolutions
<fantasai> miriam: 1. Make style as the default container type, all boxes can take
<fantasai> miriam: 2. Changing 'container' property syntax to name / type
<fantasai> miriam: 3. Changing @container preamble to match
<fantasai> florian: I think we shoud take all 3, only make sense if we take them all
<fantasai> Rossen_: Any objections to resolving on all 3?
<fantasai> RESOLVED: Boxes default to style containment, syntax of 'container' and @container preamble is name / type
<fantasai> Rossen_: Do we need to republish soon?
<fantasai> miriam: need to make some changes first
1 remaining item
mirisuzanne commentedon Jan 14, 2022
While having all elements default to style containers can cause issues for non-inherited properties (like @una's background-color example), I think it works out great for inherited properties: checking the parent font size, or current font-style, weight, color, etc. Those use-cases are very handy for solving style-toggle use cases (if parent is italic, child should be normal, and vice versa).
For use-cases where it's important to query a specific container (including user-defined container types like 'containers with backgrounds'), setting a
container-namemakes it much more robust against the possibility of accidental intervening containers. Whether or not we revisit this resolution, I would still push authors towards naming containers when that's important — as it is withbackground-color.I'm happy to revisit this if we want to put it back on the agenda (or discuss it as a part of resolving #6644), but at this point I still think we made a reasonable decision.
una commentedon Feb 9, 2022
My main issue with this is I just don't think it's a reasonable default to assume that a user wants to query the style of a direct parent in a container query. In my current experience with CQ, the majority of my demos and use cases do not query the direct parent. To help illustrate:
CQ Card
.descwhich is within a block called.metabut I'm querying the parent.card's container sizein:
Button Component Inside CQ Card
spanwithin.btn-textis queryingbuttonbuttonwithindivwithin.cardis queryingcard-containerplus-iconwithin.cart-iconbecause it happens to be organized this wayin

astearns commentedon Feb 9, 2022
In #6644 (comment), we resolved to remove type from the preamble
mirisuzanne commentedon Feb 16, 2022
I split out the remaining questions here into a new issue #7066. Closing this issue as resolved, as we've decided to remove container-type selection syntax, and rely on automated container-type selection.
[css-contain-3] Reverse order of container shorthand syntax #6393
[css-contain-3] Change the initial value of container-type to be style …