:only-child匹配父元素下唯一子节点的元素,不区分类型,仅看DOM中是否存在其他同级节点;若存在空白文本或注释节点则失效,与:only-of-type(同标签唯一)易混淆。

怎么用 :only-child 识别唯一子元素
当父容器里只有一个子元素,且该子元素没有兄弟节点时,:only-child 就能精准匹配它。它不关心子元素类型或内容,只看 DOM 结构中是否存在其他同级元素。
常见误用是把它当成“只有一个该类型子元素”的判断(那是 :only-of-type 的事),这点必须分清。
-
:only-child匹配的是「整个子元素列表中仅此一个」的元素 - 哪怕父元素里混着文本节点、注释节点或
,只要存在非空文本(比如换行缩进产生的空格),就可能破坏匹配——因为浏览器会把这类文本解析为Text节点,变成实际的兄弟节点 - 如果父元素 HTML 写成紧凑格式(如
),不换行不空格,xxx
:only-child更可靠
:only-child 和 :only-of-type 的区别在哪
这是最容易混淆的点。举个例子:
立即学习“前端免费学习笔记(深入)”;
标题
正文
此时 h1 不是 :only-child(因为还有 p 兄弟),但它可能是 :only-of-type(如果 article 里没别的 h1)。
再看这个:
ul 是 nav 的 :only-child;但如果 nav 里还藏了个 ,它就不是了。
-
:only-child→ 看「是否唯一子节点」 -
:only-of-type→ 看「是否该标签类型中唯一一个」 - 二者条件不同,不能互换,也不能叠加使用来“增强判断”
为什么有时候写了 :only-child 却不生效
最常踩的坑是 HTML 源码里看不见的节点干扰:
- 换行和缩进生成的空白文本节点(尤其在 Pug / Jade 或服务端模板渲染时容易出现)
- 注释节点:
也是真实子节点 - 动态插入内容后未清理旧节点,导致残留
- CSS 优先级被其他规则覆盖(比如更具体的类名或内联样式)
调试建议:打开浏览器开发者工具,选中父元素,在 Elements 面板里手动删掉所有文本节点和注释,再看样式是否恢复生效。
替代方案:什么时候不该用 :only-child
如果你真正想表达的是“这个元素单独存在时才应用样式”,但又无法控制 HTML 输出是否带空格/注释,那就别硬扛 :only-child。
更稳妥的做法是加 JS 判断或服务端标记:
if (parent.children.length === 1) {
parent.classList.add('has-only-child');
}或者用属性选择器配合约定:
…
然后写 CSS:section[data-child-count="1"] > article { … }
DOM 结构越不可控,越要放弃纯 CSS 的“理想化”判断,转而用显式可控的方式表达意图。
真正难的不是写对伪类,而是确认你面对的 HTML 是否真的干净到能信任 :only-child。









