CSS Nesting Module Level 1
CSS Nesting Module Level 1
Editor’s Draft
5 February 2026
More details about this document
This version:
Latest published version:
Feedback:
CSSWG Issues Repository
Inline In Spec
Editor:
Tab Atkins-Bittner
Google
Former Editor:
Adam Argyle
Google
Suggest an Edit for this Spec:
GitHub Editor
Test Suite:
World Wide Web Consortium
W3C
liability
trademark
and
permissive document license
rules apply.
Abstract
This module introduces the ability to nest one style rule inside another, with the selector of the child rule relative to the selector of the parent rule. This increases the modularity and maintainability of CSS stylesheets.
CSS
is a language for describing the rendering of structured documents
(such as HTML and XML)
on screen, on paper, etc.
Status of this document
This is a public copy of the editors’ draft.
It is provided for discussion only and may change at any moment.
Its publication here does not imply endorsement of its contents by W3C.
Don’t cite this document other than as work in progress.
Please send feedback
by
filing issues in GitHub
(preferred),
including the spec code “css-nesting” in the title, like this:
“[css-nesting]
…summary of comment…
”.
All issues and comments are
archived
Alternately, feedback can be sent to the (
archived
) public mailing list
www-style@w3.org
This document is governed by the
18 August 2025 W3C Process Document
1.
Introduction
This section is not normative.
This module describes support for nesting a style rule within another style rule,
allowing the inner rule’s selector to reference the elements matched by the outer rule.
This feature allows related styles to be aggregated into a single structure within the CSS document,
improving readability and maintainability.
Tests
General tests for nesting
block-skipping.html
(live test)
(source)
delete-other-rule-crash.html
(live test)
(source)
double-parent-pseudo-in-placeholder-crash.html
(live test)
(source)
has-nesting.html
(live test)
(source)
invalidation-001.html
(live test)
(source)
invalidation-002.html
(live test)
(source)
invalidation-003.html
(live test)
(source)
invalidation-004.html
(live test)
(source)
nested-error-recovery.html
(live test)
(source)
nesting-basic.html
(live test)
(source)
parent-pseudo-in-placeholder-crash.html
(live test)
(source)
pseudo-part-crash.html
(live test)
(source)
pseudo-where-crash.html
(live test)
(source)
supports-is-consistent.html
(live test)
(source)
1.1.
Module Interactions
This module introduces new parser rules that extend the
[CSS21]
parser model.
It introduces selectors that extend the
[SELECTORS-4]
module.
It extends and modifies some IDL and algorithms defined in the
[CSSOM-1]
module.
1.2.
Values
This specification does not define any new properties or values.
2.
Explainer
This section is non-normative.
Imagine you have some CSS that you’d like to write in a more compact way.
.foo
color
green
.foo .bar
font-size
1.4
rem
With Nesting, you can write such code as:
.foo
color
green
.bar
font-size
1.4
rem
If you’ve been nesting styles in Sass
or other CSS preprocessors,
you will find this very familiar.
You can nest any rules inside of a parent style rule:
main
div
...
.bar
...
#baz
...
:has
...
::backdrop
...
lang|=
"zh"
...
...
By default, the child rule’s selector
is assumed to connect to the parent rule
by a
descendant combinator
but you can start the nested selector
with any combinator to change that:
main
+ article
...
> p
...
~ main
...
The new
selector lets you refer to
the elements matched by the parent selector explictly,
so the previous examples could have been written as:
main
& + article
...
& > p
...
& ~ main
...
But you can place the
in other locations
within the nested selector,
to indicate other types of relationships
between the parent and child rule.
For example,
this CSS:
ul
padding-left
em
.component ul
padding-left
Can be rewritten using Nesting as:
ul
padding-left
em
.component &
padding-left
Again, the
gives you a way to say
“this is where I want the nested selector to go”.
It’s also handy when you don’t want a space between your selectors.
For example:
color
blue
&:hover
color
lightblue
Such code yields the same result as
hover
Without the
you’d get
hover
—notice the space between
and
:hover
—which would fail to style your hover link.
You can nest more than one layer deep—nesting CSS inside already-nested CSS—in as many levels as you desire.
You can mix Nesting with
Container Queries, Supports Queries, Media Queries, and/or Cascade Layers
however you want.
(Nearly) anything can go inside of anything.
3.
Nesting Style Rules
Style rules can be nested inside of other styles rules.
These
nested style rules
act exactly like ordinary style rules—associating properties with elements via selectors—but they "inherit" their parent rule’s selector context,
allowing them to further build on the parent’s selector
without having to repeat it,
possibly multiple times.
nested style rule
is exactly like a normal style rule,
except that it can use
relative selectors
which are implicitly relative
to the elements matched by the parent rule.
Tests
implicit-nesting.html
(live test)
(source)
implicit-nesting-ident.html
(live test)
(source)
implicit-nesting-ident-recovery.html
(live test)
(source)
implicit-parent-insertion-crash.html
(live test)
(source)
That is,
a nested style rule like:
.foo
color
red
color
blue
is valid,
and equivalent to:
.foo
color
red
.foo a
color
blue
The nested rule can also use the
nesting selector
to directly refer to the parent rule’s matched elements,
or use
relative selector
syntax
to specify relationships other than "descendant".
.foo
color
red
&:hover
color
blue
/* equivalent to: */
.foo
color
red
.foo:hover
color
blue
.foo
color
red
+ .bar
color
blue
/* equivalent to: */
.foo
color
red
.foo + .bar
color
blue
Tests
nested-rule-cssom-invalidation.html
(live test)
(source)
3.1.
Syntax
The contents of
style rules
now accepts
nested style rules
and
at-rules
in addition to the existing
declarations
Nested style rules
differ from non-nested rules
in the following ways:
nested style rule
accepts a
as its prelude
(rather than just a
).
Any
relative selectors
are relative to the elements represented by the
nesting selector
If a selector in the
does not start with a
combinator
but does
contain the nesting selector
it is interpreted as a non-
relative selector
The precise details of how nested style rules are parsed
are defined in
[CSS-SYNTAX-3]
An invalid
nested style rule
is ignored,
along with its contents,
but does not invalidate its parent rule.
Nested rules with
relative selectors
include the specificity of their implied
nesting selector
For example,
.foo { > .bar {...}}
and
.foo { & > .bar {...}}
have the same specificity for their inner rule.
Some CSS-generating tools that preprocess nesting
will concatenate selectors as strings,
allowing authors to build up a
single
simple selector
across nesting levels.
This is sometimes used with hierarchical name patterns
like
BEM
to reduce repetition across a file,
when the selectors themselves have significant repetition internally.
For example, if one component uses the class
.foo
and a nested component uses
.fooBar
you could write this in
Sass
as:
.foo
color
blue
&Bar
color
red
/* In Sass, this is equivalent to
.foo { color: blue; }
.fooBar { color: red; }
*/
This is not allowed in CSS,
as nesting is not a syntax transformation,
but rather matches on the actual elements the parent selector matches.
It is also true that the selector
&Bar
is invalid in CSS in the first place,
as the
Bar
part is a type selector,
which must come first in the compound selector.
(That is, it must be written as
Bar&
.)
So, luckily, there is no overlap between CSS Nesting
and the preprocessor syntax.
A selector is said to
contain the nesting selector
if, when it was
parsed
as any type of selector,
with the value "&" (U+0026 AMPERSAND) was encountered.
Note:
This is phrased in this explicit manner
so as to catch cases like
:is(:unknown(&), .bar)
where an unknown selector
(which, being unknown, we have no way of knowing
whether the argument is
meant
to be parsed as a selector or not)
is the only part of the selector that contains an
As that
might
be a perfectly valid selector
that’s only supported by newer browsers,
and we don’t want parsing to be dependent on unrelated versioning issues,
we treat it as still
containing the nesting selector
If a
has an item that
contains the nesting selector
but is invalid,
that item is preserved exactly as-is
rather than being discarded.
(This does not change the matching behavior of the selector—an invalid selector still fails to match anything—just the serialization of the selector.)
Tests
nest-containing-forgiving.html
(live test)
(source)
parsing.html
(live test)
(source)
The preceding paragraph needs to move to Selectors
when we move
itself to Selectors;
I’m monkey-patching for convenience here.
3.2.
Examples
/* & can be used on its own */
.foo
color
blue
& > .bar
color
red
> .baz
color
green
/* equivalent to
.foo { color: blue; }
.foo > .bar { color: red; }
.foo > .baz { color: green; }
*/
/* or in a compound selector,
refining the parent's selector */
.foo
color
blue
&.bar
color
red
/* equivalent to
.foo { color: blue; }
.foo.bar { color: red; }
*/
/* multiple selectors in the list are all
relative to the parent */
.foo
.bar
color
blue
+ .baz
&.qux
color
red
/* equivalent to
.foo, .bar { color: blue; }
:is(.foo, .bar) + .baz,
:is(.foo, .bar).qux { color: red; }
*/
/* & can be used multiple times in a single selector */
.foo
color
blue
& .bar & .baz & .qux
color
red
/* equivalent to
.foo { color: blue; }
.foo .bar .foo .baz .foo .qux { color: red; }
*/
/* & doesn't have to be at the beginning of the selector */
.foo
color
red
.parent &
color
blue
/* equivalent to
.foo { color: red; }
.parent .foo { color: blue; }
*/
.foo
color
red
:not
color
blue
/* equivalent to
.foo { color: red; }
:not(.foo) { color: blue; }
*/
/* But if you use a
relative selector
an initial & is implied automatically */
.foo
color
red
+ .bar + &
color
blue
/* equivalent to
.foo { color: red; }
.foo + .bar + .foo { color: blue; }
*/
/* Somewhat silly, but & can be used all on its own, as well. */
.foo
color
blue
padding
ch
/* equivalent to
.foo { color: blue; }
.foo { padding: 2ch; }
// or
.foo {
color: blue;
padding: 2ch;
*/
/* Again, silly, but can even be doubled up. */
.foo
color
blue
&&
padding
ch
/* equivalent to
.foo { color: blue; }
.foo.foo { padding: 2ch; }
*/
/* The parent selector can be arbitrarily complicated */
.error
#404
&:hover > .baz
color
red
/* equivalent to
:is(.error, #404):hover > .baz { color: red; }
*/
.ancestor .el
.other-ancestor &
color
red
/* equivalent to
.other-ancestor :is(.ancestor .el) { color: red; }
/* As can the nested selector */
.foo
& :is
.bar
&.baz
color
red
/* equivalent to
.foo :is(.bar, .foo.baz) { color: red; }
*/
/* Multiple levels of nesting "stack up" the selectors */
figure
margin
> figcaption
background
hsl
50
);
> p
font-size
.9
rem
/* equivalent to
figure { margin: 0; }
figure > figcaption { background: hsl(0 0% 0% / 50%); }
figure > figcaption > p { font-size: .9rem; }
*/
/* Example usage with Cascade Layers */
@layer
base
html
block-size
100
body
min-block-size
100
/* equivalent to
@layer base {
html { block-size: 100%; }
html body { min-block-size: 100%; }
*/
/* Example nesting Cascade Layers */
@layer
base
html
block-size
100
@layer
support
body
min-block-size
100
/* equivalent to
@layer base {
html { block-size: 100%; }
@layer base.support {
html body { min-block-size: 100%; }
*/
/* Example usage with Scoping */
@scope
.card
to
> header
:scope
inline-size
40
ch
aspect-ratio
> header
border-block-end
px
solid white
/* equivalent to
@scope (.card) to (> header) {
:scope { inline-size: 40ch; aspect-ratio: 3/4; }
:scope > header { border-block-end: 1px solid white; }
*/
/* Example nesting Scoping */
.card
inline-size
40
ch
aspect-ratio
@scope
to
> header > *
:scope > header
border-block-end
px
solid white
/* equivalent to
.card { inline-size: 40ch; aspect-ratio: 3/4; }
@scope (.card) to (> header > *) {
:scope > header { border-block-end: 1px solid white; }
*/
3.3.
Nesting Other At-Rules
In addition to
nested style rules
this specification allows
nested group rules
inside of
style rules
any at-rule whose body contains
style rules
can be nested inside of a
style rule
as well,
unless otherwise specified.
When nested in this way,
the contents of a
nested group rule
’s block
are parsed as
rather than
Style rules
are
nested style rules
with their
nesting selector
taking its definition
from the nearest ancestor
style rule
Properties can be directly used,
acting as if they were nested in a
nested declarations rule
Specifically, these rules are capable of being
nested group rules
all the
conditional group rules
@container
@media
@supports
@layer
@scope
Tests
conditional-properties.html
(live test)
(source)
conditional-rules.html
(live test)
(source)
invalid-inner-rules.html
(live test)
(source)
supports-rule.html
(live test)
(source)
The meanings and behavior of such
nested group rules
is otherwise unchanged,
unless otherwise specified.
For example, the following conditional nestings are valid:
/* Properties can be directly used */
.foo
display
grid
@media
orientation: landscape
grid-auto-flow
column
/* equivalent to: */
.foo
display
grid
@media
orientation: landscape
.foo
grid-auto-flow
column
/* and also equivalent to the unnested: */
.foo
display
grid
@media
orientation: landscape
.foo
grid-auto-flow
column
/* Conditionals can be further nested */
.foo
display
grid
@media
orientation: landscape
grid-auto-flow
column
@media
min-width >
1024
px
max-inline-size
1024
px
/* equivalent to */
.foo
display
grid
@media
orientation: landscape
.foo
grid-auto-flow
column
@media
orientation: landscape
and
min-width >
1024
px
.foo
max-inline-size
1024
px
/* Example nesting Cascade Layers */
html
@layer
base
block-size
100
@layer
support
& body
min-block-size
100
/* equivalent to */
@layer
base
html
block-size
100
@layer
base.support
html body
min-block-size
100
/* Example nesting Scoping */
.card
inline-size
40
ch
aspect-ratio
@scope
:scope
border
px
solid white
/* equivalent to */
.card
inline-size
40
ch
aspect-ratio
@scope
.card
:scope
border-block-end
px
solid white
Runs of consecutive directly-nested properties
are automatically wrapped in
nested declarations rules
(This is observable in the CSSOM.)
Tests
nesting-layer.html
(live test)
(source)
3.3.1.
Nested
@scope
Rules
When the
@scope
rule is a
nested group rule
an
in the
selector
refers to the elements matched
by the nearest ancestor style rule.
That is, the following code:
.parent
color
blue
@scope
& > .scope
to
& .limit
& .content
color
red
is equivalent to:
.parent
color
blue
@scope
.parent > .scope
to
:where
:scope
.limit
:where
:scope
.content
color
red
The
selector behaves like
:where
:scope
in
@scope
rules.
3.4.
Mixing Nesting Rules and Declarations
When a style rule contains both declarations
and
nested style rules
or
nested group rules
all three can be arbitrarily mixed.
Declarations coming after or between rules
are implicitly wrapped in
nested declarations rules
to preserve their order relative to the other rules.
For example,
in the following code:
article
color
green
color
blue
color: red
/* equivalent to */
article
color
green
:is
article
color
blue
article
color
red
/* NOT equivalent to */
article
color
green
article
color
red
:is
article
color
blue
For the purpose of determining the
Order Of Appearance
nested style rules
and
nested group rules
are considered to come
after
their parent rule.
For example:
article
color
blue
color
red
Both declarations have the same specificity (0,0,1),
but the nested rule is considered to come
after
its parent rule,
so the
color: red
declarations wins the cascade.
On the other hand, in this example:
article
color
blue
:where
color
red
The
:where()
pseudoclass reduces the specificity of the
nesting selector
to 0,
so the
color: red
declaration now has a specificity of (0,0,0),
and loses to the
color: blue
declaration
before "Order Of Appearance" comes into consideration.
Note:
While one
can
freely intermix declarations and nested rules,
it’s harder to read and somewhat confusing to do so,
since the later properties are automatically wrapped in a
nested declarations rule
that doesn’t appear in the source text.
For readability’s sake,
it’s recommended that authors put all their properties first in a style rule,
before any nested rules.
(This also happens to act slightly better in older user agents:
due to specifics of how parsing and error-recovery work,
properties appearing after nested rules can get skipped.)
4.
Nesting Selector: the
selector
When using a
nested style rule
one must be able to refer to the elements matched by the parent rule;
that is, after all,
the entire point of nesting
To accomplish that,
this specification defines a new selector,
the
nesting selector
written as
(U+0026 AMPERSAND).
When used in the selector of a
nested style rule
the
nesting selector
represents the elements matched by the parent rule.
When used in any other context,
it represents the same elements as
:scope
in that context
(unless otherwise defined).
Tests
top-level-is-scope.html
(live test)
(source)
The
nesting selector
can be desugared
by replacing it with the parent style rule’s selector,
wrapped in an
:is()
selector.
For example,
& c
color
blue
is equivalent to
:is
color
blue
The
nesting selector
cannot represent pseudo-elements
(identical to the behavior of the
:is()
pseudo-class).
For example, in the following style rule:
.foo
.foo::before
.foo::after
color
red
&:hover
color
blue
the
only represents the elements matched by
.foo
in other words, it’s equivalent to:
.foo
.foo::before
.foo::after
color
red
.foo:hover
color
blue
We’d like to relax this restriction,
but need to do so simultaneously for both
:is()
and
since they’re intentionally built on the same underlying mechanisms.
Issue 7433
The
specificity
of the
nesting selector
is equal to the largest specificity among the complex selectors
in the parent style rule’s selector list
(identical to the behavior of
:is()
),
or zero if no such selector list exists.
Tests
top-level-parent-pseudo-specificity.html
(live test)
(source)
For example, given the following style rules:
#a
& c
color
blue
.foo c
color
red
Then in a DOM structure like
class
foo
Blue text
The text will be blue, rather than red.
The specificity of the
is the larger of the specificities of
#a
([1,0,0])
and
([0,0,1]),
so it’s [1,0,0],
and the entire
& c
selector thus has specificity [1,0,1],
which is larger than the specificity of
.foo c
([0,1,1]).
Notably, this is
different
than the result you’d get
if the nesting were manually expanded out
into non-nested rules,
since the
color: blue
declaration would then be matching
due to the
b c
selector ([0,0,2])
rather than
#a c
([1,0,1]).
Why is the specificity different than non-nested rules?
The
nesting selector
intentionally uses the same specificity rules
as the
:is()
pseudoclass,
which just uses the largest specificity among its arguments,
rather than tracking
which
selector actually matched.
This is required for performance reasons;
if a selector has multiple possible specificities,
depending on how precisely it was matched,
it makes selector matching much more complicated and slower.
That skirts the question, tho:
why
do
we define
in terms of
:is()
Some non-browser implementations of Nesting-like functionality
do
not
desugar to
:is()
largely because they predate the introduction of
:is()
as well.
Instead, they desugar directly;
however, this comes with its own
significant
problems,
as some (reasonably common) cases can accidentally produce
massive
selectors,
due to the exponential explosion of possibilities.
.a1
.a2
.a3
.b1
.b2
.b3
.c1
.c2
.c3
...
/* naively desugars to */
.a1 .b1 .c1
.a1 .b1 .c2
.a1 .b1 .c3
.a1 .b2 .c1
.a1 .b2 .c2
.a1 .b2 .c3
.a1 .b3 .c1
.a1 .b3 .c2
.a1 .b3 .c3
.a2 .b1 .c1
.a2 .b1 .c2
.a2 .b1 .c3
.a2 .b2 .c1
.a2 .b2 .c2
.a2 .b2 .c3
.a2 .b3 .c1
.a2 .b3 .c2
.a2 .b3 .c3
.a3 .b1 .c1
.a3 .b1 .c2
.a3 .b1 .c3
.a3 .b2 .c1
.a3 .b2 .c2
.a3 .b2 .c3
.a3 .b3 .c1
.a3 .b3 .c2
.a3 .b3 .c3
...
Here, three levels of nesting,
each with three selectors in their lists,
produced 27 desugared selectors.
Adding more selectors to the lists,
adding more levels of nesting,
or making the nested rules more complex
can make a relatively small rule
expand into multiple megabytes of selectors
(or much, much more!).
Some CSS tools avoid the worst of this
by heuristically discarding some variations,
so they don’t have to output as much
but are still
probably
correct,
but that’s not an option available to UAs.
Desugaring with
:is()
instead eliminates this problem entirely,
at the cost of making specificity slightly less useful,
which was judged a reasonable trade-off.
The
nesting selector
is capable of matching
featureless
elements,
if they were matched by the parent rule.
While the position of a
nesting selector
in a
compound selector
does not make a difference in its behavior
(that is,
&.foo
and
.foo&
match the same elements),
the existing rule that a
type selector
, if present, must be first in the
compound selector
continues to apply
(that is,
&div
is illegal, and must be written
div&
instead).
Tests
contextually-invalid-selectors-001.html
(live test)
(source)
contextually-invalid-selectors-002.html
(live test)
(source)
contextually-invalid-selectors-003.html
(live test)
(source)
host-nesting-001.html
(live test)
(source)
host-nesting-002.html
(live test)
(source)
host-nesting-003.html
(live test)
(source)
host-nesting-004.html
(live test)
(source)
host-nesting-005.html
(live test)
(source)
nesting-type-selector.html
(live test)
(source)
5.
The Nested Declarations Rule
For somewhat-technical reasons,
it’s important to be able to distinguish properties
that appear at the start of a style rule’s contents
from those that appear interspersed with other rules.
For example, in the following two rules:
.foo
color
red
@media
...
...
background: blue
We need to treat the
color: red
and
background: blue
slightly differently.
In particular, in the CSSOM,
the
color: red
is exposed in the style rule’s
style
attribute,
while the
background: blue
needs to instead show up in its
cssRules
list.
To accomplish this, CSS parsing
automatically
wraps such properties
in a special child rule
to contain them.
However, if we were to wrap them in a
style rule
with an
selector,
it would have somewhat unfortunate behavior:
For example, in
.foo
.foo::before
color
red
background
blue
the nested rule
does not
apply the
background
property
to the
.foo::before
elements,
because the
can’t represent pseudo-elements.
Similarly, child declarations in nested non-style rules
need to be exposed as
rules
in some way,
because these sorts of rules (like
@media
have never had
style
properties.
These run into the same problems as above.
To address all of these issue,
we instead wrap runs of consecutive directly-nested properties
in a
nested declarations rule
Unless otherwise specified,
nested declarations rule
is a
nested style rule
and acts identically to any other style rule.
It matches the exact same elements and pseudo-elements
as its parent style rule,
with the same specificity behavior.
(This is
similar to
being a style rule with an
selector,
but slightly more powerful,
as explained above.)
Why does the
nested declarations rule
exist?
Originally, this specification grouped all declarations in style rules together,
"moving" them from their original location
to act as if they were placed at the front of the rule.
It also automatically wrapped raw declarations inside of
nested group rules
in plain style rules,
using the
selector.
There are two major reasons we switched to instead use the
nested declarations rule
First, using an
& {...}
rule to implicitly wrap declarations in a
nested group rule
also changed the behavior.
As shown in the example following this note,
it breaks cases where the parent style rule contains pseudo-elements,
and even when that’s not the case,
it potentially changes the specificity behavior of the nested declarations.
Switching to the
nested declarations rule
avoids these problems,
making the behavior of nested
@media
/etc
identical to the behavior of *non*-nested
@media
/etc.
Second, there are some details of future CSS features
(notably, "mixins")
that simply won’t work correctly
if interleaved declarations
are automatically moved to the front of the style rule.
We need to keep their relative order with other rules,
and in order to actually make that representable in the CSSOM,
that means they have to be wrapped in some kind of rule.
The same issues as the previous paragraph apply if we just use a normal
& {...}
rule,
so the
nested declarations rule
lets us do so without side effects.
For example, in the following stylesheet snippet:
.foo
.foo::before
.foo::after
color
black
@media
prefers-color-scheme: dark
color
white
In a darkmode page,
the
.foo
element would have its text color changed to white,
but its
::before
and
::after
pseudos would remain black,
because the
selector can’t represent pseudo-elements.
However, it was instead written as:
.foo
.foo::before
.foo::after
color
black
@media
prefers-color-scheme: dark
color
white
Then the
color: white
is implicitly wrapped in a
nested declarations rule
which is guaranteed to match
exactly
the same as its parent style rule,
so the element
and
its pseudo-elements
would all have white text in a darkmode page.
Declarations interleaved with rules get implicitly wrapped in a
nested declarations rule
which makes them part of a separate style rule.
For example, given this CSS:
.foo
color
black
@media
...
...
background: silver
If the
.foo
rule’s CSSOM object is examined,
its
style
attribute
will contain only one declaration:
the
color: black
one.
The
background: silver
declaration
will instead be found in the implicitly-created
nested declarations child rule
at
fooRule
cssRules
].
style
Tests
mixed-declarations-rules.html
(live test)
(source)
nested-declarations-cssom-whitespace.html
(live test)
(source)
nested-declarations-cssom.html
(live test)
(source)
nested-declarations-matching.html
(live test)
(source)
6.
CSSOM
Note:
[CSSOM-1]
now defines
that
CSSStyleRule
can have child rules.
When serializing a
relative selector
in a
nested style rule
the selector must be absolutized,
with the implied
nesting selector
inserted.
For example, the selector
> .foo
will serialize as
& > .foo
Tests
cssom.html
(live test)
(source)
set-selector-text.html
(live test)
(source)
6.1.
The
CSSNestedDeclarations
Interface
The
CSSNestedDeclarations
interface represents a
nested declarations rule
Exposed
Window
interface
CSSNestedDeclarations
CSSRule
SameObject
PutForwards
cssText
readonly
attribute
CSSStyleProperties
style
};
The
style
attribute
must return a
CSSStyleProperties
object for the rule,
with the following properties:
computed flag
Unset
readonly flag
Unset
declarations
The declared declarations in the rule, in
specified order
parent CSS rule
this
owner node
Null
The
CSSNestedDeclarations
rule
serializes
as if its
declaration block
had been
serialized
directly.
Tests
serialize-group-rules-with-decls.html
(live test)
(source)
Note:
This means that multiple adjacent
nested declarations rules
(which is possible to create with e.g.
insertRule
will collapse into a single rule when serialized and parsed again.
Privacy Considerations
No new privacy considerations have been reported on this specification.
Security Considerations
No new security considerations have been reported on this specification.
7.
Changes
Significant changes since the
Feb 14, 2023 Working Draft
The
selector of a
@scope
rule
no longer acts as the parent rule for nesting.
Issue 9740
Clarified that the
nesting selector
is allowed to match featureless elements.
Switched
&div
back to being invalid;
now that Syntax does "infinite lookahead",
we no longer need to allow it.
Plus, doing so avoids a clash with preprocessors.
Issue 8662
CSSOM now defines that CSSStyleRule is a CSSGroupingRule subclass,
so the manual definition of the
cssRules
attribute and related machinery
was removed.
Issue 8940
Clarified the effect of the
implied
nesting selector on specificity.
Issue 9069
Declarations intermixed with rules (or all declarations in nested group rules)
are now automatically wrapped in
@nest
rules.
(Also the
@nest
rule was added.)
Issue 8738
Replaced
@nest
with
nested declarations rules
Issue 10234
Added Web Platform Tests coverage.
Conformance
Document conventions
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:
This is an example of an informative example.
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
"advisement"
, like
this:
UAs MUST provide an accessible alternative.
Tests
Tests relating to the content of this specification
may be documented in “Tests” blocks like this one.
Any such block is non-normative.
Conformance classes
Conformance to this specification
is defined for three conformance classes:
style sheet
CSS
style sheet
renderer
UA
that interprets the semantics of a style sheet and renders
documents that use them.
authoring tool
UA
that writes a style sheet.
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.
Partial implementations
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.
Implementations of Unstable and Proprietary Features
To avoid clashes with future stable CSS features,
the CSSWG recommends
following best practices
for the implementation of
unstable
features and
proprietary extensions
to CSS.
Non-experimental implementations
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.
Further information on submitting testcases and implementation reports
can be found from on the CSS Working Group’s website at
Questions should be directed to the
public-css-testsuite@w3.org
mailing list.
Index
Terms defined by this specification
, in § 4
contain the nesting selector
, in § 3.1
CSSNestedDeclarations
, in § 6.1
nested declarations rule
, in § 5
nested group rules
, in § 3.3
nested style rule
, in § 3
nesting selector
, in § 4
nesting style rule
, in § 3
style
, in § 6.1
Terms defined by reference
[CSS-BACKGROUNDS-3]
defines the following terms:
background
[CSS-CASCADE-5]
defines the following terms:
@layer
[CSS-CASCADE-6]
defines the following terms:
@scope
[CSS-COLOR-4]
defines the following terms:
color
[CSS-CONDITIONAL-3]
defines the following terms:
@media
@supports
conditional group rule
[CSS-CONDITIONAL-5]
defines the following terms:
@container
[CSS-PSEUDO-4]
defines the following terms:
::after
::before
[CSS-SYNTAX-3]
defines the following terms:
at-rule
parse
rule
style rule
[CSS-UI-4]
defines the following terms:
bar
[CSSOM-1]
defines the following terms:
CSSRule
CSSStyleProperties
CSSStyleRule
computed flag
CSS declaration block
cssRules
declarations
insertRule(rule)
owner node
parent CSS rule
readonly flag
serialize a CSS declaration block
serialize a CSS rule
specified order
style
[SELECTORS-4]
defines the following terms:
:is()
:scope
:where()
combinator
compound selector
descendant combinator
featureless
relative selector
simple selector
specificity
type selector
[WEBIDL]
defines the following terms:
Exposed
PutForwards
SameObject
this
References
Normative References
[CSS-CASCADE-4]
Elika Etemad; Tab Atkins Jr..
CSS Cascading and Inheritance Level 4
. URL:
[CSS-CASCADE-6]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr..
CSS Cascading and Inheritance Level 6
. URL:
[CSS-COLOR-4]
Tab Atkins Jr.; Chris Lilley; Lea Verou.
CSS Color Module Level 4
. URL:
[CSS-CONDITIONAL-3]
Chris Lilley; David Baron; Elika Etemad.
CSS Conditional Rules Module Level 3
. URL:
[CSS-SYNTAX-3]
Tab Atkins Jr.; Simon Sapin.
CSS Syntax Module Level 3
. URL:
[CSS21]
Bert Bos; et al.
Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification
. URL:
[CSSOM-1]
Daniel Glazman; Emilio Cobos Álvarez.
CSS Object Model (CSSOM)
. URL:
[RFC2119]
S. Bradner.
Key words for use in RFCs to Indicate Requirement Levels
. March 1997. Best Current Practice. URL:
[SELECTORS-4]
Elika Etemad; Tab Atkins Jr..
Selectors Level 4
. URL:
[WEBIDL]
Edgar Chen; Timothy Gu.
Web IDL Standard
. Living Standard. URL:
Non-Normative References
[CSS-BACKGROUNDS-3]
Elika Etemad; Brad Kemper.
CSS Backgrounds and Borders Module Level 3
. URL:
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr..
CSS Cascading and Inheritance Level 5
. URL:
[CSS-CONDITIONAL-5]
Chris Lilley; et al.
CSS Conditional Rules Module Level 5
. URL:
[CSS-PSEUDO-4]
Elika Etemad; Alan Stearns.
CSS Pseudo-Elements Module Level 4
. URL:
[CSS-UI-4]
Tab Atkins Jr.; Florian Rivoal.
CSS Basic User Interface Module Level 4
. URL:
IDL Index
Exposed
Window
interface
CSSNestedDeclarations
CSSRule
SameObject
PutForwards
cssText
readonly
attribute
CSSStyleProperties
style
};
Issues Index
The preceding paragraph needs to move to Selectors
when we move
itself to Selectors;
I’m monkey-patching for convenience here.
We’d like to relax this restriction,
but need to do so simultaneously for both
:is()
and
since they’re intentionally built on the same underlying mechanisms.
Issue 7433
US