:first-of-type 按父元素内同标签兄弟节点单独计数,非全局首个;用 > 限定直接子元素、:nth-child(1) 或 .item:not(.item ~ .item) 可精准选首个同类元素。

为什么 :first-of-type 总是“选错”兄弟元素
它根本不是在找“你想要的第一个”,而是在每个父容器内,对所有同标签名的兄弟节点单独计数。比如 .content p:first-of-type 会钻进 .content 下任意嵌套层级的 div、section、.ad-slot 里,只要那个 p 是其**直接父元素下第一个 p**,就会被匹配——哪怕它是广告文案或侧栏说明。
.article > p:first-of-type 才是真正可控的写法
加 > 能切断后代匹配,把作用域锁死在一层。这和浏览器解析 DOM 的方式完全一致:只看父元素的直接子节点列表,不递归向下。
-
.article p:first-of-type→ 危险:等价于.article * p:first-of-type,可能命中.article > .card > p -
.article > p:first-of-type→ 安全:只匹配<div class="article"><p>...</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/code/12093" title="CSS婚礼策划服务机构宣传网站模板"><img src="https://img.php.cn/upload/webcode/000/000/018/178607072210981.jpg" alt="CSS婚礼策划服务机构宣传网站模板" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/code/12093" title="CSS婚礼策划服务机构宣传网站模板" class="overflowclass">CSS婚礼策划服务机构宣传网站模板</a> <p class="overflowclass">CSS婚礼策划服务机构宣传网站模板是一款适合提供婚礼策划和婚庆服务机构宣传网站模板下载。提示:本模板调用到谷歌字体库,可能会出现页面打开比较缓慢。</p> </div> <a rel="nofollow" href="/xiazai/code/12093" title="CSS婚礼策划服务机构宣传网站模板" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div></div>这种结构 - 即使
.article下第一个子是<h2></h2>,第二个才是<p></p>,它依然能正确选中那个p
当目标不是 p,而是带 class 的元素时
.item:first-of-type 不是你想的“所有 .item 中第一个”,而是“是 .item 类,且同时是其父元素中第一个 div(或其他对应标签)”。一旦前面有其他同标签元素(如 <div class="header">),它就失效。<ul>
<li>想选「类名为 <code>item 的第一个元素」?用 .item:nth-child(1) 或 .item:first-child(前提是它真是第一个子节点)
document.querySelector('.item').classList.add('item-first'),再写 .item-first { ... }
.item:not(.item ~ .item) —— 表示“这个 .item 前面没有其他 .item”,逻辑上就是第一个容易被忽略的关键点
:first-of-type 永远绑定在单个父元素上下文里,CSS 中根本没有“整个页面首个 p”这种全局选择器。你看到的“选错了”,90% 是因为没意识到父容器比你以为的更小、更碎——比如广告位自己就是一个独立 div,它的子 p 就是它自己的 :first-of-type。调试时务必在 Elements 面板里展开父节点,逐层确认真实子节点构成,别信 HTML 缩进或注释里的“视觉意图”。










