first-child 和 first-of-type 的区别
本文由 小茗同学 发表于 2020-04-22 浏览(1590)
最后修改 2021-10-27 标签:

区别:

  • p:first-child的含义:匹配父元素的第一个子元素、并且这个元素必须是P,如果不是则匹配不到;
  • p:first-of-type的含义:匹配父元素的第一个类型是P的子元素;

最大误区:大部分人刚开始接触时会想当然以为first-childfirst-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-typenth-of-type类似。

再次更新

2021-01-20 再次更新:之前还没注意到,:first-of-type前面写tagName和写其他选择器(比如class或者id等)含义完全不同:

  1. :first-of-type:从所有子元素中查找第一次出现的某种元素类型,例如第一个div、第一个span、第一个p,等等,同一个父元素下可能同时命中多次;
  2. tagName:first-of-type:从所有子元素中查找第一个tagName,同一个父元素下最多只可能命中一次;
  3. .className:first-of-type:从所有classclassName的子元素中查找第一次出现的某种元素类型,例如第一个div、第一个span、第一个p,等等,同一个父元素下可能同时命中多次(特别注意,并不是从子元素中查找第一个.className)。
  4. tagName.className:first-of-type:从所有classclassName的子元素中查找第一个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数量不确定)