:only-child要求元素是父元素的唯一子节点(含文本、注释等所有节点),常见失效因换行/空格/注释生成了隐藏兄弟节点;与:only-of-type区别在于后者仅按元素类型判断唯一性。

:only-child 选的是「既没有兄弟元素,又确实是某个父元素的子元素」的那个元素——不是“唯一子元素”就无效,哪怕它看起来是唯一的。
为什么 :only-child 有时不生效?
最常见原因是:HTML 结构里混入了文本节点、注释或空格。浏览器会把换行缩进当成 Text 节点,导致目标元素实际有“兄弟”(哪怕你看不见)。
- ✅ 正确结构:
<div><p>内容</p></div>
→p是div唯一子节点,p:only-child匹配 - ❌ 常见失效:
<div>\n <p>内容</p>\n</div>
→ 换行和空格生成两个Text节点,p不再是:only-child - ⚠️ 注释也会破坏:
<div><!-- 注释 --><p>内容</p></div>→p有兄弟(注释节点)
:only-child 和 :only-of-type 的关键区别
两者都要求“唯一”,但判断维度不同:
-
:only-child看的是「所有子节点中是否只有它一个」,类型不限(span、div、文本都算) -
:only-of-type看的是「同类型元素中是否只有它一个」,忽略其他类型节点 - 例如:
<section><h1>标题</h1><p>段落</p></section>
→h1:only-child不匹配(有p兄弟),但h1:only-of-type匹配(它是唯一的h1)
实际能用上的典型场景
适合处理「单个内容块」的样式隔离,但必须确保 DOM 干净:
立即学习“前端免费学习笔记(深入)”;
- 列表项只有一条时隐藏序号:
ol li:only-child::before { content: none; } - 卡片容器内仅有一个
img时居中显示:.card img:only-child { display: block; margin: 0 auto; } - 表单里只有一个
input时取消边框间距:form input:only-child { margin: 0; border-radius: 4px; }
真正要用好 :only-child,得先 inspect 元素看 computed node tree —— 很多时候问题不在 CSS,而在 HTML 里那些看不见的空白字符。



















