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

子选择器 > 只认“亲生儿子”
它只匹配父元素的**直接子元素**,中间不能隔任何层级。比如 nav > a 只会选中 <nav></nav> 下第一层的 <a></a>,如果 <a></a> 被包在 <div> 或 <code><li> 里,就完全失效。
- 常见错误:写成
.menu > li却发现下拉菜单里的li没生效——因为那些是二级菜单,嵌套在另一个<ul></ul>里,已不是.menu的直接子元素 - 适用场景:需要精准控制组件第一层结构时,比如重置导航栏主项样式,但不想影响子菜单
- 性能略优:浏览器无需遍历深层 DOM,匹配更快(尤其在复杂列表中)
后代选择器(空格)管“所有子孙”
用空格连接的选择器,如 article p,会匹配 <article></article> 内任意深度的 <p></p>,哪怕它藏在 <section><blockquote> <div> 套了五层里面。<ul>
<li>常见错误:用 <code>.card p 给卡片正文设字体,结果连卡片标题、按钮文字甚至 footer 里的 p 全被改了——因为它们都是 .card 的后代
怎么一眼判断该用哪个?看 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 看似安全,但如果某天有人把按钮挪进 <footer></footer> 里,样式就断了——这时候你得决定:是改 HTML,还是补一条 .modal footer .btn,还是干脆换成 .modal > * .btn?选哪个,取决于你愿不愿意为灵活性多担一点维护成本。









