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 InteractionsThis 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 DefinitionsThis 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 propertyCSS Containment 2 § 2 Strong Containment: the contain property
Note: There can still be indirect dependencies, see § 3.1 Inline-Size Containment.
CSS Containment 2 § 3 Types of Containment
3.1. Inline-Size ContainmentGiving an element inline-size containment applies size containment to the inline-axis sizing of its principal box. This means the inline-axis intrinsic sizes of the principal box are determined as if the element had no content. However, content continues to impact the box’s block-axis intrinsic sizes as usual, and the box is allowed to fragment normally in the block axis.
Note:In some cases, a box’s
block-axis intrinsic sizescan impact layout in the parent
formatting contextin ways that affect the box’s
inline size(e.g. by triggering scrollbars on an ancestor element), creating a dependency of the box’s
inline sizeon its own content. If this changed
inline sizeresults in a different
block size, that new
block sizecan loop into further impacting the parent formatting context, but not in a way that reverts it to the previously-problematic layout.
For example, if scrollbars were introduced, they are not then removed, even if the consequent block size is small enough to not need them; or if a box’s logical height collides with a lower-placed float and is cleared down to where it also has more available inline space and thus becomes short enough to not have collided, it is not them moved back up to its previous problematic size and position.
Thus, although inline-size containment prevents the box’s content from directly affecting its inline size through its inline-axis intrinsic sizes, its inline size can still indirectly depend on its contents by their effect on its block size.
In general, the relationship between an element’s inline size and it’s block size is unpredictable and non-monotonic, with the block size capable of shifting up and down arbitrarily as the inline size is changed. Infinite cycles are prevented by ensuring that layout does not revert to a previous (known-problematic) state, even if a naive analysis of the constraints would allow for such; in other words, layout always “moves forward”. We believe that current CSS layout specifications incorporate such rules, but to the extent that they don’t, please inform the CSSWG so that these errors can be corrected.
Consider this example, where float placement creates a dependency of block sizes on inline sizes:
<section style="width: 200px; border: solid; display: flow-root;"> <div style="float: left; width: 50px; height: 80px; background: blue;"></div> <div style="float: right; width: 50px; height: 80px; background: blue;"></div> <div style="float: left; width: 160px; height: 80px; background: navy;"></div> <article style="border: solid orangered; display: flow-root; min-width: min-content"> <div style="background: orange; aspect-ratio: 1/1;"> Article </div> </article> </section>
Article
The block layout algorithm will first place the floating boxes, with the first two sitting in the left and right corners of the container, and the third, being too wide to fit between, being pushed below them.
The following article
will then be laid out. Because it is display: flow-root, it cannot intersect any floats, and thus must take them into account when figuring out how to size and position itself.
The layout engine first attempts to place the article
flush with the top of the container, resulting a 100px width, plenty wide enough to accommodate its min-content size. However, due the aspect-ratio of its child, this would cause the article
to be 100px tall as well, which would intersect the third float 80px below, so this layout opportunity is discarded.
It then attempts to position the article
flush with the top of the third float, in the narrow 40px-wide space to its right. However, since the article
’s min-width makes it too large to fit in the 40px-wide space beside the third float, it shifts below that one as well, forming a 200px square below all the floated boxes.
Article
If the min-width is removed from the article
, or if inline-size containment is added to either the article
or header
(causing min-width: min-content to resolve to zero), then the article
will fit as a 40px square next to the final floated div
(possibly with some of its content overflowing).
At this point, the width and height of the article
(40px each) would fit back in the first considered space, flush with the top of the container. However, the box is not returned to the previous position, because the layout engine knows already that this position would result in an invalid layout.
Giving an element inline-size containment has no effect if any of the following are true:
if the element does not generate a principal box (as is the case with display: contents or display: none)
if its inner display type is table
if its principal box is an internal table box
if its principal box is an internal ruby box or a non-atomic inline-level box
Define inline-size containment in more detail (including additional examples) [Issue #1031]
4. Container QueriesWhile 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.
For example, we can define the main content area and sidebar as containers, and then describe a
.media-objectthat changes from vertical to horizontal layout depending on the size of its container:
main, aside { container: inline-size; } .media-object { display: grid; grid-template: 'img' auto 'content' auto / 100%; } @container (inline-size > 45em) { .media-object { grid-template: 'img content' auto / auto 1fr; } }
Media objects in the main and sidebar areas will each respond to their own container context.
4.1. Creating Query Containers: the container-type propertyThe 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”? [Issue #6376]
Values have the following meanings:
For example, authors can create container-responsive typography, adjusting
font-size,
line-height, and other typographic concerns based on the size of a container:
aside, main { container-type: inline-size; } h2 { font-size: 1.2em; } @container (width > 40em) { h2 { font-size: 1.5em; } }
The 40em value used in the query condition is relative to the computed value of font-size on the relevant query container.
Containers can also expose computed style values for querying. This can be useful for toggling behavior across multiple properties:
section { container-type: style; } @container (--cards) { article { border: thin solid silver; border-radius: 0.5em; padding: 1em; } }4.2. Naming Query Containers: the container-name property
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.
The keyword none and the string "none" are invalid as <custom-ident> or <string> values.
In some cases, we want to query aspects of a specific container, even if it’s not the nearest ancestor container. For example, we might want to query the height of a main content area, and the width of a more nested inline-container.
main { container-type: size; container-name: page-layout; } .my-component { container-type: inline-size; container-name: component-library; } @container page-layout (block-size > 12em) { .card { margin-block: 2em; } } @container component-library (inline-size > 30em) { .card { margin-inline: 2em; } }
Since
<string>values are allowed, we can also generate container names from attributes:
[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 shorthandThe 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.
We can define both a
container-typeand
container-nameusing the shorthand syntax:
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 container size queries and/or container 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? [Issue #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-condition> 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.
As with
media queries, we can string together multiple conditions in a single query list:
@container card (inline-size > 30em) 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-condition>s into a single query.
4.5. Animated ContainersA change in the evaluation of a container query must be part of a style change event, even when the change occurred because of animation effects.
A transition on a sibling element can indirectly affect the size of a container, triggering
style change eventswhenever container queries change their evaluation as a result:
main { display: flex; width: 300px; } #container { container: inline-size; flex: 1; } /* Resolved width is initially 200px, but changes as the transition on #sibling progresses. */ #inner { transition: 1s background-color; background-color: tomato; } /* When this container query starts (or stops) applying, a transition must start on background-color on #inner. */ @container (width <= 150px) { #inner { background-color: skyblue; } } #sibling { width: 100px; transition: width 1s; } #sibling:hover { width: 200px; }
<main> <div id=container> <div id=inner>Inner</div> </div> <div id=sibling>Sibling</div> </main>
Changes in computed values caused by container query length units must also be part of a style change event.
5. Container FeaturesA container feature queries a specific aspect of a query container.
What container features can be queried? [Issue #5989]
5.1. Size Container FeaturesA container 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 CSS 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 container 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.
For example,
query containerswith different font-sizes will evaluate
em-based queries relative to their own font sizes:
aside, main { container-type: inline-size; } aside { font-size: 16px; } main { font-size: 24px; } @container (width > 40em) { h2 { font-size: 1.5em; } }
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.
The width container feature queries the width of the query container’s content box.
5.1.2. Height: the height featureThe height container feature queries the height of the query container’s content box.
5.1.3. Inline-size: the inline-size featureThe 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 featureThe 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 featureThe 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: discreteA container style query (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 CSS feature queries. (See @supports. [CSS-CONDITIONAL-3])
Do we like this proposed syntax for style queries? [Issue #6396]
5.3. State Container FeaturesState 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 [Issue #6402]
6. Container Relative Lengths: the cqw, cqh, cqi, cqb, cqmin, cqmax unitsContainer query length units specify a length relative to the dimensions of a query container. Style sheets that use container query length units can more easily move components from one query container to another.
The container query length units are:
For each element, container query length units are evaluated as container 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 container 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 cqi and cqb units on the same element will evaluate in relation to different query containers. Similarly, cqmin and cqmax units represent the larger or smaller of the cqi and cqb 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.
Authors can ensure that
container query lengthunits have an appropriate
query containerby applying them inside a
container querywith the required
<container-type>. Custom fallback values can be defined outside the
container query:
/* The fallback value does not rely on containment */ h2 { font-size: 1.2em; } @container type(inline-size) { /* only applies when an inline-size container is available */ h2 { font-size: calc(1.2em + 1cqi); } }7. Suppressing An Element’s Contents Entirely: the content-visibility property
CSS Containment 2 § 4 Suppressing An Element’s Contents Entirely: the content-visibility property
8. Privacy and Security ConsiderationsCSS Containment 2 § 5 Privacy and Security Considerations
Appendix A. ChangesThis appendix is informative.
Changes from CSS Containment Level 2Defines the terms, properties, units, and at-rule needed for Container Queries
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.
Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.
All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]
Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example"
, like this:
Informative notes begin with the word “Note” and are set apart from the normative text with class="note"
, like this:
Note, this is an informative note.
Advisements are normative sections styled to evoke special attention and are set apart from other normative text with <strong class="advisement">
, like this: UAs MUST provide an accessible alternative.
A style sheet is conformant to this specification if all of its statements that use syntax defined in this module are valid according to the generic CSS grammar and the individual grammars of each feature defined in this module.
A renderer is conformant to this specification if, in addition to interpreting the style sheet as defined by the appropriate specifications, it supports all the features defined by this specification by parsing them correctly and rendering the document accordingly. However, the inability of a UA to correctly render a document due to limitations of the device does not make the UA non-conformant. (For example, a UA is not required to render color on a monochrome monitor.)
An authoring tool is conformant to this specification if it writes style sheets that are syntactically correct according to the generic CSS grammar and the individual grammars of each feature in this module, and meet all other conformance requirements of style sheets as described in this module.
So that authors can exploit the forward-compatible parsing rules to assign fallback values, CSS renderers must treat as invalid (and ignore as appropriate) any at-rules, properties, property values, keywords, and other syntactic constructs for which they have no usable level of support. In particular, user agents must not selectively ignore unsupported component values and honor supported values in a single multi-value property declaration: if any value is considered invalid (as unsupported values must be), CSS requires that the entire declaration be ignored.
Once a specification reaches the Candidate Recommendation stage, non-experimental implementations are possible, and implementors should release an unprefixed implementation of any CR-level feature they can demonstrate to be correctly implemented according to spec.
To establish and maintain the interoperability of CSS across implementations, the CSS Working Group requests that non-experimental CSS renderers submit an implementation report (and, if necessary, the testcases used for that implementation report) to the W3C before releasing an unprefixed implementation of any CSS features. Testcases submitted to W3C are subject to review and correction by the CSS Working Group.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4