When writing HTML you've probably noticed that it has a clear nested and visual hierarchy. CSS, on the other hand, doesn't SO FAR
If you're not familiar with CSS preprocessors (scripting languages that extend the default capabilities of CSS) like Sass, Less, Stylus, and more. these preprocessors give you the ability to use variables, nest css selectors within selectors, and much more
For a long time, a big reason to use preprocessors like Sass was that it has the ability to use variables but now css has variables too just as that css will soon have nesting as well
๐ About Nesting
Nesting CSS selectors allowing you to write more modular and maintainable style sheets and allowing you to nest your CSS selectors in a way that follows the same visual hierarchy of your HTML.
Currently, this feature is in the draft and is not available in browsers yet but we will see how to use it today, But before that let's take a closer look at nesting and how it can improve your code
Usually, CSS Rules for even moderately complicated web pages include lots of duplication for the purpose of styling related content for example in the below code we have to continually refer to table.colortable
:
table.colortable td {
text-align: center;
}
table.colortable td.c {
text-transform: uppercase;
}
table.colortable td:first-child, table.colortable td:first-child+td {
border: 1px solid black;
}
table.colortable th {
text-align: center;
background: black;
color: white;
}
โ The &
Just like in sass the ampersand (&) is used to reference the parent selector, in the below example, we're referencing the table data using ampersand to apply the text alignment
table.colortable {
& td {
text-align: center;
&.c { text-transform: uppercase }
&:first-child, &:first-child + td { border: 1px solid black }
}
& th {
text-align: center;
background: black;
color: white;
}
}
Besides removing duplication, the grouping of related rules improves the readability and maintainability of the resulting CSS.
๐ Note:
Nesting allows the grouping of related style rules, But be aware that overly nested rules will result in over-qualified CSS that could prove hard to maintain and is generally considered bad practice
If you're using a list of selectors each selector must begin with a nested selector (&)
for example in the below example, if we wanted to target
divider
class we can't just add .divider
it must be &.divider
.list {
font-size: 2rem;
&.item, &.divider {
padding: 0.5rem;
}
}
๐ฅ at nest
There's another way to nest using the @nest
rule, this rule allows you to get around some of the limitations of the ampersand (&) nesting selector alone
For instance what if you want to select a parent that is outside of the
scoped, we can add @nest
.wrapper {
...
}
.post {
...
@nest .wrapper & {
background: blue;
}
}
The @nest rule
allows us to do this, it only requires that a nesting selector
be somewhere within the selection, it doesn't have to be at the beginning but
again every selector must have a nesting selector still
๐ง Nesting Conditional Rules
Also, we can even nest conditional rules such as media queries generally, we'll see media queries toward the bottom of a style sheet where you then have to reference back to an earlier selector to change their styles at various screen sizes
.foo {
display: grid;
}
@media (orientation: landscape) {
.foo {
grid-auto-flow: column;
}
}
Nesting allows us to put these right in the main selection but again these need to contain a nesting selector
.foo {
display: grid;
@media (orientation: landscape) {
& {
grid-auto-flow: column;
}
}
}
๐งช PostCSS Nesting
Currently, browsers don't support native nesting in css yet but we're going to use a post css package called PostCSS Nesting
Here we have the following slider example that we're going to convert to use nested css, where I am going to use Vite to quickly set it up since Vite supports post css out of the box this is going to be easy
All we have to do in order to set up it is to follow these instructions:
- Open your terminal and type
npm init @vitejs/app .
- Type your project name, e.g. css-nesting
- Select Vanilla as a framework
- Select JavaScript as a variant
- Install all packages
npm i
- Install PostCSS Nesting
npm i postcss-nesting -D
- Use the following HTML, CSS from the above CodePen in your
index.html
andstyle.css
<div class="slider">
<i class="slider__image fa fa-codepen"></i>
<div class="slider__content">
<h2 class="slider__caption">codepen</h2>
<p class="slider__txt">
CodePen is a social development environment for
front-end designers and developers. Build
and deploy a website, show off your work, build test cases to
</p>
</div>
</div>
.slider {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.slider__content {
padding: 2rem;
}
.slider__image {
color: #2196F3;
font-size: 8rem;
}
.slider__caption {
margin: 2rem 0 1rem;
text-transform: uppercase;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
font-weight: 500;
}
.slider__txt {
max-width: 400px;
color: #999;
}
๐งฐ PostCSS Configurations
All you have to do is to create a new file called postcss.config.js
and add the following configurations, after that we already ready for nesting ๐
module.exports = {
plugins: [require('postcss-nesting').default],
};
๐โโ๏ธ Let's Nest!
After applying the nesting rules we already mentioned before, we will end up with the following result and it works ๐๐:
.slider {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
& .slider__image {
color: #2196F3;
font-size: 8rem;
}
& .slider__content {
padding: 2rem;
& .slider__caption {
margin: 2rem 0 1rem;
text-transform: uppercase;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
font-weight: 500;
}
& .slider__txt {
max-width: 400px;
color: #999;
}
}
}
๐ References
- drafts.csswg.org/css-nesting-1
- tabatkins.github.io/specs/css-nesting/#intro
- github.com/csstools/postcss-nesting
Thank you for reading, If you have reached so far so let me know what do you think about css having native nesting