CSS nesting 怎样组织组件内嵌套规则
来源:17golang原创
时间:2026-10-21 19:19:44 227浏览 收藏
CSS nesting 适合把一个组件的基础样式、子元素样式和状态样式放在同一个规则块里。浏览器会直接解析嵌套规则:普通嵌套选择器默认与父选择器形成后代关系,写出 & 时则可以明确要求父选择器参与拼接,例如把 &:hover 展开成 .card:hover。
它不是必须经过 Sass、Less 之类预处理器的语法。本文只讨论原生 CSS 的选择器展开、组合器、条件规则和特异性,不把嵌套当成全新的组件隔离机制。
官方资料:https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Nesting
规范入口:https://drafts.csswg.org/css-nesting/
先看一个能直接落地的组件写法
.card {
/* 只放卡片自身的布局与外观 */
padding: 1rem;
border: 1px solid #d8dee9;
border-radius: 0.75rem;
.title {
/* 默认与父选择器形成后代关系:.card .title */
margin: 0;
color: #203047;
}
&:hover {
/* & 直接代表父选择器:.card:hover,而不是 .card :hover */
border-color: #2f7cf6;
}
}
这段 CSS 的关键不是减少了几个字符,而是让相关规则共享同一个组件边界。.title 前面没有 &,所以默认得到 .card .title;&:hover 明确表示伪类要紧贴父选择器,得到的是 .card:hover。

默认后代关系和 & 不是一回事
原生 nesting 允许把样式规则放进另一条样式规则中。嵌套选择器默认相对父选择器解释,相当于在两者之间加入后代组合器。需要精确控制关系时,要把组合器或 & 写出来。
.menu {
/* 没有 &:等价于 .menu .item */
.item {
color: #40536d;
}
/* >:只匹配直接子元素 */
> .item {
padding-inline: 0.75rem;
}
/* & +:父选择器与下一个同级元素相邻 */
& + .menu {
margin-block-start: 1rem;
}
}
这里的三个关系分别是 .menu .item、.menu > .item 和 .menu + .menu。如果写成 & .item,仍然是显式的后代关系;如果把 & 省略,浏览器也会按默认后代关系处理。
最常见的误读是把 :hover 当成可以直接嵌套的后缀。.card { :hover { ... } } 表达的是卡片内部某个后代元素悬停,而不是卡片本身悬停;卡片自身状态应写成 &:hover。
把媒体查询放在组件内部,但别混淆作用域
.card {
/* 基础规则先保持可读,窄屏默认使用单列 */
display: grid;
gap: 0.75rem;
@media (width >= 48rem) {
/* 媒体查询仍位于 .card 的嵌套上下文中 */
grid-template-columns: 12rem 1fr;
.title {
/* 这里仍然指向 .card .title */
align-self: center;
}
}
}
媒体查询可以嵌套在组件规则内部,读者能在同一处看到组件的响应式变化。它改变的是条件,不会把 .title 变成全局选择器;理解这点后,可以把组件的基础规则和宽度条件放在一起维护。
如果项目仍需兼容不支持 nesting 的处理链,可保留一份扁平选择器作为回滚路径,或者由构建链统一转换。不要在同一文件里无意识地混用两套写法,否则后续排查时很难判断到底是浏览器解析、构建转换还是层叠顺序造成差异。
样式不生效时,先查 & 和特异性
& 的特异性不是简单地按一个普通字符计算。关联选择器列表中,特异性最高的选择器会影响嵌套结果;因此父规则里如果混入高特异性的 ID 选择器,嵌套规则可能比预想更难覆盖。
#shell, .card {
/* 关联列表中包含 ID,会抬高嵌套 & 的特异性 */
& .title {
color: #153e75;
}
}
.card .title {
/* 仅增加 class 可能仍然覆盖不了上面的嵌套规则 */
color: #64748b;
}
排查时先把嵌套规则展开成普通选择器,再比较选择器、层叠层和出现顺序。若只是希望状态样式覆盖基础样式,优先使用一致的 class 结构和明确的 &,不要靠不断增加选择器长度解决问题。

需要回滚时,用扁平规则保留同一语义
回滚的目标是保留选择器语义,而不是简单删除缩进。可以把嵌套块拆成普通规则,逐条对照默认后代关系与显式 & 的展开结果。
/* 原来的嵌套写法 */
.card {
/* 回滚时保留基础规则 */
padding: 1rem;
&:hover {
/* 显式父选择器展开为 .card:hover */
border-color: #2f7cf6;
}
}
/* 扁平回滚写法 */
.card:hover {
/* 只在这里保留状态规则,避免误写成 .card :hover */
border-color: #2f7cf6;
}
如果要判断当前处理链是否接受 nesting,可以把能力检测放在构建或兼容策略中;不要把“能够写进源文件”误认为“所有目标浏览器和构建链都已经按同一规则处理”。文章主题只需要确认选择器语义,实际项目还应按自己的目标环境决定是否保留降级方案。
提交前按这份清单整理组件样式
- 先确认嵌套规则对应的是组件边界,而不是为了缩短文件盲目加深层级。
- 普通子选择器按默认后代关系理解;组件自身的伪类、伪元素优先写成
&:hover、&::before。 - 子代、相邻兄弟或通用兄弟关系直接写出
>、+、~,别靠缩进猜测。 - 把媒体查询、支持查询等条件规则放在关联组件附近,同时保留清晰的基础样式。
- 样式覆盖异常时,先展开选择器比较特异性,再检查层叠层和规则顺序。
- 需要兼容旧处理链时,用扁平选择器保存回滚版本,避免把两套语义写成不同规则。
CSS nesting 的价值是让“同一个组件的规则”在源文件中保持邻近。只要记住默认后代关系、& 的显式父选择器语义,以及展开后的特异性,组件内嵌套就能保持可读而不变成选择器谜题。
两个容易混淆的问题
嵌套规则是不是只能写在 Sass 里? 不是。CSS nesting 是浏览器 CSS 语法的一部分,但目标项目是否直接交给浏览器解析,仍取决于目标环境和构建链。
为什么写了 :hover 却没有匹配卡片? 在父规则里直接写 :hover 通常表示父元素内部的后代伪类位置;卡片自身状态应显式写成 &:hover,让展开结果成为 .card:hover。
-
502 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
442 收藏
-
208 收藏
-
366 收藏
-
文章 · 前端 | 2小时前 | 前端 · JSON · javascript · JavaScript vite json模块 ES module import attributes with type=json406 收藏
-
文章 · 前端 | 2小时前 | 前端 · 性能优化 · javascript · 浏览器API · IntersectionObserver rootMargin threshold Intersection Observer API unobserve 前端懒加载182 收藏
-
文章 · 前端 | 2小时前 | 前端 · css · 浏览器兼容 · anchor-name position-area CSS anchor positioning position-anchor position-try 下拉菜单定位161 收藏
-
252 收藏
-
208 收藏
-
284 收藏
-
432 收藏
-
432 收藏
-
464 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习