CSS Nesting is Now Baseline Supported
cssNested CSS is now baseline; meaning that it’s finally supported across all the major browsers. We’ve been playing around with it and have found it really improves readability of your CSS. Let’s go through some examples.
First, a few important notes:
- Yes, we know about Tailwind, DaisyUI, SASS, etc… We’ve used them all over the past 15 years with much joy.
- Web standards continue to improve, and we’ve recently switched back to native CSS for development. No build, vanilla CSS is really good these days. I recommend you try it :)
- We use the BEM Naming Convention (Block Element Modifier) for our CSS class names. https://getbem.com/naming/
With that in mind let’s talk CSS nesting. Perhaps the best way to do so is through a couple examples. The first example shown below demonstrates how nesting can go beyond class names. It can include CSS operators like :not, :has, :is, and :where to create scoped styling that previously was only possible with javascript. The beauty of this is that the nesting makes it’s very clear for everyone on a project that all of the ‘a’ styling is happening in this one spot.
a {
color: var(--color-primary);
text-decoration: none;
/* Only apply the underline appearance to links without the class of 'button' or 'article__topic'. */
&:not(.button, .article__topic) {
text-decoration-line: underline;
text-decoration-color: var(--color-accent);
text-decoration-thickness: 0.1rem;
text-underline-offset: 0.4rem;
}
/* Only apply this style to active menu links and on link hover for links without the class of 'button' or 'article__topic'. */
&:not(.button, .article__topic):hover, &.active {
text-decoration-color: var(--color-primary);
text-decoration-thickness: var(--active-link-thickness);
}
/* If a link has a heart icon, then simulate the "a" link hover decoration using a border so that we account for the heart spacing. */
&.active:has(svg):has(.heart) {
text-decoration: none;
border-bottom: var(--active-link-thickness) solid var(--color-primary);
padding-bottom: 0.2rem;
}
}
In our second example shown below we see that CSS nesting is exceptionally clean when combined with the BEM CSS naming convention:
article {
margin-bottom: 1rem;
time {
display: block;
font-size: 0.75rem;
}
}
.article__img {
height: 40vh;
object-fit: contain;
border-radius: 1rem;
}
.article__img--circle {
border-radius: 50%;
}
- The ’time’ HTML element is a nested styled as part of the ‘article’. This way all article time HTML elements are styled the same and known to be properly scoped.
- .article__img Some but not all ‘img’ elements might need to be styled. So we have an ‘article__img’ class using the ‘block__element’ BEM syntax.
- .article__img--circle Some of the article images might need to be a circle so we create a modifier class using the ‘--’ BEM modifier syntax.
The result is a CSS file that’s readily obvious as to what’s happening. Such clear definition of scoping simply wasn’t possible in vanilla CSS prior to CSS nesting becoming baseline.
In Conclusion
Web standards continue to adopt many of the technologies that have been developed over the years. Nested CSS is no exception. Without the amazing open source work of CSS pre-processors, we wouldn’t be where we’re at today with vanilla CSS. Thank-you to all of those that put in the year of work to get move the industry to adopt amazing features like nested CSS!
Cheers 🥂