大家好,我是潘潘。
有几个css的结构伪类选择器很容易搞混,这期就帮大家梳理一下这几个选择器的使用思路。
(文末有记忆“口诀”)
前几天有小伙伴在我们的前端交流群里问了一个关于css中:last-child选择器的问题:

他给出的代码如下:

可以看到它的body里只写了两个div,第一个div设置了:first-child选择器后,成功让它向下和向右偏移了30px,但是使用:last-child选择器设置最后一个(因为这里只有两个div,所以也就是第二个)div的背景色的时候却没有效果,我也发现很奇怪,为啥没效果呢?
我开始想,难道是因为第一个元素选择器设置的背景色覆盖了:last-child的颜色?那么我把第一个元素选择器的背景色删掉,并且为演示方便,我给div都加上了边框:

结果最后一个(也就是第二个)div的颜色直接没了,:last-child选择器还是没选择到最后一个div
这就奇了怪了,难道是vscode出bug了?还是:last-child的语法我没搞懂?
经过一番菜鸟、MDN和群交流之后,我才明白原来是Live Server“搞的鬼”。

Live Server插件为了实现实时修改保存后自动刷新页面的功能,在我们打开Open with Live Server时自动创建了一个script标签,写入了js代码

因为在body中自动创建了script标签,此时div的兄弟元素的最后一个元素是script元素,并不是div,所以:last-child选择器失效。此时如果删掉这个script标签。就会选择到最后一个div,设置的紫色背景也会生效:

那既然查了这么多了,不如就趁此机会复习一下很多人一直没搞清楚的几个css伪类选择器:
:first-child:选取在一组兄弟元素中的第一个元素。
:first-of-type:选取在一组兄弟元素中的第一个指定元素。
解释一下:比如p:first-child{},选择的就是p元素的兄弟元素的第一个元素,且这个元素必须是p元素才被选择;div:first-of-type就是选择div的兄弟元素中的第一个div元素。
比如,这样使用div:first-child选择第一个div,并设置背景为天蓝色:

但是如果在第一个div前加上一个p元素,那么div:first-child就不再选择得到第一个div元素,因为div的第一个兄弟元素不是div:

而如果把:first-child改成:first-of-type选择器,即使div的兄弟元素中第一个元素为p元素,也会选择到第一个div元素:

:last-child在刚开始的例子中讲过,这里略,只讲一下:last-of-type选择器:选取在一组兄弟元素中指定元素的最后一个。
例如:
和刚开始的例子一样,使用:last-of-type选择器,即使div元素后有script元素,也可以选择到最后一个div:

因为div:last-of-type选择的是div兄弟元素中的最后一个div元素,而不是像div:last-child一样选择div的兄弟元素中的最后一个元素,且必须为div才能选到,这是这两个选择器的主要差别。
:nth-child(n):选择每个指定元素是其兄弟元素的第n个元素
:nth-last-child(n):选择每个指定元素是其兄弟元素的第n个元素,从最后一个兄弟元素计数
:nth-child(n)和:nth-last-child(n)像是:first-child和:last-child的拓展版,必须该元素的第n个兄弟元素是指定元素才能选到
例如:
这样可以选到:

但是在div的第一个兄弟元素前加上一个其他元素,div:nth-child(1)就不再能选到第一个div元素:

此时如果改成div:nth-child(2)就能选到第一个div:

:nth-last-child()只是从指定元素的最后一个兄弟元素开始计数,其他同理,略
:nth-of-type(n):选择指定元素的兄弟元素中第n个该元素
:nth-last-of-type(n):选择指定元素的兄弟元素中第n个该元素,从最后一个兄弟元素的该元素计数
:nth-of-type(n)和:nth-last-of-type(n)像是:first-of-type和:last-of-type的拓展版,它可以选择指定元素的兄弟元素中,同为该元素的第n个:
例如:
即使div的兄弟元素的第一个是p元素,div:nth-of-type(1)依然选择得到第一个div元素:

:nth-last-of-type()也一样:

同样选择到了最后一个div元素,并不受最后一个p元素的影响。
在以上八个伪类选择器中,:first-child :last-child :nth-child(n) :nth-last-child(n)在选择元素时,是按照其所有类型的兄弟元素开始计数,而:first-of-type :last-of-type :nth-of-type(n) nth-last-of-type(n),是按照其兄弟元素中,忽略除该元素以外的所有其他元素后开始计数的。
还没搞懂也没关系,你只需要记住下面这条规则:
带“child”的选择器眼中存在“异类”元素;而带“type”的眼中只有“同类”元素;带“first”的选择的是第一个;带“nth”的可以选择第几个,带“last”字眼的选择器是从后往前数。
以上,
希望大家看完这期文章之后,在使用这八个伪类选择器的时候,思路能更清晰些。