子选择器>只匹配直接子元素,如nav>a;后代选择器(空格)匹配所有嵌套子孙,如article p;判断依据是html结构深度,空格不可省略,混用需团队共识。

子选择器 > 只认“亲生儿子”
它只匹配父元素的**直接子元素**,中间不能隔任何层级。比如 nav > a 只会选中
或
里,就完全失效。
- 常见错误:写成
.menu > li却发现下拉菜单里的li没生效——因为那些是二级菜单,嵌套在另一个里,已不是.menu的直接子元素 - 适用场景:需要精准控制组件第一层结构时,比如重置导航栏主项样式,但不想影响子菜单
- 性能略优:浏览器无需遍历深层 dom,匹配更快(尤其在复杂列表中)
后代选择器(空格)管“所有子孙”
用空格连接的选择器,如 article p,会匹配
内任意深度的
,哪怕它藏在
套了五层里面。
- 常见错误:用
.card p给卡片正文设字体,结果连卡片标题、按钮文字甚至 footer 里的p全被改了——因为它们都是.card的后代- 适用场景:批量样式复用,比如统一设置某区块内所有段落、链接、列表的默认间距和颜色
- 注意兼容性:所有现代浏览器都支持,但过度使用易引发样式泄漏(style leakage),特别是组件化开发中
怎么一眼判断该用哪个?看 HTML 结构深度
打开浏览器开发者工具,把鼠标悬停在目标元素上,看右键「Reveal in Elements panel」后的嵌套路径:
- 如果目标元素紧贴在父容器下(即路径是
div > p),优先用>- 如果目标元素可能出现在多层嵌套中(如
div > section > article > p),且你希望一并覆盖,就用空格- 不确定时,先写空格版测试效果;若范围太大,再收紧为
>或加更具体类名(如.card__content p).sidebar ul { margin: 0; } /* 后代:所有 ul,包括子菜单 */ .sidebar > ul { padding: 1rem; } /* 子代:仅顶层导航 ul */容易被忽略的坑:空格不是可有可无的字符
css 对空格极其敏感——
div>p(没空格)是无效语法,等同于写错;div > p(带空格)才合法。同样,headerp不会匹配任何内容,必须写成header p(中间有空格)。立即学习“前端免费学习笔记(深入)”;
- 编辑器自动补全有时会漏掉空格,保存后样式突然失效,先检查空格
- 用 Prettier 或 Stylelint 可配置规则强制校验空格位置(如
selector-descendant-combinator-spacing)- 在 scss 中,嵌套写法
nav { > a { ... } }会自动编译出带空格的nav > a,但手写 CSS 时仍需自己留心真正在项目里混用时,最麻烦的不是语法记错,而是团队成员对“这里该不该穿透多层”没有共识。一个
.modal .btn看似安全,但如果某天有人把按钮挪进里,样式就断了——这时候你得决定:是改 HTML,还是补一条
.modal footer .btn,还是干脆换成.modal > * .btn?选哪个,取决于你愿不愿意为灵活性多担一点维护成本。