1. Introduction
This is a diff spec over CSS Containment Level 2. It is currently an Exploratory Working Draft: if you are implementing anything, please use Level 2 as a reference. We will merge the Level 2 text into this draft once it reaches CR.
1.1. Module Interactions
This document defines new features not present in earlier specifications. In addition, it aims to replace and supersede [CSS-CONTAIN-1] once stable.
1.2. Value Definitions
This specification follows the CSS property definition conventions from [CSS2] using the value definition syntax from [CSS-VALUES-3]. Value types not defined in this specification are defined in CSS Values & Units [CSS-VALUES-3]. Combination with other CSS modules may expand the definitions of these value types.
In addition to the property-specific values listed in their definitions, all properties defined in this specification also accept the CSS-wide keywords as their property value. For readability they have not been repeated explicitly.
2. Strong Containment: the contain property
Opera40+Edge79+
Edge (Legacy)NoneIENone
Firefox for Android🔰 41+iOS SafariNoneChrome for Android52+Android WebView52+Samsung Internet6.0+Opera Mobile41+
CSS Containment 2 § 2 Strong Containment: the contain property
Name: | contain |
---|---|
New values: | layout || style || paint || [ size | inline-size | block-size ] |
- inline-size
- The value turns on inline-size containment for the element. This ensures that the inline containment box can be laid out without needing to examine its descendants.
- block-size
- The value turns on block-size containment for the element. This ensures that the block containment box can be laid out without needing to examine its descendants.
3. Types of Containment
CSS Containment 2 § 3 Types of Containment
3.1. Inline-Size Containment
Giving an element inline-size containment makes its principal box behave as a size containment box on the inline axis.
Define inline-size containment in more detail <https://github.com/w3c/csswg-drafts/issues/1031>
3.2. Block-Size Containment
Giving an element block-size containment makes its principal box behave as a size containment box on the block axis.
Define block-size containment in more detail <https://github.com/w3c/csswg-drafts/issues/1031>
4. Container Queries
While media queries provide a method to query aspects of the user agent or device environment that a document is being displayed in (such as viewport dimensions or user preferences), container queries allow testing aspects of elements within the document (such as box dimensions or computed styles).
A query container is established by specifying the possible query types using the container-type property (or the container shorthand). Style rules applying to its descendants can then be conditioned by querying against it, using the @container conditional group rule.
main, aside{ container : inline-size; } .media-object{ display : grid; grid-template : 'img' auto'content' auto /100 % ; } @container ( inline-size >45 em ) { .media-object{ grid-template : 'img content' auto / auto1 fr ; } }
Media objects in the main and sidebar areas will each respond to their own container context.
4.1. Creating Query Containers: the container-type property
Name: | container-type |
---|---|
Value: | none | style || state || [ size | inline-size | block-size ] |
Initial: | none |
Applies to: | all elements |
Inherited: | no |
Percentages: | n/a |
Computed value: | the keyword none or one or more of size, inline-size, block-size, style, state |
Canonical order: | per grammar |
Animation type: | not animatable |
The container-type property establishes the element as a query container for the purpose of container queries, allowing style rules styling its descendants to query various aspects of its sizing, layout, and style and respond accordingly.
Bikeshed terms/property names to avoid confusion with other usage of “contain” and “container”? <https://github.com/w3c/csswg-drafts/issues/6376>
Values have the following meanings:
- size
- Establishes a query container for size queries on both the inline and block axis. Applies layout containment, style containment, and size containment to the principal box.
- inline-size
- Establishes a query container for size queries on the container’s own inline axis. Applies layout containment, style containment, and inline-size containment to the principal box.
- block-size
- Establishes a query container for size queries on the container’s own block axis. Applies layout containment, style containment, and block-size containment to the principal box.
- style
- Establishes a query container for style queries.
- state
- Establishes a query container for state queries.
aside, main{ container-type : inline-size; } h2{ font-size : 1.2 em ; } @container ( width >40 em ) { h2{ font-size : 1.5 em ; } }
The 40em value used in the query condition is relative to the computed value of font-size on the relevant query container.
section{ container-type : style; } @container ( --cards) { article{ border : thin solid silver; border-radius : 0.5 em ; padding : 1 em ; } }
4.2. Naming Query Containers: the container-name property
Name: | container-name |
---|---|
Value: | none | [ <custom-ident> | <string> ]+ |
Initial: | none |
Applies to: | all elements |
Inherited: | no |
Percentages: | n/a |
Computed value: | a set of unique identifiers |
Canonical order: | per grammar |
Animation type: | not animatable |
The container-name property specifies a list of query container names. These names can be used by @container rules to filter which query containers are targeted.
- none
- The query container has no query container name.
- <custom-ident>
- Specifies a query container name as an identifier.
- <string>
- Specifies a query container name as a <string> value; this computes to an identifier with the same value as the given <string>.
The keyword none and the string "none" are invalid as <custom-ident> or <string> values.
main{ container-type : size; container-name : page-layout; } .my-component{ container-type : inline-size; container-name : component-library; } @container page-layout( block-size >12 em ) { .card{ margin-block : 2 em ; } } @container component-library( inline-size >30 em ) { .card{ margin-inline : 2 em ; } }
[ data-container] { container-name : attr ( data-container); }
This will set the the query container name to use the contents of the data-container attribute when provided.
4.3. Creating Named Containers: the container shorthand
Name: | container |
---|---|
Value: | <'container-type'> [ / <'container-name'> ]? |
Initial: | see individual properties |
Applies to: | see individual properties |
Inherited: | see individual properties |
Percentages: | see individual properties |
Computed value: | see individual properties |
Animation type: | see individual properties |
Canonical order: | per grammar |
The container shorthand property sets both container-type and container-name in the same declaration. If <'container-name'> is omitted, it is reset to its initial value.
main{ container : size / layout; } .grid-item{ container : inline-size / component; }
4.4. Container Queries: the @container rule
The @container rule is a conditional group rule whose condition is a container query, which is a boolean combination of size queries and/or style queries. Style declarations within the <stylesheet> block of an @container rule are filtered by its condition to only match when the container query is true for their element’s query container.
The syntax of the @container rule is:
@container [ <container-name> | [ name(<container-name>) || type(<container-type>+) ] ]? <container-query> { <stylesheet> }
where:
<container-condition> = not <container-query> | <container-query> [ and <container-query> ]* | <container-query> [ or <container-query> ]* <container-query> = ( <container-condition> ) | size( <size-query> ) | style( <style-query> ) <size-query> = <size-feature> | <size-condition> <size-condition> = not ( <size-query> ) | ( <size-query> ) [ and ( <size-query> ) ]* | ( <size-query> ) [ or ( <size-query> ) ]* <style-query> = <style-feature> | <style-condition> <style-condition> = not ( <style-query> ) | ( <style-query> ) [ and ( <style-query> ) ]* | ( <style-query> ) [ or ( <style-query> ) ]*
For each element, the query container to be queried is selected from among the element’s ancestor query containers. The optional <container-name> filters the set of query containers considered to just those with a matching query container name, and the optional <container-type> filters the set to just those with a matching container-type. The nearest remaining query container ancestor is selected.
Should the UA automatically filter to the nearest compatible query container if no specific type is provided?
Do we like this syntax for querying specific container types? <https://github.com/w3c/csswg-drafts/issues/6393>
A query container with a container-type of size is a match for both inline-size and block-size.
Once an eligible query container has been selected for an element, each container feature in the <container-query-list> is evaluated against that query container. If the selected query container is not a valid container-type for the feature, or no ancestor is an eligible query container, then the container query is unknown for that element.
@container card( inline-size >30 em ) and( --responsive = true) { /* styles */ }
The styles above will only be applied if there nearest ancestor container named "card" meets both the inline-size and style conditions.
Style rules defined on an element inside multiple nested container queries apply when all of the wrapping container queries are true for that element.
Note: Nested container queries can evaluate in relation to different containers, so it is not always possible to merge the individual <container-query-list>s into a single query.
5. Container Features
A container feature queries a specific aspect of a query container.
What container features can be queried? <https://github.com/w3c/csswg-drafts/issues/5989>
5.1. Size Container Features
A size query (syntactically represented as <size-query>) allows querying the size of the query container’s principal box. It is a boolean combination of individual size features (<size-feature>) that each query a single, specific dimensional feature of the query container. The syntax of a <size-feature> is the same as for a media feature: a feature name, a comparator, and a value. [mediaqueries-5] The boolean syntax and logic combining size features into a <size-query> is the same as for feature queries. (See @supports. [CSS-CONDITIONAL-3])
If the query container does not have a principal box, or the principal box is not a layout containment box, or the query container does not support size queries on the relevant axes, then the result of evaluating the size feature is unknown.
Relative length units in container query conditions are evaluated based on the the computed values of the query container.
Note: This is different from the handling of relative units in media queries.
aside, main{ container-type : inline-size; } aside{ font-size : 16 px ; } main{ font-size : 24 px ; } @container ( width >40 em ) { h2{ font-size : 1.5 em ; } }
The 40em value used in the query condition is relative to the computed value of font-size on the relevant query container:
-
For any h2 inside aside, the query condition will be true above 640px.
-
For any h2 inside main, the query condition will be true above 960px.
5.1.1. Width: the width feature
Name: | width |
---|---|
For: | @container |
Value: | <length> |
Type: | range |
The width container feature queries the width of the query container’s content box.
5.1.2. Height: the height feature
Name: | height |
---|---|
For: | @container |
Value: | <length> |
Type: | range |
The height container feature queries the height of the query container’s content box.
5.1.3. Inline-size: the inline-size feature
Name: | inline-size |
---|---|
For: | @container |
Value: | <length> |
Type: | range |
The inline-size container feature queries the size of the query container’s content box in the query container’s inline axis.
5.1.4. Block-size: the block-size feature
Name: | block-size |
---|---|
For: | @container |
Value: | <length> |
Type: | range |
The block-size container feature queries the size of the query container’s content box in the query container’s block axis.
5.1.5. Aspect-ratio: the aspect-ratio feature
Name: | aspect-ratio |
---|---|
For: | @container |
Value: | <ratio> |
Type: | range |
The aspect-ratio container feature is defined as the ratio of the value of the width container feature to the value of the height container feature.
5.1.6. Orientation: the orientation feature
Name: | orientation |
---|---|
For: | @container |
Value: | portrait | landscape |
Type: | discrete |
- portrait
- The orientation container feature is portrait when the value of the height container feature is greater than or equal to the value of the width container feature.
- landscape
- Otherwise orientation is landscape.
5.2. Style Container Features
A style queries (syntactically represented by <style-query>) allows querying the computed values of the query container. It is a boolean combination of individual style features (<style-feature>) that each query a single, specific property of the query container. The syntax of a <style-feature> is the same as for a declaration [CSS-SYNTAX-3], and its query is true if the computed value of the given property on the query container matches the given value (which is also computed with respect to the query container), unknown if the property or its value is unsupported, and false otherwise. The boolean syntax and logic combining style features into a <style-query> is the same as for feature queries. (See @supports. [CSS-CONDITIONAL-3])
Do we like this proposed syntax for style queries? <https://github.com/w3c/csswg-drafts/issues/6396>
5.3. State Container Features
State queries allow querying miscellaneous query container states, such as whether a position: sticky box is displaced from its in-flow position, or whether the box is visible on screen.
Define a syntax for state-based container queries <https://github.com/w3c/csswg-drafts/issues/6402>
6. Container Relative Lengths: the qw, qh, qi, qb, qmin, qmax units
Query length units specify a length relative to the dimensions of a query container. Style sheets that use query length units can more easily move components from one query container to another.
The query length units are:
unit | relative to |
---|---|
qw | 1% of a query container’s width |
qh | 1% of a query container’s height |
qi | 1% of a query container’s inline size |
qb | 1% of a query container’s block size |
qmin | The smaller value of qi or qb |
qmax | The larger value of qi or qb |
For each element, query length units are evaluated as size queries on the relevant axis (or axes) described by the unit. The query container for each axis is the nearest ancestor container that accepts size queries on that axis. If no eligible query container is available, then use the small viewport size for that axis.
Note: In some cases qi and qb units on the same element will evaluate in relation to different query containers. Similarly, qmin and qmax units represent the larger or smaller of the qi and qb units, even when those dimensions come from different query containers.
Child elements do not inherit the relative values as specified for their parent; they inherit the computed values.
/* The fallback value does not rely on containment */ h2{ font-size : 1.2 em ; } @container type ( inline-size) { /* only applies when an inline-size container is available */ h2{ font-size : calc ( 1.2 em +1 qi ); } }
"container width" and "container height" units <https://github.com/w3c/csswg-drafts/issues/5888>
7. Suppressing An Element’s Contents Entirely: the content-visibility property
In only one current engine.
Opera71+Edge85+
Edge (Legacy)NoneIENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android85+Android WebView85+Samsung Internet14.0+Opera Mobile60+
CSS Containment 2 § 4 Suppressing An Element’s Contents Entirely: the content-visibility property
8. Privacy and Security Considerations
CSS Containment 2 § 5 Privacy and Security Considerations
Appendix A. Changes
This appendix is informative.
Changes from CSS Containment Level 2
-
Defines the terms, properties, units, and at-rule needed for Container Queries
Acknowledgments
Comments and previous work from Adam Argyle, Amelia Bellamy-Royds, Anders Hartvoll Ruud, Brian Kardell, Chris Coyier, Christopher Kirk-Nielsen, David Herron, Elika J. Etemad (fantasai), Eric Portis, Ethan Marcotte, Geoff Graham, Gregory Wild-Smith, Ian Kilpatrick, Jen Simmons, Kenneth Rohde Christiansen, L. David Baron, Lea Verou, Martin Auswöger, Martine Dowden, Mike Riethmuller, Morten Stenshorne, Nicole Sullivan, Rune Lillesveen, Scott Jehl Scott Kellum, Stacy Kvernmo, Theresa O’Connor, Una Kravets, and many others have contributed to this specification.