Revision:
The CSS nesting module defines a syntax for nesting selectors, providing the ability to nest one style rule inside another, with the selector of the child rule relative to the selector of the parent rule.
CSS nesting is different from CSS preprocessors - such as Sass - in that it is parsed by the browser rather than being pre-compiled by a CSS preprocessor.
CSS nesting helps with the readability, modularity, and maintainability of CSS stylesheets. It also potentially helps reduce the size of CSS files, thereby decreasing the amount of data downloaded by users.
The CSS & nesting selector explicitly states the relationship between parent and child rules when using CSS nesting. It makes the nested child rule selectors relative to the parent element.
Without the & nesting selector, the child rule selector selects child elements. The child rule selectors have the same specificity weight as if they were within :is().
If not used in nested style rule, the & nesting selector represents the scoping root.
CSS syntax:
parentRule {
/* parent rule style properties */
& childRule {
/* child rule style properties */
}
}
When the nested rule needs to be attached (with no whitespace) to the parent rule, such as when using a "pseudo-class" or creating "compound selectors", the & nesting selector must be immediately prepended to achieve the desired effect.
CSS syntax:
parentRule {
.parent-rule {
/* parent rule properties */
&:hover {
/* child rule properties */
}
}
/* the browser parses the above nested rules as shown below */
.parent-rule {
/* parent rule properties */
}
.parent-rule:hover {
/* child rule properties */
}
The & nesting selector can also be appended to reverse the context of the rules.
CSS syntax:
parentRule {
.card {
/* .card styles */
.featured & {
/* .featured .card styles */
}
}
/* the browser parses above nested rules as */
.card {
/* .card styles */
}
.featured .card {
/* .featured .card styles */
}
The & nesting selector can be placed multiple times:
CSS syntax:
parentRule {
.card {
/* .card styles */
.featured & & & {
/* .featured .card .card .card styles */
}
}
/* the browser parses above nested rules as */
.card {
/* .card styles */
}
.featured .card .card .card {
/* .featured .card .card .card styles */
}
CSS nesting can be used to create child selectors of a parent, which in turn can be used to target child elements of specific parents. This can be done with or without the & nesting selector.
Using the & nesting selector can be necessary or helpful:
When joining selectors together, such as using compound selectors or pseudo-classes.
For backwards compatibility.
As a visual indicator to aid with readability, when seeing the & nesting selector you know that CSS nesting is being used.
CSS syntax:
/* Without nesting selector */
parent {
/* parent styles */
child {
/* child of parent styles */
}
}
/* With nesting selector */
parent {
/* parent styles */
& child {
/* child of parent styles */
}
}
/* the browser will parse both of these as */
parent {
/* parent styles */
}
parent child {
/* child of parent styles */
}
In CSS, a combinator is a symbol that relates two CSS selectors to each other in order to style elements in a certain way. Combinators allow to apply style rules to elements based on their parent elements or sibling elements.
CSS combinators can also be used with or without the & nesting selector.
CSS3 includes four types of combinators: the descendant combinator, the child combinator, the adjacent sibling combinator, and the general sibling combinator.
The descendant combinator is written as two selectors "separated by a single space", and targets all instances of the second selector that descend from (i.e., are nested inside) the first selector. It selects every instance of an element nested inside another, including child elements, child elements of those child elements, and so on.
example: descendant combinator
#my-div p {
color: #e66e50;
font-size: 1.5rem;
}
Explanation: the descendant combinator "#my-div p" applies the associated rules to all <p> elements inside the <div> #my-div.
The child combinator is written as a "greater-than symbol (>)" placed between two CSS selectors. It targets all instances of an element that are direct descendants, or child elements, of another element. The style cascade stops after the first nesting level.
example: child combinator
main p { color: #e66e50; }
main > p { font-size: 1.5rem; }
Explanation: in the example, a descendant combinator is used to color all paragraph text inside <main> orange, and a child combinator to style only the child paragraphs of <main> with a larger font size.
The adjacent sibling combinator is written as a "plus sign (+) between two CSS selectors". It targets an element matching the second selector only if it immediately follows an element that matches the first selector. Additionally, both elements must be children of the same parent element (and are thus called “sibling elements”).
example: adjacent sibling combinator
h1 + p {
color: orange;
font-family: Avenir;
}
In the example, the first paragraph receives styling because it directly follows <h1>. However, a second paragraph does not.
The general sibling combinator is written as the "tilde symbol (~)" and targets all elements that follow a specific sibling element. Unlike the adjacent sibling selector, the targeted elements do not need to immediately follow the first element.
example: general sibling combinator
h1 ~ p {
color: orange;
font-family: Avenir;
}
Explanation: in the example, all <p> elements are styled because they are proceeded by <h1> in the document, despite not all being directly adjacent to each other.
A compound selector is a sequence of simple selectors that are not separated by a combinator. A compound selector represents a set of simultaneous conditions on a single element. A given element is said to match a compound selector when the element matches all the simple selectors in the compound selector.
CSS syntax:
#myId {
}
[pattern*="\d"] {
}
When using compound selectors in nested CSS, the & nesting selector has to be used, because the browser will automatically add whitespace between selectors that do not use the & nesting selector.
CSS syntax:
.a {
/* styles for element with class="a" */
.b {
/* styles for element with class="b" which is a descendant of class="a" */
}
&.b {
/* styles for element with class="a b" */
}
}
/* the browser parses this as */
.a {
/* styles for element with class="a" */
}
.a .b {
/* styles for element with class="b" which is a descendant of class="a" */
}
.a.b {
/* styles for element with class="a b" */
}
In CSS, nested classes are used to create a style for one or more child elements. You can nest CSS as deeply as you want and the CSS will only apply to those that it is assigned to.
A CSS class is a style that can be applied to HTML elements. These are broken into different sections and when you want to apply a particular style, you include it on your HTML element with the class attribute.
Syntax:.class-Name{css properties:value;}
example: various classes
.hugeBox { width: 100%; }
.hugeBox-top { margin-top: 10px; }
.hugeBox-bottom { margin-bottom: 10px; }
.hugeBox-right { margin-right: 10px; }
.hugeBox-left { margin-left: 10px; }
Nested CSS classes can only be applied to child elements. You might have an outer CSS rule that looks like .parent-class { color: blue; } and then you would nest the CSS for children of this parent inside it like so: /*nested CSS rules go here*/
example
h1.header {font-weight: 700}
EQUALS
h1 {
&.header {font-weight: 700
}
}
Whenever a selector — in this case, a class selector — is added on the same element, the space between & and the selector must be ignored.
example
.foo { color: #000000; }
.foo .bar { color: #fd2020; }
.foo .bar > .baz { color: #ffffff; }
EQUALS
.foo {color: #000000;
& .bar { color: #fd2020;
& > .baz {color: #ffffff;
}
}
}
Another interesting thing about nesting class selectors is that you don't need "&" because class names start with the "period symbol" when you declare them in CSS.
example
<div class="header">
<h1 class="heading">Hello!</h1>
<p class="text">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Corrupti nihil, officiis aut vel.
<a href="#" class="link">This is a Link</a>
</p>
</div>
.header {position: absolute; left: 25%; top: 40%; transform: translate(-13%, -42%); color: #22232e;
.heading {font-size: 3.5rem;}
.text {font-size: 2rem; margin: 25px 0px 25px;
.link { color: #00c2cb;
&:hover { color: #3498db;
}
}
}
}
With CSS nesting, one rule can be placed inside another. This is especially useful for managing styles that are context-dependent.
For example, if you have a ".container" class and want to style its ".item" elements, you can write the ."item" rules directly inside the ".container" rule.
CSS nesting is parsed directly by the browser. You don't need a preprocessor to compile nested rules; they work natively in the browser.
examples
code:
<form>
<label for="name">Name:
<input type="text" id="name" />
</label>
<label for="surname">Surname:</label>
<input type="text" id="surname" />
</form>
<style>
input {border: red 2px solid;}
label {font-family: system-ui; font-size: 1.25rem;
& input {border: purple 2px solid;}
}
</style>
Nesting allows to write in a more succinct, grouped format that reduces redundancy.
Before nesting, every selector needed to be explicitly declared, separately from one another. This leads to repetition, stylesheet bulk and a scattered authoring experience.
"before" example
.nesting {color: hotpink;}
.nesting > .is {color: rebeccapurple;}
.nesting > .is > .awesome {color: deeppink;}
"after" example
.nesting {color: hotpink;
> .is {color: rebeccapurple;
> .awesome {color: deeppink;}
}
}
Nesting reduces the need to repeat selectors while also co-locating style rules for related elements. It can also help styles match the HTML they target. Nesting can help with: organization, reducing file size, refactoring.
example: nesting
<div class="nesting">
<div class="is">
<div class="awesome"></div>
</div>
</div>
<style>
@layer demo {
.nesting {background: hotpink;
> .is {background: rebeccapurple;
> .awesome {background: deeppink;}
}
}
}
@layer demo.support {
.nesting {inline-size: 25vmin; aspect-ratio: 1;display: grid;place-items: center;}
.nesting > * {grid-area: 1/1; }
.is {aspect-ratio: 1;inline-size: 50%; display: grid;place-items: center;}
.awesome {aspect-ratio: 1; inline-size: 50%;}
}
</style>
example: nesting
<div>
<section class="box">
<h4 class="title">This is title</h4>
<div class="content">This is content.</div>
<button class="button">This is button</button>
</section>
<section class="box1">
<h4 class="title1">This is title</h4>
<div class="content1">This is content.</div>
<button class="button1">This is button</button>
</section>
</div>
<style>
.box {background-color: blue;
.title {background-color: yellow;}
}
.box1 {background-color: skyblue;
&:hover {background-color: green;}
}
.box1 {background-color: skyblue;
.content1 {background-color: pink;}
}
</style>
<div class="header">
<h1>Hello!</h1>
<p>
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Corrupti nihil, officiis aut vel.
<a href="#">This is a Link</a>
</p>
</div>
.header{ position: absolute; left: 25%; top: 40%;
transform: translate(-13%,-42%); color: #22232e;}
.header h1{ font-size: 3.5rem; }
.header p{font-size: 2rem; margin: 25px 0px 25px;}
.header p a{color: #00c2cb;}
.header p a:hover{color: #e498db;}
header {position: absolute; left: 25%; top: 40%; transform: translate(-13%,-42%);
color: #22232e;
h1 {font-size: 3.5rem;}
p { font-size: 2rem; margin: 25px 0px 25px;
a { color: #00c2cb;
&:hover {color: #e498db;
}
}
}
}
.header { position: absolute; left: 25%; top: 40%; transform: translate(-13%,-42%); color: #22232e;
& h1 {font-size: 3.5rem; }
& p {font-size: 2rem; margin: 25px 0px 25px;
& a { color: #00c2cb;
&:hover {color: #3498db;}
}
}
}
The "&"" is needed at the beginning of each selector for the nesting to be valid. The & is referencing the parent selector. That way, if we invert the above CSS style and replace every & with the parent selector, we will get back the initial CSS structure.
The nesting method also applies to nesting conditional rules such as "media queries" and "feature queries" (@supports).
example
.header {font-size: 40px
@media (max-width: 760px ) {
& {font-size: 24px;
}
}
}
EQUALS
.header {font-size: 40px;}
@media (max-width: 760px) {
.header {font-size: 24px;}
}
.header {font-size: 40px
@media (orientation: landscape) {
& {grid-auto-flow: column;
}
@media (max-width: 760px ) {
& {font-size: 24px;
}
}
}
}
EQUALS
.header {font-size: 40px
@media (orientation: landscape) {
.header {grid-auto-flow: column;}
@media (max-width: 760px ) {
,header {font-size: 24px;}
}
}
}
example
#header span,
#header a,
p span,
p a {
color: #0000ff;
}
:is(#header, p) span,
:is(#header, p) a {
color: #ff0000;
}
#header, p {
& span, & a { color: #ff0000; }
}
avoid over-nesting : a common rule of thumb is to keep nesting only three levels deep
styles after nested selectors are ignored : when nesting styles in CSS, any styles defined after nested selectors will be ignored. This is good to keep in mind, as it emphasizes the importance of organizing your rules carefully.