子选择器>能精准控制样式作用域,只匹配直接子元素,避免后代选择器误中深层嵌套项,提升可维护性、性能与结构契约透明度。

子选择器 > 能切断 DOM 层级穿透,避免误中深层嵌套项
多层嵌套列表(比如 <ol> 套 <ol> 套 <ol>)时,ol li 这种后代选择器会匹配所有层级的 li,包括第一层、第二层、第三层……浏览器不区分“谁是哪一级”,只要 li 在某个 ol 内部就命中。结果就是:你只想改第一层编号样式,却把三级菜单里的 li 也一起重置了。
而 ol > li 强制只认“亲儿子”——它只查 ol 的直接子节点,中间插一层 <ol> 或 <div> 就立刻失效。这种“物理隔离”让样式作用域可控,不会因为 HTML 多套了一层就失控。
WordPress 子菜单类名重复时,> 是唯一能靠结构锚定层级的手段
WordPress 默认给所有子菜单都加 .sub-menu 类,HTML 结构类似:
<ul id="primary-menu">
<li><a>首页</a></li>
<li><a>产品</a>
<ul class="sub-menu"> <!-- 一级下拉 -->
<li><a>硬件</a>
<ul class="sub-menu"> <!-- 二级下拉 -->
<li><a>服务器</a></li>
</ul>
</li>
</ul>
</li>
</ul>这时用 #primary-menu .sub-menu 会同时命中两级,根本分不开;但写成:
立即学习“前端免费学习笔记(深入)”;
-
#primary-menu > .sub-menu→ 只抓第一层 -
#primary-menu > .sub-menu > .sub-menu→ 只抓第二层 -
#primary-menu > .sub-menu > .sub-menu > .sub-menu→ 只抓第三层
每层都靠 > 严格卡住父子关系,不依赖类名唯一性,也不怕中间混入无 class 的容器。
:not() 和 > 搭配时,能真正限定作用范围
在列表交互中常要排除禁用项,比如 .menu > li:not(.disabled)。这里 :not() 的作用对象被 > 锁死在“一级 li”上,哪怕某项内部又渲染了一个小列表(含自己的 li),也不会被误判为可点击项。
换成 .menu li:not(.disabled) 就危险了:它会遍历整个子树,把内嵌小列表里带 .disabled 的 li 也纳入计算,可能破坏行高、溢出或点击区域。
性能和重构友好性:> 让 CSS 和 HTML 的耦合更透明
浏览器匹配 .nav > ul > li > a 时,是从右往左找 a,再逐级验证父级是否严格满足“直接父节点”条件。路径短、回溯少,比 .nav ul li a(要向上查四层祖先链)快且稳定。
更重要的是,一旦 HTML 结构变动(比如把 <li><a> 改成 <li><div><a>),.nav > ul > li > a 直接失效——这不是 bug,而是帮你提前暴露结构与样式的契约断裂。而空格选择器会默默继续生效,直到某天样式错乱到无法调试。
真正容易被忽略的点是:> 不是“为了写得更长”,而是把“DOM 层级必须对齐”这个隐含假设,显式写进 CSS 里。写的时候多看一眼审查元素里的真实嵌套深度,比事后调半天优先级更省时间。


















