区别:
p:first-child
的含义:匹配父元素的第一个子元素、并且这个元素必须是P
,如果不是则匹配不到;p:first-of-type
的含义:匹配父元素的第一个类型是P
的子元素;
最大误区:大部分人刚开始接触时会想当然以为first-child
是first-of-type
的效果,但其实,first-of-type
才是大部分人想要的。
示例:
<style>
p:first-child {color: red}
div:first-of-type{color: blue}
</style>
<section>
<p>第1个元素</p>
<div>第2个元素</div>
<span>第3个元素</span>
<span>第4个元素</span>
</section>
如上面示例:
p:first-child
匹配第一个元素;div:first-child
匹配不到任何元素;div:first-of-type
匹配第二个元素;
其他诸如last-of-type
、nth-of-type
类似。
再次更新
2021-01-20 再次更新:之前还没注意到,:first-of-type
前面写tagName
和写其他选择器(比如class或者id等)含义完全不同:
:first-of-type
:从所有子元素中查找第一次出现的某种元素类型,例如第一个div
、第一个span
、第一个p
,等等,同一个父元素下可能同时命中多次;tagName:first-of-type
:从所有子元素中查找第一个tagName
,同一个父元素下最多只可能命中一次;.className:first-of-type
:从所有class
是className
的子元素中查找第一次出现的某种元素类型,例如第一个div
、第一个span
、第一个p
,等等,同一个父元素下可能同时命中多次(特别注意,并不是从子元素中查找第一个.className
)。tagName.className:first-of-type
:从所有class
是className
的子元素中查找第一个tagName
,同一个父元素下最多只可能命中一次(特别注意,并不是从子元素中查找第一个tagName.className
);
举个例子说明第3点:
<style>
.test:first-of-type{color: red;}
.test:last-of-type {color: blue;}
</style>
<section>
<p>第1个p元素</p>
<p class="test">第2个p元素</p>
<div class="test">第1个div元素</div>
<div>第2个div元素</div>
<div class="test">第3个div元素</div>
<p class="test">第3个p元素</p>
<span>第1个span元素</span>
</section>
上面例子中,第1个div元素
命中了,但是第2个p元素
没有命中,因为它虽然是第一个p.test
,但不是第一个p
。
再举个例子说明第4点:
<style>
div.test:first-of-type {color: blue;}
</style>
<section>
<div>第1个干扰div元素</div>
<div>第2个干扰div元素</div>
<div>第N个干扰div元素</div>
<div class="test">第1个div.test元素</div>
<div class="test">第2个div.test元素</div>
<p class="test">第1个p元素</p>
<span>第1个span元素</span>
</section>
上面例子中,没有命中任何元素,实际上这种情况也没法使用CSS去命中(假设干扰div数量不确定)