2

Day 99: native nesting

 1 year ago
source link: https://www.matuzo.at/blog/2023/100daysof-day99/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Day 99: native nesting

posted on February 9., 2023

It’s time to get me up to speed with modern CSS. There’s so much new in CSS that I know too little about. To change that I’ve started #100DaysOfMoreOrLessModernCSS. Why more or less modern CSS? Because some topics will be about cutting-edge features, while other stuff has been around for quite a while already, but I just have little to no experience with it.


Nesting in CSS is coming soon! For me personally not the killer feature, at least compared to cascade layers or container queries, but still exciting. Let’s see how it works.

The most important thing to know about native nesting in CSS is that the nested selector always must start with a symbol (. # : [ * + > ~) because of limitations in browser parsing engines.

The following code doesn't work:

/* Doesn't work */

ul {
li {
border-color: green;
}
}

To work around that limitation the nested selector can start with an &.

ul {
& li {
border-color: green;
}
}

/*
Same as:
ul li { }
*/

Besides this limitation, everything works as expected for me. Here are some of the things I've tested:

a {
&:hover {
background-color: aqua;
}

&:focus-visible {
background-color: aqua;
}
}

/*
Same as:
a:hover { }
a:focus-visible { }
*/
a {
&:is(:hover, :focus-visible) {
background-color: aqua;
}
}

/*
Same as:
a:is(:hover, :focus-visible) { }
*/
h2 {
font-family: sans-serif;

&::first-letter {
color: red;
}
}

/*
Same as:
h2 { }
h2::first-letter { }
*/
h2 {
& + p {
background-color: red;
}
}

/*
Same as:
h2 + p { }
*/
h2 {
.parent & {
background-color: aqua;
}
}

/*
Same as:
.parent h2 { }
*/
h2 {
@media (min-width: 400px) {
background: red;
}
}

/*
Same as:
@media (min-width: 400px) {
h2 { }
}
*/
h2 {
@media (min-width: 400px) {
background: red;

&::before {
content: "!";
color: #fff;
}

& ~ p {
& span {
background-color: #000;
}

:is(span) {
color: #fff;
}
}
}
}

/*
Same as:
@media (min-width: 400px) {
h2 { }
h2::before { }
h2 ~ p span { }
h2 ~ p :is(span) { }
}
*/
div {
& & & h3 {
background-color: green;
}
}

/*
Same as:
div div div h3 { }
*/
h3 {
:is(div) & {
color: #fff;
}
}

/*
Same as:
:is(div) h3 { }
*/
a {
&[download] {
border: 1px solid red;
}
}

/*
Same as:
a[download] { }
*/

You can try it today in Chrome Dev, Safari Technology Preview, or Polypane 13.

See on CodePen.

Further reading

Want more?

  1. Previous post: Day 98: oklab() and oklch()

Overview: 100 Days Of More Or Less Modern CSS

My blog doesn't support comments yet, but you can reply via e-mail.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK