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

子选择器 > 只认“亲生儿子”
它只匹配父元素的**直接子元素**,中间不能隔任何层级。比如 用空格连接的选择器,如 打开浏览器开发者工具,把鼠标悬停在目标元素上,看右键「Reveal in Elements panel」后的嵌套路径: CSS 对空格极其敏感—— 立即学习“前端免费学习笔记(深入)”; 真正在项目里混用时,最麻烦的不是语法记错,而是团队成员对“这里该不该穿透多层”没有共识。一个 nav > a 只会选中 下第一层的 ,如果 被包在 里,就完全失效。
.menu > li 却发现下拉菜单里的 li 没生效——因为那些是二级菜单,嵌套在另一个 里,已不是 .menu 的直接子元素后代选择器(空格)管“所有子孙”
article p,会匹配 内任意深度的 ,哪怕它藏在
.card p 给卡片正文设字体,结果连卡片标题、按钮文字甚至 footer 里的 p 全被改了——因为它们都是 .card 的后代怎么一眼判断该用哪个?看 HTML 结构深度
div > p),优先用 >
div > section > article > p),且你希望一并覆盖,就用空格> 或加更具体类名(如 .card__content p).sidebar ul { margin: 0; } /* 后代:所有 ul,包括子菜单 */
.sidebar > ul { padding: 1rem; } /* 子代:仅顶层导航 ul */容易被忽略的坑:空格不是可有可无的字符
div>p(没空格)是无效语法,等同于写错;div > p(带空格)才合法。同样,headerp 不会匹配任何内容,必须写成 header p(中间有空格)。
selector-descendant-combinator-spacing)nav { > a { ... } } 会自动编译出带空格的 nav > a,但手写 CSS 时仍需自己留心.modal .btn 看似安全,但如果某天有人把按钮挪进 里,样式就断了——这时候你得决定:是改 HTML,还是补一条 .modal footer .btn,还是干脆换成 .modal > * .btn?选哪个,取决于你愿不愿意为灵活性多担一点维护成本。









