CSS3 nth 伪类选择器

简介: 考察下面的 HTML 代码片段: section 1 section 2 item 1 sub item 1 sub item 2 ...

考察下面的 HTML 代码片段:

<div>
    <section>section 1</section>
    <section>section 2</section>
    <ul>
        <li>item 1</li>
        <li>
            <ul>
                <li>sub item 1</li>
                <li>sub item 2</li>
                <li>sub item 3</li>
            </ul>
        </li>
        <li>item 3</li>
        <li>item 4</li>
        <li>item 5</li>
        <li>item 6</li>
        <li>item 7</li>
        <li>item 8</li>
        <li>item 9</li>
    </ul>
    <section>section 3</section>
    <section>section 4</section>
    <section>section 5</section>
</div>

单凭 section 可以让我们选中所有的<section> 标签,what if we wanna specific ones? 譬如只选中第一个。

那你可能已经知道:first-child伪类选择器了,所以选中第一个也不是什么麻烦事情。类似地可以用:last-child选中最后一个指定的元素。

section:first-child,section:last-child {
    color: red;
}

here comes out the result:
css :fist-child & :last-child 选择器

当场景再复杂一些的时候,譬如选中第2个,第3个,第基数个,很自然地,我们会想到引入一个变量来完成任务。

nth 系列荣誉登场

CSS3中的 nth 系列选择器便是这样一种支持变量计算的选择器,可以完成上述复杂的选择需求。

譬如高亮前面示例 HTML 片段中第基数个 sectionli 标签可以这样做:

section:nth-child(2n+1),li:nth-child(2n+1){
    color:red;
}

and here comes out the result again:

使用 :nth-child 高亮第基数个元素

:nth-child完整的语法为:nth-child(an+b),它匹配父容器下面中第an+b个子元素。例如:nth-child(3n+1)将会选中位置位于第1(3*0+1),4(3*1+1),7(3*2+1)...的元素。

:nth-child这样厉害的选择器还有3个!它们分别是:

借助于这样灵活的选择器,在编写样式时使我们更加得心应手,甚至有了很多花样玩法。

:nth-child

:nth-child(an+b) 会匹配所有兄弟节点中位置位于an+b位置的元素。 其中 n 是从0开始的正整数。

除了像前面所说的可以通过完整的表达式匹配到连续规律位置的元素外,如果我们将 a 设为0的话,就可以匹配指定的单个元素。

譬如考察下面的 HTML 片段:

<div>
    <p>foo</p>
    <p>bar</p>
    <p>baz</p>
</div>

高亮第二个元素:

p:nth-child(2){
    color: red;
}

利用:nth-child 选中第2个元素

同理,:nth-child(3) 会选中第三个元素。

这个示例中,也可以用:nth-last-child:

p:nth-last-child(2){
    color: red;
}

效果当然是一样的,因为:nth-last-child(2)从后面开始数第二个,正好与顺位数第二个是同一元素。

:nth-of-type

:nth-of-type(an+b)用法上没有区别,但它只会匹配相同标签的兄弟元素。也就是在:nth-child的基础上加了一条限制:标签要一致。

还是考察刚刚的 HTML 片段,我们要选中第二个<p> 标签,仍然是指定位置为2即可:

p:nth-of-type(2){
    color: red;
}

但情况变一下,我们在第2个<p>标签前面加上另外一个元素譬如<section>,考察更新后的 HTML 片段:

<div>
    <p>foo</p>
    <section>quz</section>
    <p>bar</p>
    <p>baz</p>
</div>

此时我们仍然想要选中第2个<p>标签。

p:nth-child(2){
    color: red;/*会匹配失败,因为第二个子元素不是 p 标签*/
}
p:nth-of-type(2){
    color: red;/*仍然匹配成功*/
}

此时用:nth-child(2)不会选中任何元素,因为它的意思是选中div下面子元素中的第2个元素,并且这个元素是一个<p> 标签。而上面 HTML 片段中,第二个子元素明显不是<p>标签,所以匹配失败。

而通过:nth-of-type(2)来选择则仍然生效。因为不管第2个<p>元素前面插几个<section>标签,此时内容为bar<p>标签仍然是父容器所有子节点中顺位第二个类型为<p>的标签。

:nth-child:nth-of-type的区别

通过前面的示例可以看出,:nth-of-type在你始终需要选择第 N 个特定类型的元素时更为可靠,它首先会提取出所限定的元素类型,然后再从这个没有杂质的集合中去匹配顺序。

因此:nth-of-type在大多数时候可能更满足你的需要,毕竟很多时候需求是选中第3个<span>,第5个<p>。而不是第7个元素,无论是什么类型的节点。

这里有一个页面:nth Tester可以方便地把玩 nth 系列的四大金钢。通过可视化操作应该能够更好地理解。

扩展的花样玩法

前面说道,表达式an+b可以将 a 取值为0,这样就可以选中第 b 个元素。如果将 a 取值为1的话,我们就可以选中从第 b 个元素开始的所有元素。

譬如选中从第三个元素开始的所有<p>标签:

<div>
    <p>1</p>
    <p>2</p>
    <p>3</p>
    <p>4</p>
    <p>5</p>
</div>
p:nth-child(n+3){
    color: red;
}

选中从第3个元素后的所有p标签

虽然 n 是从0开始的正整数,但 a 其实可以取负值的。当我们将 a 取值为-1的时候,可以达到只选取前 b 个元素的目的。

示例:选中前3个元素

<div>
    <p>1</p>
    <p>2</p>
    <p>3</p>
    <p>4</p>
    <p>5</p>
</div>
p:nth-child(-n+3){
    color: red;
}

选取前3个元素

另外,选取基数和偶数元素时,可以通过指定值为oddeven来完成,这和2n+12n效果是一样的。

css 选偶数元素 p:nth-child(2n){ color: red; } /*或者*/ p:nth-child(even){ color: red; }

css 选基数元素 p:nth-child(2n+1){ color: red; } /*或者*/ p:nth-child(odd){ color: red; }

https://css-tricks.com/useful-nth-child-recipies/

需要注意的地方

与 class 的搭配

博主在使用过程中刚好遇到一个问题,可以拿出来分享一下。
那就是 nth 系列对元素的类名是不生效的,也就是说它只对标签名起作用,如果你使用时指定为 class 名则不会生效。

譬如考察下面的 HTML 片段与 CSS:

<div>
    <p>1</p>
    <p class="foo">2</p>
    <p class="foo">3</p>
    <p class="foo">4</p>
    <p class="foo">5</p>
</div>
/*从带 class 为'foo'的 p 标签中选取第2个将字体设为红色*/
p.foo:nth-of-type(2){
    color: red;
}
/*从带 class 为'foo'的 p 标签中选取第3个将字体设为绿色*/
p.foo:nth-child(3){
    color: green;
}

上述 CSS 中,我们只希望对带 class 且值为foo<p>标签进行操作,于是使用了类选择器进行限制,但最终结果其实是这样的:

我们预期值为3的应该为红色,因为它是带 class 且值为foo这种类型里面的第二个,但其实值为2的 <p>标签被选中了。因为第一个不带 class 的 <p> 标签其实也参与了进来,证明 class 选择器其实没有生效,并没有起到限制的作用。

对于:nth-child同理。

推而广之,其实对于其他嵌套 CSS 语法组合(arbitrary selector),譬如属性选择[type=text]:nth-child:nth-of-type 都是会忽略的。

对于:nth-child,纳入考量的永远是同属同一个父容器下同一级所有的兄弟元素。而对于:nth-of-type来说,则是同一父容器下,同一级所有兄弟元素中标签类型相同的元素。

与 querySelector 的搭配

既然是伪类选择器,所以就无法使用 querySelector 来进行选择。我想你已经读出另外一层意思,即所有伪类选择器在 querySelector 中都不起作用,而不只是 nth 系列。原因见W3C Spec

浏览器兼容性

:nth-child 为例,nth 系列的浏览器支持情况还是蛮理想的。可以放心使用。

来自 MDN 关于 nth-child 的浏览器兼容性表格

更多资料

目录
相关文章
|
2月前
|
前端开发
CSS:高级选择器
CSS:高级选择器
36 1
|
2月前
|
前端开发 JavaScript
CSS:基础选择器
CSS:基础选择器
46 1
|
10天前
|
前端开发 JavaScript UED
深入理解与应用 CSS 伪类选择器
【10月更文挑战第23天】通过以上对 CSS 伪类选择器的深入探讨,我们可以更好地理解和应用它们,为网页设计和开发带来更丰富、更灵活的样式效果。同时,要注意在实际应用中根据具体情况合理选择和使用伪类选择器,以达到最佳的设计效果和用户体验。
26 2
|
29天前
CSS3 新增伪类有那些
CSS3 引入了多种新伪类,增强了样式控制的灵活性。新增的结构伪类如 `:nth-child(n)` 和 `:first-of-type` 可以根据元素的位置和类型进行选择;状态伪类如 `:enabled` 和 `:checked` 则根据元素的状态进行选择;动态伪类如 `:hover` 和 `:active` 则基于用户的交互行为。这些伪类让样式定制更加多样和强大。
|
2月前
|
前端开发 JavaScript 容器
谁动了我的选择器?深入理解CSS选择器优先级
该文章详细解释了CSS选择器的工作原理,包括不同种类选择器的权重计算规则,并通过实例说明了如何解决样式冲突问题,确保所需的样式能够正确应用到目标元素上。
|
2月前
|
前端开发
前端基础(四)_CSS层叠样式表_什么是css_css样式的引入方式_样式表的优先级_样式选择器
本文详细介绍了CSS(层叠样式表)的基本概念、语法规则、引入方式、样式表的优先级和样式选择器。文章解释了CSS的作用,展示了如何在HTML中通过行内样式、内部样式和外部样式引入CSS,讨论了不同CSS选择器的优先级和如何确定最终的样式应用。此外,还强调了使用`!important`规则时的优先级高于行内样式。
80 1
|
25天前
|
前端开发
运用CSS伪类与属性,巧妙实现背景图片旋转效果
运用CSS伪类与属性,巧妙实现背景图片旋转效果
22 0
|
1月前
|
前端开发
CSS常见的选择器
CSS常见的选择器
17 0
|
2月前
|
前端开发 JavaScript
【CSS】选择器
【CSS】选择器
|
3月前
|
前端开发
CSS3选择器
【8月更文挑战第23天】CSS3选择器。
32 1