原生 CSS 嵌套(Nesting)终于来了!
1. 那个我们用了十年的“非官方”功能
如果你写过几年前的前端代码,你一定对 Sass 或 Less 不陌生。在这些 CSS 预处理器中,有一个功能几乎是所有开发者的最爱:选择器嵌套 (Nesting)。它允许我们像写 HTML 一样,将子选择器的规则写在父选择器的内部,极大地提升了代码的可读性和组织性。
// Sass 语法
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
}
li { display: inline-block; }
a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
}多年来,我们一直依赖构建工具将这种语法编译成浏览器认识的普通 CSS。但现在,情况变了。
2. 原生 CSS 嵌套登场
从 2023 年初开始,主流浏览器(Chrome, Safari, Firefox)陆续宣布支持原生的 CSS Nesting Module。这意味着,我们可以直接在 .css 文件里编写嵌套规则,无需任何预处理。
上面的例子用原生 CSS 可以这样写:
/* 原生 CSS 语法 */
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
}
li { display: inline-block; }
a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
}是的,它看起来和 Sass 完全一样!
3. & 的重要角色
和预处理器一样,& 符号在原生嵌套中也扮演着关键角色,它代表了父选择器。这在处理伪类、伪元素或组合选择器时非常有用。
.card {
background: white;
border-radius: 8px;
/* & 代表 .card */
&:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
/* & 代表 .card,组合成 .card.dark-mode */
&.dark-mode {
background: #333;
}
/* & 代表 .card,组合成 .card > .header */
> .header {
font-weight: bold;
}
}4. 与 Sass 的一个微小但重要的区别
在 Sass 中,你可以直接嵌套类选择器,比如 .card { .title { ... } }。在原生 CSS Nesting 的早期规范中,这是不被允许的,任何嵌套的规则都必须以一个符号(如 &, >, +, ~)开头。
虽然最新的规范放宽了这一限制,允许直接嵌套标签选择器(如 article { h1 { ... } }),但在嵌套类选择器时,为了明确和避免歧义,最佳实践仍然是使用 &。
/* 推荐写法 */
.article {
& .author-name {
font-style: italic;
}
}
/* 不推荐的写法 (在某些早期实现或严格解析器中可能无效) */
.article {
.author-name {
font-style: italic;
}
}使用 & 可以清晰地表达 .author-name 是 .article 的后代。
5. 浏览器支持与未来
截至 2023 年 9 月,所有主流现代浏览器(Chrome 112+, Safari 16.5+, Firefox 117+)均已支持 CSS Nesting。这意味着我们可以开始在生产环境中逐步使用它。
原生 CSS 嵌套的到来,是 Web 平台自身进化的又一个重要里程碑。它减少了我们对构建工具的依赖,让 CSS 本身变得更加强大和富有表现力,也让新入门的前端开发者能够更直观地编写和理解样式代码。