应使用 p:first-of-type 而非 p:first-child,因后者仅匹配父元素首个子节点且对空白、注释、其他标签敏感,而前者在所有同类型段落中取首项,语义准确、兼容性好,但需加容器限定以防全局污染。

直接用 p:first-of-type,别碰 p:first-child —— 后者在真实 HTML 结构里大概率失效。
为什么 p:first-child 总是不生效
它只认“父元素的第一个直接子节点”,完全不管标签类型。哪怕前面只有换行、空格、注释,或者一个 <h2>、<div class="ad">,p:first-child 就立刻失联。
- HTML 中常见结构:
<article><h1>标题</h1><p>第一段</p></article>→ 这里<p>是第二个子节点,p:first-child匹配失败 - 连 DOM 树里的文本节点(比如段落前的回车)都会干扰匹配,调试时看不到也容易漏查
- 它和“页面上第一个段落”这个业务需求根本不是一回事
p:first-of-type 才是真正靠谱的选择
它只看同类型元素(即所有 <p>)中谁排第一,其他兄弟节点(<h2>、<div>、注释、空白)全被无视。
- 兼容性够用:IE9+ 全支持,现代项目基本无压力
- 语义清晰:
p:first-of-type就是“第一个段落”,不是“第一个孩子” - 示例 HTML:
<section><h2>导语</h2><p>首段内容</p><p>次段内容</p></section>→p:first-of-type稳稳命中“首段内容”
必须加容器限定,否则会全局污染
单独写 p:first-of-type 会作用于整个页面所有 <p> 的首个实例,包括页脚、侧边栏、弹窗里的段落 —— 很可能出 bug。
立即学习“前端免费学习笔记(深入)”;
- 推荐写法:
article p:first-of-type、.post-content p:first-of-type、main > p:first-of-type - 优先用语义化标签(如
<main>、<section>)或稳定 class 限定范围,别依赖 DOM 深度 - 如果首段需要去上边距或取消首行缩进,记得显式重置:
margin-top: 0或text-indent: 0,别指望继承值可靠
别忘了它只按标签类型计数,不看 class 或属性
p.highlight:first-of-type 和 p:first-of-type 行为完全不同:前者找的是带 highlight 类的第一个 <p>;后者找的是所有 <p> 中的第一个,哪怕它没 class。
- 如果你要控制“带某个 class 的首个段落”,得用
p.highlight:first-of-type,不是p:first-of-type.highlight(后者语法错误) - 如果父容器里只有一个
<p>,那它同时匹配:first-of-type和:last-of-type,这点容易被忽略 - 它不能跨父级查找 —— CSS 没有“文档中第一个
<p>”这种全局选择器,所有伪类都严格限制在单个父元素内计算


















