原生 CSS 嵌套语法实战
CSS 原生嵌套终于在 2023 年底得到主流浏览器支持。不用预处理器也能写嵌套了。
基本语法
/* 原生嵌套 */
.card {
padding: 1rem;
& .title {
font-size: 1.5rem;
}
& .content {
color: #666;
}
&:hover {
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
}
编译后:
.card {
padding: 1rem;
}
.card .title {
font-size: 1.5rem;
}
.card .content {
color: #666;
}
.card:hover {
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
嵌套选择器
& 代表父选择器,可以拼接在任何位置:
.button {
background: blue;
&:hover {
background: darkblue;
}
&:active {
transform: scale(0.98);
}
&:disabled {
opacity: 0.5;
}
}
也可以用在选择器中间:
.container {
body.dark & {
background: #1a1a1a;
}
.sidebar & {
width: 100%;
}
}
嵌套 @ 规则
媒体查询可以嵌套在规则内部:
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
@media (max-width: 768px) {
grid-template-columns: repeat(2, 1fr);
}
@media (max-width: 480px) {
grid-template-columns: 1fr;
}
}
这比传统的写法清晰很多:
/* 传统写法 */
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
@media (max-width: 768px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 480px) {
.grid {
grid-template-columns: 1fr;
}
}
实际组件示例
/* 一个完整的卡片组件 */
.post-card {
border-radius: 8px;
overflow: hidden;
background: #fff;
transition: transform 0.2s, box-shadow 0.2s;
& .thumbnail {
aspect-ratio: 16 / 9;
object-fit: cover;
width: 100%;
}
& .body {
padding: 1rem;
& .title {
font-size: 1.25rem;
font-weight: 600;
margin-bottom: 0.5rem;
&:hover {
color: #0070f3;
}
}
& .excerpt {
color: #666;
line-height: 1.6;
}
}
& .footer {
padding: 0.75rem 1rem;
border-top: 1px solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
& .date {
font-size: 0.875rem;
color: #999;
}
& .tag {
font-size: 0.75rem;
padding: 0.25rem 0.5rem;
background: #f0f0f0;
border-radius: 4px;
}
}
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
@media (prefers-color-scheme: dark) {
background: #1a1a1a;
& .body .excerpt {
color: #aaa;
}
& .footer {
border-top-color: #333;
}
}
}
与预处理器对比
原生嵌套和 Sass/Less 的区别:
| 特性 | 原生 CSS | Sass |
|---|---|---|
| 嵌套选择器 | ✅ | ✅ |
| 嵌套属性 | ❌ | ✅ |
| 变量 | ✅ (--var) |
✅ ($var) |
| 混合宏 | ❌ | ✅ |
| 函数 | ❌ | ✅ |
| 继承 | ❌ | ✅ |
原生嵌套能满足大部分场景,但复杂项目还是需要预处理器或 PostCSS。
浏览器支持
2024 年初,所有主流浏览器都已支持:
- Chrome 120+
- Firefox 121+
- Safari 17.2+
- Edge 120+
如果需要兼容旧浏览器,可以用 PostCSS 的 postcss-nesting 插件:
npm install postcss-nesting
// postcss.config.js
module.exports = {
plugins: {
'postcss-nesting': true,
}
};
小结
原生 CSS 嵌套让样式代码更简洁、更易维护。对于不需要复杂预处理器功能的项目,可以直接使用原生语法,减少构建依赖。
CSS
返回首页