<pre class="metadata">
Title: CSS Conditional Rules Module Level 5
Group: csswg
Shortname: css-conditional
Level: 5
Status: WD
Prepare for TR: yes
Date: 2025-10-30
!Delta Spec: yes
Work Status: Exploring
ED: https://drafts.csswg.org/css-conditional-5/
TR: https://www.w3.org/TR/css-conditional-5/
Editor: L. David Baron, Google https://www.google.com/, https://dbaron.org/, w3cid 15393
Editor: Elika J. Etemad / fantasai, Apple, http://fantasai.inkedblade.net/contact, w3cid 35400
Editor: Chris Lilley, W3C, https://svgees.us/, w3cid 1438
Editor: Miriam E. Suzanne, Invited Expert, https://www.miriamsuzanne.com/who/, w3cid 117151
Editor: Lea Verou, Invited Expert, https://lea.verou.me/about, w3cid 52258
Abstract: This module contains the features of CSS
	for conditional processing of parts of style sheets,
	based on capabilities of the processor or the environment
	the style sheet is being applied in.
	It includes and extends the functionality of CSS Conditional 4 [[!css-conditional-4]],
	adding the generalized conditional rule ''@when''
	and the chained conditional rule ''@else'',
	as well as introducing font processing queries
	to the [=supports query=] syntax used in ''@supports'' rules,
	and container queries.
Default Highlight: css
WPT Path Prefix: css/css-conditional/
WPT Display: open
</pre>

<pre class="link-defaults">
	spec:css-break-3; type:dfn; text:forced break
	spec:css-break-3; type:dfn; text:fragmentation
	spec:css-break-3; type:dfn; text:fragmentation container
	spec:css-break-3; type:dfn; text:fragmentation context
	spec:css-break-3; type:dfn; text:fragmented flow
	spec:css-cascade-5; type:dfn; text:property
	spec:css-conditional-3; type:dfn; text:conditional group rule
	spec:css-conditional-3; type:type; text:<supports-decl>
	spec:css-conditional-4; type:type; text:<supports-selector-fn>
	spec:css-contain-2; type:dfn; text:layout containment box
	spec:css-contain-2; type:dfn; text:size containment box
	spec:css-display-3; type:property; text:display
	spec:css-fonts-4; type:type; text:<font-format>
	spec:css-fonts-4; type:type; text:<font-tech>
	spec:css-grid-1; type:property; text:grid
	spec:css-pseudo-4; type:dfn; text:fictional tag sequence
	spec:css-pseudo-4; type:selector; text:::file-selector-button
	spec:css-pseudo-4; type:selector; text:::placeholder
	spec:css-scroll-snap-2; type:dfn; text:scrollsnapchanging
	spec:css-sizing-3; type:dfn; text:height
	spec:css-sizing-3; type:dfn; text:size
	spec:css-sizing-3; type:dfn; text:width
	spec:css-sizing-3; type:property; text:height
	spec:css-sizing-3; type:property; text:min-height
	spec:css-sizing-3; type:property; text:min-width
	spec:css-sizing-4; type:property; text:aspect-ratio
	spec:css-sizing-4; type:property; text:contain-intrinsic-size
	spec:css-ui-3; type:property; text:text-overflow
	spec:css-values-4; type:dfn; text:identifier
	spec:css-values-4; type:dfn; text:relative length
	spec:css2; type:dfn; text:stacking context
	spec:css2; type:property; text:content
	spec:css2; type:property; text:counter-increment
	spec:infra; type:dfn; text:list
	spec:intersection-observer; type:dfn; text:intersection root
	spec:selectors-4; type:dfn; text:pseudo-elements
	spec:web-animations-1; type:dfn; text:effect values
</pre>

<h2 id="introduction">
Introduction</h2>

	ISSUE: This is currently an early draft of the things that are <em>new</em> in level 5.
	The features in Level 3 and Level 4 are still defined
	in [[css-conditional-3]] and [[css-conditional-4]]
	and have not yet been copied here.

	CSS Conditional Level 5 extends
	the ''@supports'' rule and [=supports query=] syntax
	to allow testing for custom support conditions as well as supported [=at-rules=] and font technologies.

	It also adds an ''@when'' rule,
	which generalizes the concept of a conditional rule.
	Anything that can be expressed in an existing conditional rule
	can be expressed in ''@when''
	by wrapping it in an appropriate function
	to declare what kind of condition it is.
	This allow authors to easily combine multiple types of queries,
	such as media queries and supports queries,
	in a single boolean expression.
	Without this,
	authors must rely on nesting separate conditional rules,
	which is harder to read and write,
	presupposes the conditions are to be conjoined with the “and” boolean relation
	(with no easy way to indicate anything else),
	and restricts their utility in the proposed [=conditional rule chains=].

	It also adds ''@else'' rules,
	which immediately follow other conditional rules
	and automatically qualify their conditions
	as the inverse of the immediately preceding rule’s conditions,
	such that only the first matching rule in a [=conditional rule chain=]
	is applied.

	It also adds Container Queries.
	They are conceptually similar to Media Queries,
	but allow testing aspects of elements within the document (such as box dimensions or computed styles),
	rather than on the document as a whole.

<h2 id="at-supports-ext">
Extensions to the ''@supports'' rule</h2>

	This level of the specification extends the <<supports-feature>> syntax as follows:

	<pre class="prod def" nohighlight>
		<dfn>&lt;supports-feature></dfn> = <<supports-selector-fn>>
		                   | <<supports-font-tech-fn>> | <<supports-font-format-fn>>
		                   | <<supports-at-rule-fn>> | <<supports-named-feature-fn>>
		                   | <<supports-env-fn>> | <<supports-decl>>
		<dfn>&lt;supports-decl></dfn> = ( [ <<declaration>> | <<supports-condition-name>> ] )
		<dfn>&lt;supports-font-tech-fn></dfn> = font-tech( <<font-tech>> )
		<dfn>&lt;supports-font-format-fn></dfn> = font-format( <<font-format>> )
		<dfn>&lt;supports-at-rule-fn></dfn> = at-rule( <<at-keyword-token>> )
		<dfn>&lt;supports-named-feature-fn></dfn> = named-feature( <<ident>> )
		<dfn>&lt;supports-env-fn></dfn> = env( <<ident>> )
	</pre>

	<dfn>&lt;declaration></dfn> here matches anything that would be successfully parsed by <l spec=css-syntax>[=consume a declaration=]</l>,
	ignoring the context-validation check at the end of that algorithm.
	<span class=note>Notably, this includes a trailing ''!important'',
	which is valid but ignored for the purpose of ''@supports''.</span>

	<dl dfn-type=function dfn-for="@supports">
		: <<supports-condition-name>>
		::
			The result is true if the UA
			<a href="#dfn-supports-condition-name">supports the named condition</a>.
			If the name is not recognized,
			the result is false.

		: <dfn>font-tech( <<font-tech>> )</dfn>
		::
			The result is true if the UA
			[=supports the font tech=]
			provided as an argument to the function.

		: <dfn>font-format( <<font-format>> )</dfn>
		::
			The result is true if the UA
			[=supports the font format=]
			provided as an argument to the function.

		: <dfn>at-rule( <<at-keyword-token>> )</dfn>
		::
			The result is true if the UA
			[=supports the at-rule=]
			provided as an argument to the function.

		: <dfn>named-feature( <<ident>> )</dfn>
		::
			The result is true if the UA
			[=supports the named feature=]
			provided as an argument to the function.

		: <dfn>env( <<ident>> )</dfn>
		::
			The result is true if the UA
			[=supports the environment variable=]
			provided as an argument to the function.
	</dl>

<h3 id="support-definition-ext">
Extensions to the definition of support</h3>

<h4 id="support-definition-ext-fonts">
Font techs and formats</h4>

	<wpt>
		js/CSS-supports-L5.html
	</wpt>

	A CSS processor is considered to
	<dfn export for=CSS id="dfn-support-font-tech" lt="support a font tech|support the font tech">support a font tech</dfn>
	when it is capable of utilizing the specified [[css-fonts-4#font-tech-definitions]]
	in layout and rendering.

	A CSS processor is considered to
	<dfn export for=CSS id="dfn-support-font-format" lt="support a font format|support the font format">support a font format</dfn>
	when it is capable of utilizing the specified [[css-fonts-4#font-format-definitions]]
	in layout and rendering,
	and this format is not specified as a <<string>>.

<h4 id="support-definition-at-rules">
At-rules</h4>

	<wpt>
		js/supports-at-rule.html
	</wpt>

	A CSS processor is considered to
	<dfn export for=CSS id="dfn-support-at-rule" lt="support an at-rule | support the at-rule">support an at-rule</dfn>
	if it would accept an [=at-rule=] beginning with the specified at-keyword
	within any context.

	Note: Because ''@charset'' is not a valid [=at-rule=],
	it is not considered to be supported under this definition.

<h4 id="support-definition-named-features">
Named features</h4>

	A CSS processor is considered to
	<dfn export for=CSS id="dfn-support-named-feature" lt="support a named feature|support the named feature">support a named feature</dfn>
	if it supports the named feature based on the feature definition
	described in the following list:

	<dl value for="named-feature()" export>
		: <dfn>anchor-position-follows-transforms</dfn>
		:: Anchoring to a transformed element automatically takes into account the anchor's transforms,
			causing the positioned element to shift to match it.
			[[CSS-ANCHOR-POSITIONING]]

			(An earlier version of the specification did not take transforms into account.)
	
		: <dfn>single-axis-scroll-container</dfn>
		:: The ability to have [=single-axis scroll containers=],
			where one axis is scrollable and the other is ''overflow/clip''.
			[[CSS-OVERFLOW-4]]

			(Previously, specifying ''overflow/clip'' alongside a scrollable value caused it to compute to ''overflow/hidden'',
			which is still a scrollable value even if it doesn't generate a scrollbar.)
	</dl>

	If the feature is not listed the processor does not support the named feature.

	Note: The CSS Working Group intends to add features to this list rarely,
	when there is real demand for feature testing something specific
	and it would be unreasonable to add a more general feature testing mechanism
	that would cover the use case.

<h4 id="support-definition-supports-condition-name">
Named conditions</h4>

	A CSS processor is considered to
	<dfn export for=CSS id="dfn-supports-condition-name" lt="support a named condition|support the named condition">support a named condition</dfn>
	when the related [=named supports condition=] returns true.

<h4 id="support-definition-env">
Environment variables</h4>

	A CSS processor is considered to
	<dfn export for=CSS id="dfn-support-env" lt="support an environment variable|support the environment variable">support an environment variable</dfn>
	if the <<ident>> is a supported [=environment variable=].

<h2 id="when-rule">
Generalized Conditional Rules: the ''@when'' rule</h2>

	The <dfn>@when</dfn> at-rule is a [=conditional group rule=]
	that generalizes the individual [=conditional group rules=]
	such as ''@media'' and ''@supports''.
	It is defined as:

	<pre class=prod>
		@when <<boolean-condition>> {
		  <<rule-list>>
		}
	</pre>

	Where <dfn><<boolean-condition>></dfn> is a boolean algebra a la [[mediaqueries-4#mq-syntax]],
	but with ''media()'' and ''supports()'' functions as leaves.

	Issue: Define "boolean algebra, with X as leaves" in a generic way in Conditional,
	so all the conditional rules can reference it directly,
	rather than having to redefine boolean algebra on their own.

	The ''media()'' and ''supports()'' functions are defined as:

	<pre class=prod>
	<dfn>media()</dfn> = media( [ <<mf-plain>> | <<mf-boolean>> | <<mf-range>> ] )
	<dfn>supports()</dfn> = supports( <<declaration>> )
	</pre>

	A ''media()'' or ''supports()'' function is associated with the boolean result
	that its contained condition is associated with.

<h2 id="else-rule">
Chained Conditionals: the ''@else'' rule</h2>

	Usually, [=conditional group rules=] are independent;
	each one has a separate condition
	evaluated without direct reference to any other rule,
	and decides whether or not to apply its contained rules
	based solely on its condition.

	This is fine for simple conditions,
	but makes it difficult to write a collection of conditionals
	that are meant to be mutually exclusive:
	authors have to very carefully craft their conditions
	to not activate when the other rules are meant to,
	and make sure the collection of conditionals
	don't accidentally <em>all</em> exclude some situation
	which is then left unstyled.

	The <dfn>@else</dfn> rule is a [=conditional group rule=]
	used to form [=conditional rule chains=],
	which associate multiple [=conditional group rules=]
	and guarantee that only the first one that matches
	will evaluate its condition as true.
	It is defined as:

	<pre class=prod>
		@else <<boolean-condition>>? {
			<<rule-list>>
		}
	</pre>

	''@else'' is interpreted identically to ''@when''.
	If its <<boolean-condition>> is omitted,
	it's treated as having a condition that's always true.

	A <dfn export>conditional rule chain</dfn> is
	a series of consecutive [=conditional group rules=],
	starting with a [=conditional group rule=] other than ''@else'',
	followed by zero or more ''@else'' rules.
	There cannot be anything between the successive [=conditional group rules=]
	other than whitespace and/or comments;
	any other token “breaks” the chain.

	Issue: Should we require that only the last ''@else'' in a chain can have an omitted condition?
	It's not uncommon for me, when debugging code,
	to short-circuit an if-else chain by setting one of them to "true";
	I presume that would be similarly useful in CSS?
	It's still pretty easy to see you've done something wrong if you omit the condition accidentally.

	Within a [=conditional rule chain=],
	the conditions of each [=conditional group rule=] are evaluated in order.
	If one of them is true,
	the conditions of all <em>following</em> [=conditional group rules=] in the chain
	evaluate to false,
	regardless of their stated condition.

	An ''@else'' rule that is not part of a [=conditional rule chain=]
	is invalid and must be ignored.

	<div class=example>
		For example, here's a (somewhat silly) conditional chain:

		<pre class="lang-css">
			@when media(width >= 400px) and media(pointer: fine) and supports(display: flex) {
			  /* A */
			} @else supports(caret-color: pink) and supports(background: double-rainbow()) {
			  /* B */
			} @else {
			  /* C */
			}
		</pre>

		Exactly one of the preceding rules will be chosen,
		even though the second rule
		doesn't exclude large widths, fine points, or flexbox support,
		and the last rule
		doesn't specify anything at all.

		To achieve the same result without [=conditional rule chains=],
		you'd need to write:

		<pre class="lang-css">
			@media (width >= 400px) and (pointer: fine) {
			  @supports (display: flex) {
				/* A */
			  }
			  @supports not (display: flex) {
				@supports (caret-color: pink) and (background: double-rainbow()) {
				  /* B */
				}
				@supports not ((caret-color: pink) and (background: double-rainbow())) {
				  /* C */
				}
			  }
			}
			@media not ((width >= 400px) and (pointer: fine)) {
			  @supports (caret-color: pink) and (background: double-rainbow()) {
				/* B */
			  }
			  @supports not ((caret-color: pink) and (background: double-rainbow())) {
				/* C */
			  }
			}
		</pre>

		This is simultaneously hard to read,
		requires significant duplication of both conditions and contents,
		and is <em>very</em> difficult to write correctly.
		<!-- (I wrote it wrong <em>twice</em> while producing this example.) -->
		If the conditions got any more complicated
		(which is not unusual in real-world content),
		the example would get <em>significantly</em> worse.
	</div>

	<div class="example">
		In this example, three different color font technologies
		are tested, in order of preference,
		plus a monochrome fallback.
		The most capable, COLRv1, supports both gradients and font variations;
		the next best choice, SVG, supports gradients
		while the least capable, COLRv0, supports flat color fill only.

		The fallback has no test condition,
		so will always be chosen unless one of the earlier conditions succeeds.

		<pre class="lang-css">
			@when font-tech(color-COLRv1) and font-tech(variations) {
			  @font-face { font-family: icons; src: url(icons-gradient-var.woff2); }
			}
			@else font-tech(color-SVG) {
			  @font-face { font-family: icons; src: url(icons-gradient.woff2); }
			}
			@else font-tech(color-COLRv0) {
			  @font-face { font-family: icons; src: url(icons-flat.woff2); }
			}
			@else {
			  @font-face { font-family: icons; src: url(icons-fallback.woff2); }
			}
		</pre>

		Notice that in this example,
		the variable color font is only downloaded
		if COLRv1 is supported
		and font variations are also supported.

		Notice too that only one of the available options will be downloaded;
		this would not be the case without ''@when'' and ''@else'',
		as the next example shows.
	</div>

	<div class="example">
		In this example,
		although it appears that the fallback will not be used
		if COLRv1 is supported,
		in fact both fonts will be downloaded,
		which wastes bandwidth if it is not used.

		The fallback might still be used for some characters;
		for example, if the color font supports only Latin,
		while the fallback supports Latin and Greek.

		<pre class="lang-css">
			@font-face { font-family: icons; src: url(icons-fallback.woff2);
			@supports font-tech(color-COLRv1) {
			  @font-face { font-family: icons; src: url(icons-gradient-var.woff2); }
			}
		</pre>
	</div>

<h2 id="container-queries">
Container Queries</h2>

	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).

	By default, all elements are <dfn export lt="query container">query containers</dfn>
	for the purpose of [=container style queries=],
	and can be established as [=query containers=]
	for [=container size queries=] and [=container scroll-state queries=] by specifying
	the additional query types using the 'container-type' property
	(or the 'container' [=shorthand=]).
	Style rules applying to a [=query container=]’s [=flat tree=] descendants
	can be conditioned by querying against it,
	using the ''@container'' [=conditional group rule=].

	An ancestor element that generates a box is not an eligible container for
	[=container size queries=] if that box is not an ancestor box of any boxes
	generated by the querying element.

	<div class=note>
		There are cases where the box for a [=pseudo-element=] is generated as a
		sibling box of its originating element's box. If we allowed querying the size
		of a sibling box, it would introduce layout cycles.

		For example, the ''::scroll-marker-group'' and ''::scroll-button()'' pseudo-elements
		generate sibling boxes of their originating element's box.
		These pseudo-elements will not be able to query their originating scroller
		for [=container size queries=]. They will, however, be able to query other
		eligible [=query container=] ancestors.
	</div>

	<div class=example>
		For example, we can define the main content area and sidebar as containers,
		and then describe a ''.media-object'' that changes
		from vertical to horizontal layout depending on the size of its container:

		<pre class=lang-css>
		main, aside {
		  container: my-layout / inline-size;
		}

		.media-object {
		  display: grid;
		  grid-template: 'img' auto 'content' auto / 100%;
		}

		@container my-layout (inline-size > 45em) {
		  .media-object {
			grid-template: 'img content' auto / auto 1fr;
		  }
		}
		</pre>

		Media objects in the main and sidebar areas
		will each respond to their own container context.
	</div>

	For the ''::part()'' and ''::slotted()'' <a>pseudo-element</a> selectors,
	which represent real elements in the DOM tree, [=query containers=] can be
	established by [=flat tree=] ancestors of those elements.
	For other <a>pseudo-element</a>s, [=query containers=] can be established by
	inclusive [=flat tree=] ancestors of their <a>originating element</a>.

	<div class=note>
		It follows that:

		* ''::before'', ''::after'', ''::marker'', and ''::backdrop'' query their
			originating elements
		* ''::first-letter'' and ''::first-line'' query their originating elements,
			even if the <a>fictional tag sequence</a> may push the
			<code>::first-line</code> past other elements for the purpose of
			inheritance and rendering
		* ''::slotted()'' selectors can query containers inside the shadow tree,
			including the slot itself
		* ''::slotted()::before'' selectors can query the slotted shadow host child
		* ''::part()'' selectors can query containers inside the shadow tree
		* ''::placeholder'' and ''::file-selector-button'' can query the input
			element, but do not expose any internal containers if the input element is
			implemented using a shadow tree
	</div>

	<div class=example>
		A ::before selector querying the size of the originating element:

		<pre class=lang-html>
		&lt;style>
		  #container {
			width: 100px;
			container-type: inline-size;
		  }
		  @container (inline-size < 150px) {
			#inner::before {
			  content: "BEFORE";
			}
		  }
		&lt;/style>
		&lt;div id=container>
		  &lt;span id=inner>&lt;/span>
		&lt;/div>
		</pre>
	</div>

	<div class=example>
		A ::slotted() selector for styling a shadow host child can query a
		container in the shadow tree:

		<pre class=lang-html>
		&lt;div id=host style="width:200px">
		  &lt;template shadowroot=open>
			&lt;style>
			  #container {
				width: 100px;
				container-type: inline-size;
			  }
			  @container (inline-size < 150px) {
				::slotted(span) {
				  color: green;
				}
			  }
			&lt;/style>
			&lt;div id=container>
			  &lt;slot />
			&lt;/div>
		  &lt;/template>
		  &lt;span id=slotted>Green&lt;/span>
		&lt;/div>
		</pre>
	</div>

<h3 id="container-type">
Creating Query Containers: the 'container-type' property</h3>

	<pre class='propdef'>
		Name: container-type
		Value: normal | [ [ size | inline-size ] || scroll-state ]
		Initial: normal
		Inherited: no
		Applies to: all elements
		Computed value: specified keyword
		Animation type: not animatable
	</pre>

	The 'container-type' property establishes the element as a
	[=query container=] for certain types of queries. For size
	[=container queries=], which require certain types of containment, elements
	are explicitly made [=query containers=] through this property. For other
	types of [=query containers=] any element can be a [=query container=], such
	as for [=container style queries=].

	Values have the following meanings:

	<dl dfn-type=value dfn-for=container-type>
		<dt><dfn>size</dfn>
		<dd>
			Establishes a [=query container=] for [=container size queries=]
			on both the [=inline axis|inline=] and [=block axis=].
			Applies [=style containment=] and [=size containment=]
			to the [=principal box=],
			and establishes an [=independent formatting context=].
		<dt><dfn>inline-size</dfn>
		<dd>
			Establishes a [=query container=] for [=container size queries=]
			on the container’s own [=inline axis=].
			Applies [=style containment=] and [=inline-size containment=]
			to the [=principal box=],
			and establishes an [=independent formatting context=].
		<dt><dfn>scroll-state</dfn>
		<dd>
			Establishes a [=query container=] for [=container scroll-state queries=].
			For queries that match the state of the scroller itself
			(such as ''@container/scrollable''),
			the element is only a [=query container=]
			on the element's own [=scrollable axises=].

			Note: This means that a ''scrollable'' query, for example,
			could query against different containers
			for ''scroll-state(scrollable: block)'' and ''scroll-state(scrollable: inline)'' queries.
		<dt><dfn>normal</dfn>
		<dd>
			The element is not a [=query container=]
			for any [=container size queries=] or [=container scroll-state queries=],
			but remains a [=query container=] for [=container style queries=].
	</dl>

	<div class=example>
		For example, authors can create container-responsive typography,
		adjusting 'font-size', 'line-height', and other typographic concerns
		based on the size of a container:

		<pre class=lang-css>
		aside, main {
		  container-type: inline-size;
		}

		h2 { font-size: 1.2em; }

		@container (width > 40em) {
		  h2 { font-size: 1.5em; }
		}
		</pre>

		The ''40em'' value used in the query condition
		is relative to the [=computed value=] of 'font-size'
		on the relevant [=query container=].
	</div>

	<div class=example>
		Containers can also expose computed style values for querying.
		This can be useful for toggling behavior across multiple properties:

		<pre class=lang-css>
		@container style(--cards: small) {
		  article {
			border: thin solid silver;
			border-radius: 0.5em;
			padding: 1em;
		  }
		}
		</pre>
	</div>

	<div class=example>
		Containers can also expose state that depends on scroll offset. This example
		styles a descendant of a sticky positioned element when it is stuck to the
		top edge:

		<pre class=lang-css>
		#sticky {
		  container-type: scroll-state;
		  position: sticky;
		}
		@container scroll-state(stuck: top) {
		  #sticky-child {
			background-color: lime;
		  }
		}
		</pre>
	</div>

<h3 id="container-name">
Naming Query Containers: the 'container-name' property</h3>

	<pre class='propdef'>
		Name: container-name
		Value: none | <<custom-ident>>+
		Initial: none
		Inherited: no
		Applies to: all elements
		Computed Value: the keyword ''container-name/none'', or an ordered list of [=identifiers=]
		Animation type: not animatable
	</pre>

	<wpt>
		container-queries/container-ident-function.html
		container-queries/container-ident-function.html
	</wpt>

	The 'container-name' property
	specifies a list of <dfn export lt="query container name">query container names</dfn>.
	These names can be used by ''@container'' rules
	to filter which [=query containers=] are targeted.
	Container names are not [=tree-scoped names=].

	<dl dfn-for=container-name dfn-type=value>
	<dt><dfn>none</dfn>
	<dd>
		The [=query container=] has no [=query container name=].
	<dt><dfn><<custom-ident>></dfn>
	<dd>
		Specifies a [=query container name=] as an [=identifier=].
		The keywords ''container-name/none'', ''and'', ''not'', and ''or'' are excluded from this <<custom-ident>>.
	</dl>

	<div class=example>
		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.

		<pre class=lang-css>
		main {
		  container-type: size;
		  container-name: my-page-layout;
		}

		.my-component {
		  container-type: inline-size;
		  container-name: my-component-library;
		}

		@container my-page-layout (block-size > 12em) {
		  .card { margin-block: 2em; }
		}

		@container my-component-library (inline-size > 30em) {
		  .card { margin-inline: 2em; }
		}
		</pre>

		It is also possible to query for a container only based on its name.

		<pre class=lang-css>
		@container my-page-layout {
		  .card { padding: 1em; }
		}
		</pre>
	</div>


<h3 id="container-shorthand">
Creating Named Containers: the 'container' shorthand</h3>

	<pre class='propdef shorthand'>
		Name: container
		Value: <<'container-name'>> [ / <<'container-type'>> ]?
	</pre>

	<wpt>
		container-queries/animation-container-size.html
		container-queries/animation-container-type-dynamic.html
		container-queries/animation-nested-animation.html
		container-queries/animation-nested-transition.html
		container-queries/aspect-ratio-feature-evaluation.html
		container-queries/at-container-parsing.html
		container-queries/at-container-serialization.html
		container-queries/at-container-style-parsing.html
		container-queries/at-container-style-serialization.html
		container-queries/auto-scrollbars.html
		container-queries/backdrop-invalidation.html
		container-queries/calc-evaluation.html
		container-queries/canvas-as-container-001.html
		container-queries/canvas-as-container-002.html
		container-queries/canvas-as-container-003.html
		container-queries/canvas-as-container-004.html
		container-queries/canvas-as-container-005.html
		container-queries/canvas-as-container-006.html
		container-queries/change-display-in-container.html
		container-queries/chrome-legacy-skip-recalc.html
		container-queries/column-spanner-in-container.html
		container-queries/conditional-container-status.html
		container-queries/container-computed.html
		container-queries/container-for-cue.html
		container-queries/container-for-shadow-dom.html
		container-queries/container-inheritance.html
		container-queries/container-inner-at-rules.html
		container-queries/container-inside-multicol-with-table.html
		container-queries/container-longhand-animation-type.html
		container-queries/container-name-computed.html
		container-queries/container-name-invalidation.html
		container-queries/container-name-parsing.html
		container-queries/container-name-tree-scoped.html
		container-queries/container-nested.html
		container-queries/container-parsing.html
		container-queries/container-selection-unknown-features.html
		container-queries/container-selection.html
		container-queries/container-size-invalidation-after-load.html
		container-queries/container-size-invalidation.html
		container-queries/container-size-nested-invalidation.html
		container-queries/container-size-shadow-invalidation.html
		container-queries/container-type-computed.html
		container-queries/container-type-containment.html
		container-queries/container-type-invalidation.html
		container-queries/container-type-layout-invalidation.html
		container-queries/container-type-parsing.html
		container-queries/container-units-animation.html
		container-queries/container-units-basic.html
		container-queries/container-units-computational-independence.html
		container-queries/container-units-content-box.html
		container-queries/container-units-gradient-invalidation.html
		container-queries/container-units-gradient.html
		container-queries/container-units-in-at-container-dynamic.html
		container-queries/container-units-in-at-container-fallback.html
		container-queries/container-units-in-at-container.html
		container-queries/container-units-ineligible-container.html
		container-queries/container-units-invalidation.html
		container-queries/container-units-media-queries.html
		container-queries/container-units-rule-cache.html
		container-queries/container-units-selection.html
		container-queries/container-units-shadow.html
		container-queries/container-units-sharing-via-rule-node.html
		container-queries/container-units-small-viewport-fallback.html
		container-queries/container-units-svglength.html
		container-queries/container-units-typed-om.html
		container-queries/counters-flex-circular.html
		container-queries/counters-in-container-dynamic.html
		container-queries/counters-in-container.html
		container-queries/crashtests/br-crash.html
		container-queries/crashtests/canvas-as-container-crash.html
		container-queries/crashtests/chrome-bug-1289718-000-crash.html
		container-queries/crashtests/chrome-bug-1289718-001-crash.html
		container-queries/crashtests/chrome-bug-1346969-crash.html
		container-queries/crashtests/chrome-bug-1362391-crash.html
		container-queries/crashtests/chrome-bug-1429955-crash.html
		container-queries/crashtests/chrome-bug-1505250-crash.html
		container-queries/crashtests/chrome-bug-346264227-crash.html
		container-queries/crashtests/chrome-bug-372358471-crash.html
		container-queries/crashtests/chrome-custom-highlight-crash.html
		container-queries/crashtests/chrome-layout-root-crash.html
		container-queries/crashtests/chrome-quotes-crash.html
		container-queries/crashtests/chrome-remove-insert-evaluator-crash.html
		container-queries/crashtests/columns-in-table-001-crash.html
		container-queries/crashtests/columns-in-table-002-crash.html
		container-queries/crashtests/container-in-canvas-crash.html
		container-queries/crashtests/container-type-change-chrome-legacy-crash.html
		container-queries/crashtests/dialog-backdrop-crash.html
		container-queries/crashtests/dirty-rowgroup-crash.html
		container-queries/crashtests/flex-in-columns-000-crash.html
		container-queries/crashtests/flex-in-columns-001-crash.html
		container-queries/crashtests/flex-in-columns-002-crash.html
		container-queries/crashtests/flex-in-columns-003-crash.html
		container-queries/crashtests/focus-inside-content-visibility-crash.html
		container-queries/crashtests/force-sibling-style-crash.html
		container-queries/crashtests/grid-in-columns-000-crash.html
		container-queries/crashtests/grid-in-columns-001-crash.html
		container-queries/crashtests/grid-in-columns-002-crash.html
		container-queries/crashtests/grid-in-columns-003-crash.html
		container-queries/crashtests/iframe-init-crash.html
		container-queries/crashtests/inline-multicol-inside-container-crash.html
		container-queries/crashtests/inline-with-columns-000-crash.html
		container-queries/crashtests/inline-with-columns-001-crash.html
		container-queries/crashtests/input-column-group-container-crash.html
		container-queries/crashtests/input-placeholder-inline-size-crash.html
		container-queries/crashtests/marker-gcs-after-disconnect-crash.html
		container-queries/crashtests/math-block-container-child-crash.html
		container-queries/crashtests/mathml-container-type-crash.html
		container-queries/crashtests/orthogonal-replaced-crash.html
		container-queries/crashtests/pseudo-container-crash.html
		container-queries/crashtests/remove-dom-child-change-style.html
		container-queries/crashtests/reversed-ol-crash.html
		container-queries/crashtests/size-change-during-transition-crash.html
		container-queries/crashtests/svg-layout-root-crash.html
		container-queries/crashtests/svg-resource-in-container-crash.html
		container-queries/crashtests/svg-text-crash.html
		container-queries/crashtests/table-in-columns-000-crash.html
		container-queries/crashtests/table-in-columns-001-crash.html
		container-queries/crashtests/table-in-columns-002-crash.html
		container-queries/crashtests/table-in-columns-003-crash.html
		container-queries/crashtests/table-in-columns-004-crash.html
		container-queries/crashtests/table-in-columns-005-crash.html
		container-queries/crashtests/top-layer-crash.html
		container-queries/crashtests/top-layer-nested-crash.html
		container-queries/custom-layout-container-001.https.html
		container-queries/custom-property-style-queries.html
		container-queries/custom-property-style-query-change.html
		container-queries/deep-nested-inline-size-containers.html
		container-queries/dialog-backdrop-create.html
		container-queries/dialog-backdrop-remove.html
		container-queries/display-contents-dynamic-style-queries.html
		container-queries/display-contents.html
		container-queries/display-in-container.html
		container-queries/display-none.html
		container-queries/fieldset-legend-change.html
		container-queries/flex-basis-with-container-type.html
		container-queries/font-relative-calc-dynamic.html
		container-queries/font-relative-units-dynamic.html
		container-queries/font-relative-units.html
		container-queries/fragmented-container-001.html
		container-queries/get-animations.html
		container-queries/grid-container.html
		container-queries/grid-item-container.html
		container-queries/idlharness.html
		container-queries/iframe-in-container-invalidation.html
		container-queries/iframe-invalidation.html
		container-queries/ineligible-containment.html
		container-queries/inheritance-from-container.html
		container-queries/inline-size-and-min-width.html
		container-queries/inline-size-bfc-floats.html
		container-queries/inline-size-containment-vertical-rl.html
		container-queries/inline-size-containment.html
		container-queries/inner-first-line-non-matching.html
		container-queries/layout-dependent-focus.html
		container-queries/multicol-container-001.html
		container-queries/multicol-inside-container.html
		container-queries/nested-query-containers.html
		container-queries/nested-size-style-container-invalidation.html
		container-queries/never-match-container.html
		container-queries/no-layout-containment-abspos-dynamic.html
		container-queries/no-layout-containment-abspos.html
		container-queries/no-layout-containment-baseline.html
		container-queries/no-layout-containment-fixedpos-dynamic.html
		container-queries/no-layout-containment-fixedpos.html
		container-queries/no-layout-containment-scroll.html
		container-queries/no-layout-containment-subgrid-crash.html
		container-queries/orthogonal-wm-container-query.html
		container-queries/percentage-padding-orthogonal.html
		container-queries/pseudo-elements-001.html
		container-queries/pseudo-elements-002.html
		container-queries/pseudo-elements-002b.html
		container-queries/pseudo-elements-003.html
		container-queries/pseudo-elements-004.html
		container-queries/pseudo-elements-005.html
		container-queries/pseudo-elements-006.html
		container-queries/pseudo-elements-007.html
		container-queries/pseudo-elements-008.html
		container-queries/pseudo-elements-009.html
		container-queries/pseudo-elements-010.html
		container-queries/pseudo-elements-011.html
		container-queries/pseudo-elements-012.html
		container-queries/pseudo-elements-013.html
		container-queries/query-content-box.html
		container-queries/query-evaluation-style.html
		container-queries/query-evaluation.html
		container-queries/reattach-container-with-dirty-child.html
		container-queries/registered-color-style-queries.html
		container-queries/resize-while-content-visibility-hidden.html
		container-queries/scroll-state/at-container-scrollable-parsing.html
		container-queries/scroll-state/at-container-scrollable-serialization.html
		container-queries/scroll-state/at-container-snapped-parsing.html
		container-queries/scroll-state/at-container-snapped-serialization.html
		container-queries/scroll-state/at-container-stuck-parsing.html
		container-queries/scroll-state/at-container-stuck-serialization.html
		container-queries/scroll-state/container-type-scroll-state-computed.html
		container-queries/scroll-state/container-type-scroll-state-containment.html
		container-queries/scroll-state/container-type-scroll-state-parsing.html
		container-queries/scroll-state/scroll-state-initially-scrollable.html
		container-queries/scroll-state/scroll-state-initially-snapped.html
		container-queries/scroll-state/scroll-state-initially-stuck.html
		container-queries/scroll-state/scroll-state-scrollable-change.html
		container-queries/scroll-state/scroll-state-scrollable-container-type-change.html
		container-queries/scroll-state/scroll-state-scrollable-layout-change.html
		container-queries/scroll-state/scroll-state-scrollable-wm.html
		container-queries/scroll-state/scroll-state-snapped-change.html
		container-queries/scroll-state/scroll-state-snapped-container-type-change.html
		container-queries/scroll-state/scroll-state-snapped-layout-change.html
		container-queries/scroll-state/scroll-state-snapped-none.html
		container-queries/scroll-state/scroll-state-snapped-snap-changing.html
		container-queries/scroll-state/scroll-state-snapped-wm.html
		container-queries/scroll-state/scroll-state-stuck-container-type-change.html
		container-queries/scroll-state/scroll-state-stuck-layout-change.html
		container-queries/scroll-state/scroll-state-stuck-writing-direction.html
		container-queries/scroll-state/scroll-state-target-query-change.html
		container-queries/scrollbar-container-units-block.html
		container-queries/scrollbar-container-units-inline.html
		container-queries/sibling-layout-dependency.html
		container-queries/size-container-no-principal-box.html
		container-queries/size-container-with-quotes.html
		container-queries/size-container-writing-mode-change.html
		container-queries/size-feature-evaluation.html
		container-queries/style-change-in-container.html
		container-queries/style-container-for-shadow-dom.html
		container-queries/style-container-invalidation-inheritance.html
		container-queries/style-not-sharing-float.html
		container-queries/style-query-document-element.html
		container-queries/style-query-no-cycle.html
		container-queries/style-query-with-unknown-width.html
		container-queries/svg-foreignobject-child-container.html
		container-queries/svg-foreignobject-no-size-container.html
		container-queries/svg-g-no-size-container.html
		container-queries/svg-root-size-container.html
		container-queries/table-inside-container-changing-display.html
		container-queries/top-layer-dialog-backdrop.html
		container-queries/top-layer-dialog-container.html
		container-queries/top-layer-dialog.html
		container-queries/top-layer-nested-dialog.html
		container-queries/transition-scrollbars.html
		container-queries/transition-style-change-event-002.html
		container-queries/transition-style-change-event.html
		container-queries/unsupported-axis.html
		container-queries/viewport-units-dynamic.html
		container-queries/viewport-units.html
		container-queries/whitespace-update-after-removal.html
	</wpt>

	The 'container' [=shorthand property=] sets
	both 'container-type' and 'container-name' in the same declaration.
	If <<'container-type'>> is omitted,
	it is reset to its [=initial value=].

	<div class=example>
		We can define both a 'container-type' and 'container-name'
		using the shorthand syntax:

		<pre class=lang-css>
		main {
		  container: my-layout / size;
		}

		.grid-item {
		  container: my-component / inline-size;
		}
		</pre>
	</div>


<h3 id="container-rule">
Container Queries: the ''@container'' rule</h3>

	The <dfn at-rule id="at-ruledef-container">@container</dfn> rule
	is a [=conditional group rule=] whose condition contains
	a <dfn export>container query</dfn>,
	which is a boolean combination of [=container size queries=] and/or [=container style queries=].
	Style declarations within the ''@container'' rule
	are [[css-cascade-4#filtering|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:

	<pre class="prod def">
	@container <<container-condition>># {
	  <<rule-list>>
	}
	</pre>

	where:

	<pre class="prod def">
	<dfn><<container-condition>></dfn> = [ <<container-name>>? <<container-query>>? ]!
	<dfn><<container-name>></dfn> = <<custom-ident>>
	<dfn><<container-query>></dfn> = not <<query-in-parens>>
					  | <<query-in-parens>> [ [ and <<query-in-parens>> ]* | [ or <<query-in-parens>> ]* ]
	<dfn><<query-in-parens>></dfn> = ( <<container-query>> )
					  | ( <<size-feature>> )
					  | style( <<style-query>> )
					  | scroll-state( <<scroll-state-query>> )
					  | <<general-enclosed>>

	<dfn><<style-query>></dfn>     = not <<style-in-parens>>
					  | <<style-in-parens>> [ [ and <<style-in-parens>> ]* | [ or <<style-in-parens>> ]* ]
					  | <<style-feature>>
	<dfn><<style-in-parens>></dfn> = ( <<style-query>> )
					  | ( <<style-feature>> )
					  | <<general-enclosed>>
	<dfn><<style-feature>></dfn> = <<style-feature-plain>> | <<style-feature-boolean>> | <<style-range>>
	<dfn><<style-feature-plain>></dfn> = <<style-feature-name>> : <<style-feature-value>>
	<dfn><<style-feature-boolean>></dfn> = <<style-feature-name>>
	<dfn><<style-range>></dfn> = <<style-range-value>> <<mf-comparison>> <<style-range-value>>
			| <<style-range-value>> <<mf-lt>> <<style-range-value>> <<mf-lt>> <<style-range-value>>
			| <<style-range-value>> <<mf-gt>> <<style-range-value>> <<mf-gt>> <<style-range-value>>
	<dfn><<style-range-value>></dfn> = <<custom-property-name>> | <<style-feature-value>>

	<dfn><<scroll-state-query>></dfn>     = not <<scroll-state-in-parens>>
							 | <<scroll-state-in-parens>> [ [ and <<scroll-state-in-parens>> ]* | [ or <<scroll-state-in-parens>> ]* ]
							 | <<scroll-state-feature>>
	<dfn><<scroll-state-in-parens>></dfn> = ( <<scroll-state-query>> )
							 | ( <<scroll-state-feature>> )
							 | <<general-enclosed>>
	</pre>

	<wpt>
		container-queries/container-ident-function.html
		container-queries/container-ident-function.html
		container-queries/multiple-size-containers-comma-separated-queries.html
		container-queries/multiple-style-containers-comma-separated-queries.html
		container-queries/query-container-name.html
		container-queries/scroll-state/at-container-scrolled-parsing.html
		container-queries/scroll-state/multiple-scroll-state-containers-comma-separated-queries.html
		container-queries/scroll-state/scroll-state-query-with-var.html
		container-queries/size-query-with-var.html
	</wpt>

	The keywords ''container-name/none'', ''and'', ''not'', and ''or''
	are excluded from the <<custom-ident>> above.

	For each element,
	the [=query container=] to be queried
	is selected from among the element’s ancestor [=query containers=]
	that are established as a valid [=query container=]
	for all the [=container features=]
	in the <<container-query>>. If the <<container-query>> contains
	unknown or unsupported [=container feature=]s,
	no [=query container=] will be selected for that <<container-condition>>.
	The <<container-name>> filters the set of [=query containers=] considered
	to just those with a matching [=query container name=].

	Once an eligible [=query container=] has been selected for an element,
	each [=container feature=] in the <<container-query>>
	is evaluated against that [=query container=].
	If no ancestor is an eligible [=query container=],
	then the [=container query=] is ''unknown'' for that element.
	As with media queries, <<general-enclosed>> evaluates to ''unknown''.
	If the <<container-query>> is omitted, the [=query container=] is eligible as
	long as the <<container-name>> matches.

	If a [=container query=] includes multiple <<container-condition>>s,
	each condition will select it's own [=query container=],
	and evaluate independently.
	A [=container query=] is ''true'' if <em>any</em> of its component
	<<container-condition>>s are ''true'',
	and ''false'' only if <em>all</em> of its component
	<<container-condition>>s are ''false''.

	<div class=example>
		As with [=media queries=],
		we can string together multiple queries in a single condition:

		<pre class=lang-css>
		@container card (inline-size > 30em) and style(--responsive: true) {
		  /* styles */
		}
		</pre>

		The styles above will only be applied
		if there is an ancestor container named "card"
		that meets both the '@container/inline-size'
		and [=container style query|style=] conditions.

		We can also combine multiple conditions into a list,
		with each condition evaluating against a different container:

		<pre class=lang-css>
		@container card (inline-size > 30em), style(--large: true) {
		  /* styles */
		}
		</pre>

		The styles above will be applied
		if there is an ancestor container named "card"
		that meets the '@container/inline-size' condition
		<em>or</em> the nearest style container
		meets the [=container style query|style=] condition.
	</div>

	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.

	<div class=example>
		Using a single comma-separated [=container query=],
		we can query multiple containers:

		<pre class=lang-css>
		@container card (inline-size > 30em), style(--responsive: true) {
		  /* styles */
		}
		</pre>

		The styles above will apply for an element inside <em>either</em>
		a container named "card" that meets the '@container/inline-size' condition,
		<em>or</em> a container meeting the [=container style query|style=] condition.

		In order to require that <em>all</em> conditions are met
		while querying multiple containers,
		we would need to nest multiple queries:

		<pre class=lang-css>
		@container card (inline-size > 30em) {
		  @container style(--responsive: true) {
			/* styles */
		  }
		}
		</pre>

		The styles above will only be applied
		if there is <em>both</em> an ancestor container named "card"
		that meets the '@container/inline-size' condition,
		<em>and</em> an ancestor container
		meeting the [=container style query|style=] condition.
	</div>

	Global, name-defining [=at-rules=]
	such as ''@keyframes'' or ''@font-face'' or ''@layer''
	that are defined inside [=container queries=]
	are not constrained by the [=container query=] conditions.


<h3 id="animated-containers">
Animated Containers</h3>

	A change in the evaluation of a [=container query=] must be part of a [=style change event=],
	even when the change occurred because of [=effect values|animation effects=].

	<div class=example>
		A transition on a sibling element can indirectly affect the size of a
		container, triggering [=style change events=] whenever container queries
		change their evaluation as a result:

		<pre class=lang-css>
			main {
			  display: flex;
			  width: 300px;
			}

			#container {
			  container-type: 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;
			}
		</pre>

		<pre class=lang-html>
			&lt;main>
			  &lt;div id=container>
				&lt;div id=inner>Inner&lt;/div>
			  &lt;/div>
			  &lt;div id=sibling>Sibling&lt;/div>
			&lt;/main>
		</pre>

	</div>

	Changes in [=computed values=] caused by [=container query length=] units
	must also be part of a [=style change event=].


<h2 id="container-features">
Container Features</h2>

	A <dfn export>container feature</dfn>
	queries a specific aspect of a [=query container=].

	[=Container features=] use the same rules as [=media features=] when evaluating
	in a [=boolean context=].

<h3 id="size-container">
Size Container Features</h3>

	A <dfn export>container size query</dfn>
	allows querying
	the size of the [=query container=]’s [=principal box=].
	It is a boolean combination of
	individual <dfn export>size features</dfn> (<<size-feature>>)
	that each query a single, specific dimensional feature of the [=query container=].
	The syntax of a <dfn><<size-feature>></dfn> 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 [=container size query|size query=]
	is the same as for [=CSS feature queries=].
	(See ''@supports''. [[!css-conditional-3]])

	<wpt>
		container-queries/size-container-auto-height.html
		container-queries/var-evaluation.html
	</wpt>

	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
	(including [=container query length=] units)
	and [=custom properties=]
	in [=container query=] conditions
	are evaluated based on the [=computed values=] of the [=query container=].

	Tree counting functions ([[css-values-5#tree-counting]]) are evaluated against
	the container element.

	Note: This is different from the handling of relative units in [=media queries=].

	Note: If [=custom property=] substitution results in an invalid value for the
	[=size feature=], it is handled the same as other invalid feature values,
	and the result of the [=size feature=] is ''unknown''.

	<div class=example>
		For example, [=query containers=] with different font-sizes
		will evaluate ''em''-based queries relative to their own font sizes:

		<pre class=lang-css>
		aside, main {
		  container-type: inline-size;
		}

		aside { font-size: 16px; }
		main { font-size: 24px; }

		@container (width > 40em) {
		  h2 { font-size: 1.5em; }
		}
		</pre>

		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''.
	</div>

	<div class=example>
		Similarly, [=query containers=] will evaluate ''var()''-based queries
		relative to their own [=computed value=] of the [=custom property=]:

		<pre class=lang-css>
		aside, main {
		  container-type: inline-size;
		}

		aside { --query: 300px; }
		main { --query: 500px; }

		@container (width > var(--query)) {
		  h2 { font-size: 1.5em; }
		}
		</pre>

		The ''var(--query)'' value used in the query condition
		is substituted with the [=computed value=] of
		the ''--query'' [=custom property=] on the relevant [=query container=]:

		* For any ''h2'' inside ''aside'',
			the query condition will be true above ''300px''.
		* For any ''h2'' inside ''main'',
			the query condition will be true above ''500px''.
	</div>

<h4 id="width">
Width: the '@container/width' feature</h4>

	<pre class="descdef mq">
		Name: width
		For: @container
		Value: <<length>>
		Type: range
	</pre>

	The '@container/width' [=container feature=]
	queries the [=width=]
	of the [=query container=]’s [=content box=].

<h4 id="height">
Height: the '@container/height' feature</h4>

	<pre class="descdef mq">
		Name: height
		For: @container
		Value: <<length>>
		Type: range
	</pre>

	The '@container/height' [=container feature=]
	queries the [=height=]
	of the [=query container=]’s [=content box=].

<h4 id="inline-size">
Inline-size: the '@container/inline-size' feature</h4>

	<pre class="descdef mq">
		Name: inline-size
		For: @container
		Value: <<length>>
		Type: range
	</pre>

	The '@container/inline-size' [=container feature=]
	queries the [=size=]
	of the [=query container=]’s [=content box=]
	in the [=query container=]’s [=inline axis=].


<h4 id="block-size">
Block-size: the '@container/block-size' feature</h4>

	<pre class="descdef mq">
		Name: block-size
		For: @container
		Value: <<length>>
		Type: range
	</pre>

	The '@container/block-size' [=container feature=]
	queries the [=size=]
	of the [=query container=]’s [=content box=]
	in the [=query container=]’s [=block axis=].


<h4 id="aspect-ratio">
Aspect-ratio: the '@container/aspect-ratio' feature</h4>

	<pre class="descdef mq">
		Name: aspect-ratio
		For: @container
		Value: <<ratio>>
		Type: range
	</pre>

	The '@container/aspect-ratio' [=container feature=] is defined as the ratio
	of the value of the '@container/width' [=container feature=]
	to the value of the '@container/height' [=container feature=].


<h4 id="orientation">
Orientation: the '@container/orientation' feature</h4>

	<pre class="descdef mq">
		Name: orientation
		For: @container
		Value: portrait | landscape
		Type: discrete
	</pre>

	<dl dfn-type=value dfn-for="@container/orientation">
		<dt><dfn>portrait</dfn>
		<dd>
			The '@container/orientation' [=container feature=] is ''portrait''
			when the value of the '@container/height' [=container feature=]
			is greater than or equal to
			the value of the '@container/width' [=container feature=].
		<dt><dfn>landscape</dfn>
		<dd>Otherwise '@container/orientation' is ''landscape''.
	</dl>


<h3 id="style-container">
Style Container Features</h3>

	A <dfn export>container style query</dfn> allows querying
	the [=computed values=] of the [=query container=].
	It is a boolean combination of individual <dfn export>style features</dfn>
	(<<style-feature>>) that each query a single, specific property of the [=query container=].
	The syntax of a <<style-feature>>
	is either the same as for a valid [=declaration=][[!CSS-SYNTAX-3]],
	a <<style-feature-name>>
	or a valid <dfn export>style range</dfn> (<<style-range>>).
	The <dfn><<style-feature-name>></dfn> can be either a [=supported CSS property=]
	or a valid <<custom-property-name>>.
	The <dfn><<style-feature-value>></dfn> production matches any valid <<declaration-value>>
	as long as it doesn't contain <<mf-lt>>, <<mf-gt>> and <<mf-eq>> tokens.

	<wpt>
		container-queries/style-query-registered-custom-rem-change.html
		container-queries/style-query-unset-on-root.html
	</wpt>

	A <<style-feature-plain>> evaluates to true
	if the [=computed value=] of the given property
	on the [=query container=] matches the given value
	(which is also [=computed value|computed=] with respect to the [=query container=]),
	and false otherwise.

	A [=style feature=] without a value (<<style-feature-boolean>>) evaluates to true
	if the [=computed value=] is different
	from the [=initial value=]
	for the given [=property=].

	<div algorithm>
		To <dfn noexport>evaluate a <<style-range>></dfn>,
		the following steps needs to be performed:

		1. If <<style-range-value>> is a <<custom-property-name>>,
			it needs to be substituted
			as if the <<custom-property-name>> was wrapped inside a ''var()''.
		2. Substitute [=arbitrary substitution function=] within <<style-range-value>>.
		3. Parse <<style-range-value>> to
			<<number>>, <<percentage>>, <<length>>, <<angle>>, <<time>>, <<frequency>> or <<resolution>>.
			If this cannot be done, evaluate to false.
		4. If each <<style-range-value>> from the range have the same type,
			compute each and evaluate the comparison;
			a unitless zero must be treated as being a zero-<<length>> when compared against a <<length>> .
		5. Otherwise evaluate to false.
	</div>

	The boolean syntax and logic combining [=style features=] into a [=container style query|style query=]
	is the same as for [=CSS feature queries=].
	(See ''@supports''. [[!css-conditional-3]])

	[=Style features=] that query a [=shorthand property=] are true if the
	[=computed values=] match for each of its [=longhand properties=],
	and false otherwise.

	[=Cascade-dependent keywords=], such as ''revert'' and ''revert-layer'',
	are invalid as values in a [=style feature=], and cause the
	[=container style query=] to be false.

	Note: The remaining non-cascade-dependent [=CSS-wide keywords=]
	are [=computed value|computed=] with respect to the [=query container=],
	the same as other values.

<h3 id="scroll-state-container">
Scroll State Container Features</h3>

	A <dfn export>container scroll-state query</dfn>
	allows querying a container for state that depends on scroll position.
	It is a boolean combination
	of individual <dfn lt="scroll-state feature">scroll-state features</dfn>
	(<<scroll-state-feature>>)
	that each query a single feature of the [=query container=].
	The syntax of a <dfn><<scroll-state-feature>></dfn> is the same as for a [=media feature=]:
	a feature name, a comparator, and a value.

	[=Scroll-state features=] can either match state of the scroller itself
	(such as the ''scrollable'' feature),
	or an element that is affected by the scroll position
	of an ancestor [=scroll container's=] [=scrollport=]
	(such as the ''snapped'' feature).

<h4 id="updating-scroll-state">
Updating Scroll State</h4>

	Scroll state may cause layout cycles since queried scroll state may cause style changes,
	which may lead to scroll state changes as a result of layout.

	To avoid such layout cycles,
	''scroll-state'' [=query containers=] update their current state
	as part of [=run snapshot post-layout state steps=]
	which is only run at specific points in the
	<a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model">HTML event loop processing model</a>.

	When asked to [=run snapshot post-layout state steps=],
	update the current state of every ''scroll-state'' [=query container=].
	This snapshotted state will be used for any style and layout updates
	until the next time these steps are run.

<h4 id="stuck">
Sticky positioning: the '@container/stuck' feature</h4>

	<pre class="descdef mq">
		Name: stuck
		For: @container
		Value: none | top | right | bottom | left | block-start | inline-start | block-end | inline-end
		Type: discrete
	</pre>

	<wpt>
		container-queries/scroll-state/scroll-state-stuck-pseudo.html
	</wpt>

	The '@container/stuck' [=container feature=] queries whether a
	''position/sticky'' positioned container is visually shifted to stay inside
	the [=sticky view rectangle=] for the given edge. The logical edges map to
	physical based on the direction and writing-mode of the [=query container=].
	None of the values match if the [=query container=] is not [=sticky positioned=].

	It is possible for two values from opposite axes to match at the same time,
	but not for opposite edges along the same axis.

	<div class=example>
		May match:
		<pre class="lang-css">
		  @container scroll-state((stuck: top) and (stuck: left)) { ... }
		</pre>

		Will never match:
		<pre class="lang-css">
		  @container scroll-state((stuck: left) and (stuck: right)) { ... }
		</pre>
	</div>

	<dl dfn-type=value dfn-for="@container/stuck">
		<dt><dfn>none</dfn>
		<dd>
			The ''position/sticky'' container is not shifted in any direction.
		<dt><dfn>top</dfn>
		<dd>
			The ''position/sticky'' container is shifted to stay inside the top edge.
		<dt><dfn>right</dfn>
		<dd>
			The ''position/sticky'' container is shifted to stay inside the right edge.
		<dt><dfn>bottom</dfn>
		<dd>
			The ''position/sticky'' container is shifted to stay inside the bottom edge.
		<dt><dfn>left</dfn>
		<dd>
			The ''position/sticky'' container is shifted to stay inside the left edge.
		<dt><dfn>block-start</dfn>
		<dd>
			The ''position/sticky'' container is shifted to stay inside the [=block-start=] edge.
		<dt><dfn>inline-start</dfn>
		<dd>
			The ''position/sticky'' container is shifted to stay inside the [=inline-start=] edge.
		<dt><dfn>block-end</dfn>
		<dd>
			The ''position/sticky'' container is shifted to stay inside the [=block-end=] edge.
		<dt><dfn>inline-end</dfn>
		<dd>
			The ''position/sticky'' container is shifted to stay inside the [=inline-end=] edge.
	</dl>

<h4 id="snapped">
Scroll snapping: the '@container/snapped' feature</h4>

	<pre class="descdef mq">
		Name: snapped
		For: @container
		Value: none | x | y | block | inline | both
		Type: discrete
	</pre>

	<wpt>
		container-queries/scroll-state/scroll-state-snapped-both.html
		container-queries/scroll-state/scroll-state-snapped-pseudo.html
	</wpt>

	The '@container/snapped' [=container feature=] queries
	whether a [=snap target=] is, or would be,
	snapped to its [=scroll snap container=] in the given axis.
	That is, it matches any [=snap target=] that the {{scrollsnapchanging}} event is fired for.

	<dl dfn-type=value dfn-for="@container/snapped">
		<dt><dfn>none</dfn>
		<dd>
			The [=query container=] is not a [=snap target=].
		<dt><dfn>x</dfn>
		<dd>
			'@container/snapped' [=container feature=] matches ''@container/snapped/x''
			if the [=query container=] is a horizontal [=snap target=] for its [=scroll container=].
		<dt><dfn>y</dfn>
		<dd>
			'@container/snapped' [=container feature=] matches ''@container/snapped/y''
			if the [=query container=] is a vertical [=snap target=] for its [=scroll container=].
		<dt><dfn>block</dfn>
		<dd>
			'@container/snapped' [=container feature=] matches ''@container/snapped/block''
			if the [=query container=] is a [=snap target=] for its [=scroll container=].
			in the block direction of the [=scroll snap container=].
		<dt><dfn>inline</dfn>
		<dd>
			'@container/snapped' [=container feature=] matches ''@container/snapped/inline''
			if the [=query container=] is a [=snap target=] for its [=scroll container=]
			in the inline direction of the [=scroll snap container=].
		<dt><dfn>both</dfn>
		<dd>
			'@container/snapped' [=container feature=] matches ''both''
			if the [=query container=] is a [=snap target=] for its [=scroll container=]
			in both directions of the [=scroll snap container=].
	</dl>

<h4 id="scrollable">
Scrollable: the '@container/scrollable' feature</h4>

	<pre class="descdef mq">
		Name: scrollable
		For: @container
		Value: none | top | right | bottom | left | block-start | inline-start | block-end | inline-end | x | y | block | inline
		Type: discrete
	</pre>

	<wpt>
		container-queries/scroll-state/scroll-state-scrollable-axis.html
		container-queries/scroll-state/scroll-state-scrollable-body-001.html
		container-queries/scroll-state/scroll-state-scrollable-body-002.html
		container-queries/scroll-state/scroll-state-scrollable-layout-change-002.html
		container-queries/scroll-state/scroll-state-scrollable-pseudo.html
		container-queries/scroll-state/scroll-state-scrollable-root.html
	</wpt>

	The '@container/scrollable' [=container feature=] queries
	whether a [=scroll container=] has clipped [=scrollable overflow rectangle=] content in the given direction
	which is reachable through user initiated scrolling.
	That is, '@container/scrollable' does not match for a ''overflow/hidden'' container,
	nor for a [=unreachable scrollable overflow region=].

	The logical values map to physical
	based on the direction and writing-mode of the [=query container=].
	None of the values match if the container is not a [=scroll container=].

	<dl dfn-type=value dfn-for="@container/scrollable">
		<dt><dfn>none</dfn>
		<dd>
			The [=scroll container=] does not have [=scrollable overflow=] in any direction.
		<dt><dfn>top</dfn>
		<dd>
			The [=scroll container=] has [=scrollable overflow=] past the top edge.
		<dt><dfn>right</dfn>
		<dd>
			The [=scroll container=] has [=scrollable overflow=] past the right edge.
		<dt><dfn>bottom</dfn>
		<dd>
			The [=scroll container=] has [=scrollable overflow=] past the bottom edge.
		<dt><dfn>left</dfn>
		<dd>
			The [=scroll container=] has [=scrollable overflow=] past the left edge.
		<dt><dfn>block-start</dfn>
		<dd>
			The [=scroll container=] has [=scrollable overflow=] past the [=block-start=] edge.
		<dt><dfn>inline-start</dfn>
		<dd>
			The [=scroll container=] has [=scrollable overflow=] past the [=inline-start=] edge.
		<dt><dfn>block-end</dfn>
		<dd>
			The [=scroll container=] has [=scrollable overflow=] past the [=block-end=] edge.
		<dt><dfn>inline-end</dfn>
		<dd>
			The [=scroll container=] has [=scrollable overflow=] past the [=inline-end=] edge.
		<dt><dfn>x</dfn>
		<dd>
			The [=scroll container=] has horizontally [=scrollable overflow=].
		<dt><dfn>y</dfn>
		<dd>
			The [=scroll container=] has vertically [=scrollable overflow=].
		<dt><dfn>block</dfn>
		<dd>
			The [=scroll container=] has [=scrollable overflow=] in its block direction.
		<dt><dfn>inline</dfn>
		<dd>
			The [=scroll container=] has [=scrollable overflow=] in its inline direction.
	</dl>

<h4 id="scrolled">
Scrolled: the '@container/scrolled' feature</h4>

	<pre class="descdef mq">
		Name: scrolled
		For: @container
		Value: none | top | right | bottom | left | block-start | inline-start | block-end | inline-end | x | y | block | inline
		Type: discrete
	</pre>

	<wpt>
		container-queries/scroll-state/scroll-state-scrolled-arrow-key-scroll.html
		container-queries/scroll-state/scroll-state-scrolled-home-end-scroll.html
		container-queries/scroll-state/scroll-state-scrolled-hv.html
		container-queries/scroll-state/scroll-state-scrolled-keyboard-scroll-on-body.html
		container-queries/scroll-state/scroll-state-scrolled-keyboard-scroll-on-root.html
		container-queries/scroll-state/scroll-state-scrolled-mouse-drag-scroll.html
		container-queries/scroll-state/scroll-state-scrolled-multiple-scrollers.html
		container-queries/scroll-state/scroll-state-scrolled-programmatic-absolute-scrolls.html
		container-queries/scroll-state/scroll-state-scrolled-programmatic-relative-scrolls.html
		container-queries/scroll-state/scroll-state-scrolled-pu-pd-scroll.html
		container-queries/scroll-state/scroll-state-scrolled-scrollbar-button-clicks.html
		container-queries/scroll-state/scroll-state-scrolled-scrollbar-track-clicks.html
		container-queries/scroll-state/scroll-state-scrolled-spacebar-scroll.html
		container-queries/scroll-state/scroll-state-scrolled-user-touch-scroll.html
		container-queries/scroll-state/scroll-state-scrolled-wheel-scroll.html
		container-queries/scroll-state/scroll-state-scrolled-wm.html
		container-queries/scroll-state/at-container-scrolled-parsing.html
		container-queries/scroll-state/at-container-scrolled-serialization.html
	</wpt>

	For a [=query container=] that is a [=scroll container=],
	the '@container/scrolled' [=container feature=] queries the direction
	of its most recent [=relative scroll=].
	The logical values map to physical
	based on the direction and writing-mode of the [=query container=].
	None of the values match if the container is not a [=scroll container=].

	<dl dfn-type=value dfn-for="@container/scrolled">
		<dt><dfn>none</dfn>
		<dd>
			The [=query container=] has not had a [=relative scroll=] yet.
		<dt><dfn>top</dfn>
		<dd>
			The most recent [=relative scroll=] was upwards.
		<dt><dfn>right</dfn>
		<dd>
			The most recent [=relative scroll=] was to the right.
		<dt><dfn>bottom</dfn>
		<dd>
			The most recent [=relative scroll=] was downwards.
		<dt><dfn>left</dfn>
		<dd>
			The most recent [=relative scroll=] was to the left.
		<dt><dfn>block-start</dfn>
		<dd>
			The most recent [=relative scroll=] was towards the [=block-start=] direction.
		<dt><dfn>inline-start</dfn>
		<dd>
			The most recent [=relative scroll=] was towards the [=inline-start=] direction.
		<dt><dfn>block-end</dfn>
		<dd>
			The most recent [=relative scroll=] was towards the [=block-end=] direction.
		<dt><dfn>inline-end</dfn>
		<dd>
			The most recent [=relative scroll=] was towards the [=inline-end=] direction.
		<dt><dfn>x</dfn>
		<dd>
			The most recent [=relative scroll=] was in the horizontal direction.
		<dt><dfn>y</dfn>
		<dd>
			The most recent [=relative scroll=] was in the vertical direction.
		<dt><dfn>block</dfn>
		<dd>
			The most recent [=relative scroll=] was in the block direction.
		<dt><dfn>inline</dfn>
		<dd>
			The most recent [=relative scroll=] was in the inline direction.
	</dl>


<h2 id="container-lengths">
Container Relative Lengths: the ''cqw'', ''cqh'', ''cqi'', ''cqb'', ''cqmin'', ''cqmax'' units</h2>

	<dfn export lt="container query length | container query length unit">Container query length units</dfn>
	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:

	<table class="data">
	<caption>Informative Summary of Container Units</caption>
	<thead>
		<tr><th>unit<th>relative to
	</thead>
	<tbody>
		<tr><td>''cqw''
			<td>1% of a [=query container=]’s [=width=]
		<tr><td>''cqh''
			<td>1% of a [=query container=]’s [=height=]
		<tr><td>''cqi''
			<td>1% of a [=query container=]’s [=inline size=]
		<tr><td>''cqb''
			<td>1% of a [=query container=]’s [=block size=]
		<tr><td>''cqmin''
			<td>The smaller value of ''cqi'' or ''cqb''
		<tr><td>''cqmax''
			<td>The larger value of ''cqi'' or ''cqb''
	</tbody>
	</table>

	<wpt>
		container-queries/container-units-auto.html
		container-queries/container-units-selection-pseudo.html
	</wpt>

	For each element,
	[=container query length=] units are evaluated
	using the same rules 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 <a>computed values</a>.

	<div class=example>
		Authors can ensure that [=container query length=] units
		have an appropriate [=query container=]
		by applying them inside a [=container query=]
		that relies on the same ''container-type''.
		Custom fallback values can be defined outside the [=container query=]:

		<pre class=lang-css>
		/* The fallback value does not rely on containment */
		h2 { font-size: 1.2em; }

		@container (inline-size >= 0px) {
		  /* only applies when an inline-size container is available */
		  h2 { font-size: calc(1.2em + 1cqi); }
		}
		</pre>
	</div>


<h2 id="supports-condition-rule">
Defining Custom Support Queries: the ''@supports-condition'' rule</h2>

The <dfn at-rule id="at-ruledef-supports-condition">@supports-condition</dfn> [=at-rule=] is a [=conditional group rule=] that allows authors to define and name a [=supports query=] for later reuse,
creating a <dfn export>named supports condition</dfn>.
This enables complex or frequently-used feature queries to be referenced by name,
improving maintainability and readability.

	<pre class="prod def">
	@supports-condition <<supports-condition-name>> {
	  <<block-contents>>
	}
	</pre>

	<wpt>
		at-supports-selector-details-content-before.html
		at-supports-selector-details-content.html
	</wpt>

	Where <dfn><<supports-condition-name>></dfn> is an <<extension-name>> that defines the name of the supports query.

	Anything inside the block is evaluated to test whether the user agent supports the features used.
	The contents do not have any effect on the document's rendering.

	Once defined, the named supports condition can be used in subsequent ''@supports'' or ''@when'' conditions.

	If multiple ''@supports-condition'' rules are defined with the same name,
	the last one in document order wins, and all preceding ones are ignored.

	<div class="example">
		For example, we can define a supports query checking multiple properties at once:
		<pre class="lang-css">
		@supports-condition --thicker-underlines {
		  text-decoration-thickness: 0.2em;
		  text-underline-offset: 0.3em;
		}

		/* Equivalent to (text-decoration-thickness: 0.2em) and (text-underline-offset: 0.3em) */
		@supports (--thicker-underlines) {
		  a {
		    text-decoration: underline;
		    text-decoration-thickness: 0.2em;
		    text-underline-offset: 0.3em;
		  }
		}
		</pre>
	</div>

	''@supports-condition'' rules are allowed before ''@import'' and ''@namespace'' rules (after the ''@charset'' rule, if any).

	<div class="example">
		As support queries can contain arbitrary declarations,
		they can be used to detect support for complex features such as nesting:
		<pre class="lang-css">
		@supports-condition --nesting {
		  & { }
		}

		@import url("nested-styles.css") supports(--nesting);
		</pre>
	</div>

	<div class="example">
		Support queries can also be used to detect support for at-rules:
		<pre class="lang-css">
		@supports-condition --stuck-container-feature {
		  @container scroll-state(stuck: top) { }
		}

		@supports (--stuck-container-feature) {
		  div { border-color: navy; }
		}
		</pre>
	</div>

	Issue: The name of the at-rule is under discussion.
	Alternatives include ''@supports-query'', ''@supports-test'', and ''@custom-supports''.
	The name should be consistent with the one chosen for custom media queries.

<h2 id="apis">APIs</h2>


<h3 id="the-csscontainerrule-interface">
The <code>CSSContainerRule</code> interface</h3>

	The {{CSSContainerRule}} interface represents an ''@container'' rule.

	<pre class='idl'>
	dictionary CSSContainerCondition {
	  required CSSOMString name;
	  required CSSOMString query;
	};

	[Exposed=Window]
	interface CSSContainerRule : CSSConditionRule {
		readonly attribute CSSOMString containerName;
		readonly attribute CSSOMString containerQuery;
		readonly attribute FrozenArray&lt;CSSContainerCondition> conditions;
	};
	</pre>

	Issue: We should try to remove {{CSSContainerRule/containerName}} and
	{{CSSContainerRule/containerQuery}}, since they don't deal with multiple
	conditions correctly.

	<wpt>
		container-queries/container-rule-cssom.html
	</wpt>

	<dl class='idl-attributes'>
		<dt><code>conditionText</code> of type <code>CSSOMString</code> (CSSContainerRule-specific definition for attribute on CSSConditionRule)
		<dd>The <code>conditionText</code> attribute (defined on the <code>CSSConditionRule</code> parent rule),
			on getting, must return a value as follows:

			<div algorithm="CSSContainerRule.conditionText">
				1. Let |conditions| be the result of getting the {{CSSContainerRule/conditions}} attribute.
				1. Let |first| be <code>true</code>.
				1. Let |result| be the empty string.
				1. [=list/For each=] |condition| in |conditions|:
					1. If |first| is <code>false</code>, append <code>", "</code> to |result|.
					1. Set |first| to <code>false</code>.
					1. If |condition|'s {{CSSContainerCondition/name}} is not empty:
						1. Append |condition|'s {{CSSContainerCondition/name}} to |result|.
						1. If |condition|'s {{CSSContainerCondition/query}} is not empty,
							 append a single space to |result|.
					1. Append |condition|'s {{CSSContainerCondition/query}} to |result|.
				1. Return |result|
			</div>

		<dt><code>containerName</code> of type <code>CSSOMString</code>
		<dd>The <code>containerName</code> attribute, on getting, must return a value as follows:
			<div algorithm="CSSContainerRule.containerName">
				1. Let |conditions| be the result of getting the {{CSSContainerRule/conditions}} attribute.
				1. If the length of |conditions| is 1:
					1. Return the only |conditions| item's {{CSSContainerCondition/name}}.
				1. return <code>""</code>.
			</div>

		<dt><code>containerQuery</code> of type <code>CSSOMString</code>
		<dd>The <code>containerQuery</code> attribute,
			on getting, must return a value as follows:
			<div algorithm="CSSContainerRule.containerQuery">
				1. Let |conditions| be the result of getting the {{CSSContainerRule/conditions}} attribute.
				1. If the length of |conditions| is 1:
					1. Return the only |conditions| item's {{CSSContainerCondition/query}}.
				1. Return <code>""</code>.
			</div>

		<dt><code>conditions</code> of type <code>FrozenArray&lt;CSSContainerCondition?></code>
		<dd>The <code>conditions</code> attribute, on getting,
			must return a value as follows:
			<div algorithm="CSSContainerRule.conditions">
				1. Let |result| be an empty [=list=].
				1. [=list/For each=] <<container-condition>> |condition| specified in the rule:
					1. Let |dict| be a new {{CSSContainerCondition}} with
						 {{CSSContainerCondition/name}} set to the
						 <a lt="serialize an identifier">serialized</a> <<container-name>>
						 of |condition| if specified, or <code>""</code> otherwise,
						 and {{CSSContainerCondition/query}} set to the
						 <<container-query>> specified in |condition|
						 without any logical simplifications,
						 so that the returned query will evaluate to the same result
						 as the specified query
						 in any conformant implementation of this specification
						 (including implementations that implement future extensions
						 allowed by the <<general-enclosed>> extensibility mechanism in this specification).
						 In other words,
						 token stream simplifications are allowed
						 (such as reducing whitespace to a single space
						 or omitting it in cases where it is known to be optional),
						 but logical simplifications (such as removal of unneeded parentheses,
						 or simplification based on evaluating results) are not allowed.
					1. [=list/Append=] |dict| to |result|.
				1. Return |result|.
			</div>
	</dl>

	Issue(6205): Container Queries should have a <code>matchContainer</code> method.
	This will be modeled on {{matchMedia()}} and the {{MediaQueryList}} interface,
	but applied to Elements rather than the Window.
	When measuring layout sizes, it behaves Similar to <code>resizeObserver</code>,
	but it provides the additional Container Query syntax and features.

<h3 id="the-csssupportscondition-interface">
The <code>CSSSupportsConditionRule</code> interface</h3>

	The {{CSSSupportsConditionRule}} interface represents an ''@supports-condition'' rule.

	<pre class='idl'>
	[Exposed=Window]
	interface CSSSupportsConditionRule : CSSGroupingRule {
		readonly attribute CSSOMString name;
	};
	</pre>

	<dl class='idl-attributes'>
		<dt><code>name</code> of type <code>CSSOMString</code>
		<dd>This attribute is the name of the [=named supports condition=].
	</dl>

<h2 class=no-num id="security">Security Considerations</h2>

	No security issues have been raised against this document

<h2 class=no-num id="privacy">Privacy Considerations</h2>

	<!-- COPY FROM L3 when importing the rest of the spec -->

	The ''font-tech()'' and ''font-format()'' functions
	may provide information about the user's software
	such as its version
	and whether it is running with non-default settings that enable or disable certain features.

	This information can also be determined through other APIs.
	However, the features in this specification are one of the ways this information
	is exposed on the Web.

	This information can also, in aggregate, be used to improve the accuracy of
	<a href="https://www.w3.org/2001/tag/doc/unsanctioned-tracking/">fingerprinting</a> of the user.



<h2 id='changes' class='no-num'>
Changes</h2>

<h3 id="changes-20241105"  class="no-num">
Changes since the <a href="https://www.w3.org/TR/2024/WD-css-conditional-5-20241105/">Working Draft of 5 November 2024</a>
</h3>

<ul>
	<!-- to  21 October -->
	<li>
		Extended [=supports queries=] to express [=environment variable=] capabilities
		via ''@supports/env()''.
		(<a href="https://github.com/w3c/csswg-drafts/issues/3576">#3576</a>)
	</li>
	<li>Clarified that the last @supports-condition in document order wins
		(<a href="https://github.com/w3c/csswg-drafts/issues/12973">#12973</a>)
	</li>
	<li>
		Extended [=supports queries=] to express [=at-rule=] capabilities
		via ''at-rule()''.
		(<a href="https://github.com/w3c/csswg-drafts/issues/2463">#2463</a>,
		<a href="https://github.com/w3c/csswg-drafts/issues/6966">#6966</a>,
		<a href="https://github.com/w3c/csswg-drafts/issues/11116">#11116</a>,
		<a href="https://github.com/w3c/csswg-drafts/issues/11117">#11117</a>)</li>
	<li>Added ''@supports-condition'' at-rule and related {{CSSSupportsConditionRule}} interface.
		(<a href="https://github.com/w3c/csswg-drafts/issues/12622">#12622</a>)</li>
	<li>Clarified that container-names are not tree-scoped
		(<a href="https://github.com/w3c/csswg-drafts/issues/12090">#12090</a>)
	</li>
	<li>Defined direction feature for scroll-state() queries
		(<a href="https://github.com/w3c/csswg-drafts/issues/6400#issuecomment-3200664309">#6400</a>)
	</li>
	<li>Clarified that 0 and 0px are equivalent in conditions
		(<a href="https://github.com/w3c/csswg-drafts/issues/12236#issuecomment-3204826253">#12236</a>)
	</li>
	<!-- explainer commit, omitted -->
	<li>Defined a range syntax for style container queries
		(<a href="https://github.com/w3c/csswg-drafts/issues/8376#issuecomment-2773374483">#8376</a>)
	</li>
	<li>Explicitly allow tree-counting functions
		(<a href="https://github.com/w3c/csswg-drafts/issues/10982">#10982</a>)
	</li>
	<li>Dimensional query containers no longer apply layout containment
		(<a href="https://github.com/w3c/csswg-drafts/pull/10544">#10544</a>)</li>
	<li>Added "both" value for snapped query
		(<a href="https://github.com/w3c/csswg-drafts/issues/11181">#11181</a>)
	</li>
	<li>Added axis keywords for overflowing
		(<a href="https://github.com/w3c/csswg-drafts/issues/11183">#11183</a>)
	</li>
	<li>Renamed overflowing to scrollable
		(<a href="https://github.com/w3c/csswg-drafts/issues/11182">#11182</a>)</li>
	<li>Made <<container-query>> optional
		(<a href="https://github.com/w3c/csswg-drafts/issues/9192#issuecomment-1789850349">#9192</a>)
	</li>
	<li>Extended [=supports queries=] to express named features
		via ''named-feature()''.
		(<a href="https://github.com/w3c/csswg-drafts/issues/9875">#9875</a>)
	</li>
</ul>

<h3 id="changes-20240723"  class="no-num">
Changes since the <a href="https://www.w3.org/TR/2024/WD-css-conditional-5-20240723/">Working Draft of 23 July 2024</a>
</h3>

<ul>
	<!-- To 31 Oct 2024 -->
	<li>Added ''@container/stuck/none''-keywords to scroll-state() features (<a href="https://github.com/w3c/csswg-drafts/pull/10874">#10874</a>)</li>
	<li>Added container-type:scroll-state, and scroll-state() queries for stuck, snapped, and scrollable features
		(<a href="https://github.com/w3c/csswg-drafts/issues/6402#issuecomment-1812973013">#6402</a>,
		<a href="https://github.com/w3c/csswg-drafts/issues/10784#issuecomment-2379901508">#10784</a>,
		<a href="https://github.com/w3c/csswg-drafts/issues/10796#issuecomment-2379885032">#10796</a>)</li>
	<li>Corrected example (there is no container-type:style)</li>
	<li>Specified that container queries use the flat tree (<a href="https://github.com/w3c/csswg-drafts/issues/5984#issuecomment-2112977366">#5984</a>)</li>
</ul>

<h3 id="changes-20211221"  class="no-num">
Changes since the <a href="https://www.w3.org/TR/2021/WD-css-conditional-5-20211221/">First Public Working Draft of 21 December 2021</a>
</h3>

	<ul>
		<!-- to 18 Jun 2024 -->
		<li>Moved container queries to this specification, from CSS Contain 3  (<a href="https://github.com/w3c/csswg-drafts/issues/10433">#10433</a>)</li>
		<li>Imported the definitions of &lt;font-format> and &lt;font-tech> from CSS Fonts 4, rather than duplicating them in this specification (<a href="https://github.com/w3c/csswg-drafts/issues/8110">#8110</a>)</li>
		<li> Updated to use the new parsing algorithm names and block production names</li>
		<li>Corrected a typo in the grammar of &lt;font-format></li>
		<li>Corrected extra spaces in the font-tech and font-format productions (<a href="https://github.com/w3c/csswg-drafts/issues/7369">#7369</a>)</li>
	</ul>

<h3 id="changes-from-L4" class="no-num">
Additions since Level 4</h3>

	<ul>
		<li>Added ''@when'' and ''@else''.
		<li>Extended [=supports queries=] to express font capabilities
			via ''font-tech()'' and ''font-format()''.
		<li>Extended [=supports queries=] to express at-rule capabilities
			via ''at-rule()''.
		<li>Extended [=supports queries=] to express named features
			via ''named-feature()''.
		<li>Moved Container Queries from [[CSS-CONTAIN-3]] to this specification.
			(See also the [[CSS-CONTAIN-3#changes]] for more information
			on the evolution of this feature.)
		<li>Added ''@supports-condition'' at-rule and related {{CSSSupportsConditionRule}} interface.
	</ul>

<h2 class="no-num" id="acknowledgments">Acknowledgments</h2>

	The ''@when'' and ''@else'' rules are based on a proposal by Tab Atkins.

	Comments and previous work from
	Adam Argyle,
	Amelia Bellamy-Royds,
	Anders Hartvoll Ruud,
	Brian Kardell,
	Chris Coyier,
	Christopher Kirk-Nielsen,
	David Herron,
	Eric Portis,
	Ethan Marcotte,
	Florian Rivoal,
	Geoff Graham,
	Gregory Wild-Smith,
	Ian Kilpatrick,
	Jen Simmons,
	Kenneth Rohde Christiansen,
	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.

<wpt hidden title="tests for earlier levels">
	at-media-001.html
	at-media-002.html
	at-media-003.html
	at-media-content-001.html
	at-media-content-002.html
	at-media-content-003.html
	at-media-content-004.html
	at-media-dynamic-001.html
	at-media-whitespace-optional-001.html
	at-media-whitespace-optional-002.html
	at-supports-001.html
	at-supports-002.html
	at-supports-003.html
	at-supports-004.html
	at-supports-005.html
	at-supports-006.html
	at-supports-007.html
	at-supports-008.html
	at-supports-009.html
	at-supports-010.html
	at-supports-011.html
	at-supports-012.html
	at-supports-013.html
	at-supports-014.html
	at-supports-015.html
	at-supports-016.html
	at-supports-017.html
	at-supports-018.html
	at-supports-019.html
	at-supports-020.html
	at-supports-021.html
	at-supports-022.html
	at-supports-023.html
	at-supports-024.html
	at-supports-025.html
	at-supports-026.html
	at-supports-027.html
	at-supports-028.html
	at-supports-029.html
	at-supports-030.html
	at-supports-031.html
	at-supports-032.html
	at-supports-033.html
	at-supports-034.html
	at-supports-035.html
	at-supports-036.html
	at-supports-037.html
	at-supports-038.html
	at-supports-039.html
	at-supports-043.html
	at-supports-044.html
	at-supports-045.html
	at-supports-046.html
	at-supports-048.html
	at-supports-content-001.html
	at-supports-content-002.html
	at-supports-content-003.html
	at-supports-content-004.html
	at-supports-font-format-001.html
	at-supports-font-tech-001.html
	at-supports-namespace-001.html
	at-supports-namespace-002.html
	at-supports-selector-001.html
	at-supports-selector-002.html
	at-supports-selector-003.html
	at-supports-selector-004.html
	at-supports-selector-detecting-invalid-in-logical-combinations.html
	at-supports-selector-file-selector-button.html
	at-supports-selector-placeholder.html
	at-supports-whitespace.html
	css-supports-001.xht
	css-supports-002.xht
	css-supports-003.xht
	css-supports-004.xht
	css-supports-005.xht
	css-supports-006.xht
	css-supports-007.xht
	css-supports-008.xht
	css-supports-009.xht
	css-supports-010.xht
	css-supports-011.xht
	css-supports-012.xht
	css-supports-013.xht
	css-supports-014.xht
	css-supports-015.xht
	css-supports-016.xht
	css-supports-017.xht
	css-supports-018.xht
	css-supports-019.xht
	css-supports-020.xht
	css-supports-021.xht
	css-supports-022.xht
	css-supports-023.xht
	css-supports-024.xht
	css-supports-025.xht
	css-supports-026.xht
	css-supports-029.xht
	css-supports-030.xht
	css-supports-031.xht
	css-supports-032.xht
	css-supports-033.xht
	css-supports-034.xht
	css-supports-035.xht
	css-supports-036.xht
	css-supports-037.xht
	css-supports-038.xht
	css-supports-039.xht
	css-supports-040.xht
	css-supports-041.xht
	css-supports-042.xht
	css-supports-043.xht
	css-supports-044.xht
	css-supports-045.xht
	css-supports-046.xht
	idlharness.html
	js/001.html
	js/CSS-supports-CSSStyleDeclaration.html
	js/CSS-supports-L3.html
	js/CSS-supports-L4.html
	js/CSS-supports-selector-detecting-invalid-in-logical-combinations.html
	js/conditional-CSSGroupingRule.html
	js/supports-conditionText.html
</wpt>

<wpt hidden title="unclear where these go">
	js/CSS-supports-details-content-pseudo-parsing.html
</wpt>

<wpt hidden title="crashers">
	container-queries/crashtests/chrome-bug-385317081-crash.html
	container-queries/crashtests/chrome-bug-439886903-crash.html
	container-queries/position-sticky-crash.html
</wpt>
