<p>考察下面的 HTML 代码片段:</p>
<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个!它们分别是:

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

特别适合于规律性重复的样式当中。譬如我司对于默认头像的处理,将9个主题色值进行今次循环使用。



五彩斑斓的头像

: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效果是一样的。

选偶数元素

p:nth-child(2n){
color: red;
}
/*或者*/
p:nth-child(even){
color: red;
}

选基数元素

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>标签进行操作,于是使用了类选择器进行限制,但最终结果其实是这样的:



class 的搭配

我们预期值为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 的浏览器兼容性表格

更多资料

CSS3 nth 伪类选择器的更多相关文章

  1. CSS3 结构伪类选择器 详解

    1 CSS3 结构伪类选择器 1.E:root 匹配E元素所在的根元素 即:html 2. E:nth-child(n) (1)匹配E元素的父元素中第n个子元素,(2)且该位置的子元素类型必须是E类型 ...

  2. Atitit.隔行换色  变色 css3 结构性伪类选择器

    Atitit.隔行换色  变色 css3 结构性伪类选择器 1.1. css3隔行换色扩展阅读 1 1.2. 结构伪选择器 1 1.3. jQuery 选择器2 1.1. css3隔行换色扩展阅读 原 ...

  3. CSS3 :nth-child()伪类选择器

    CSS3 :nth-child()伪类选择器 CSS3的强大,让人惊叹,人们在惊喜之余,又不得不为其艰难的道路感到可惜:好 的标准只有得到行业浏览器的良好支持才算得上“标准”.CSS3标 准已提出数年 ...

  4. CSS3 结构性伪类选择器(2)

    CSS3 结构性伪类选择器—first-child “:first-child”选择器表示的是选择父元素的第一个子元素的元素E.简单点理解就是选择元素中的第一个子元素,记住是子元素,而不是后代元素. ...

  5. CSS3 结构性伪类选择器(1)

    1.CSS3 结构性伪类选择器—root :root选择器就是匹配元素E所在文档的根元素.在HTML文档中,根元素始终是<html>. “:root”选择器等同于<html>元 ...

  6. (转)CSS3:nth-child()伪类选择器,奇偶数行自定义样式first-child

    原文地址 Table表格奇偶数行定义样式: CSS3的强大,让人惊叹,人们在惊喜之余,又不得不为其艰难的道路感到可惜:好的标准只有得到行业浏览器的良好支持才算得上“标准”.CSS3标 准已提出数年,但 ...

  7. CSS3:nth-child()伪类选择器,Table表格奇偶数行定义样式

    转自爱设计 原文链接http://www.dangshopex.com/jishufenxiang/WEBkaifajishu/8653.html CSS3的强大,让人惊叹,人们在惊喜之余,又不得不为 ...

  8. css3 结构性伪类选择器

    伪类 选择器 类型 说明 备注 E:first-line 伪元素选择器 选择匹配E元素内的第一行文本 E:first-letter 伪元素选择器 选择匹配E元素内的第一个字符 E:before 伪元素 ...

  9. css3 - 语言伪类选择器

    <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...

随机推荐

  1. Apache Ignite高性能分布式网格框架-初探

    Apache Ignite初步认识 今年4月开始倒腾openfire,过程中经历了许多,更学到了许多.特别是在集群方面有了很多的认识,真正开始认识到集群的概念及应用方法. 在openfire中使用的集 ...

  2. 解决PHP-问题:Class 'SimpleXMLElement' not found in

    1.问题 在ubuntu 16.10中,学习PHP,学习到PHP如何生成XML文件时候,碰到了这个问题: PHP Fatal error: Class 'ClassName\SimpleXMLElem ...

  3. scrapy爬虫docker部署

    spider_docker 接我上篇博客,为爬虫引用创建container,包括的模块:scrapy, mongo, celery, rabbitmq,连接https://github.com/Liu ...

  4. 【转】39个让你受益的HTML5教程

    闲话少说,本文作者为大家收集了网上学习HTML5的资源,期望它们可以帮助大家更好地学习HTML5. 好人啊! 不过,作者原来说的40个只有39个,因为第5个和第8个是重复的. 原文在此! 1. 五分钟 ...

  5. 微软发布VSBT,无需安装Visual Studio即可实现项目编译

    安装了Visual Studio的那些使用微软平台的开发者通常能够非常容易地操作自己的项目:打开解决方案,修改内容,设置好所有必须的文件以及配置后编译项目.但是在构建服务器或者持续交付系统等没有安装V ...

  6. JAVA面试题

    在这里我将收录我面试过程中遇到的一些好玩的面试题目 第一个面试题:ABC问题,有三个线程,工作的内容分别是打印出"A""B""C",需要做的 ...

  7. arcgis api for js入门开发系列四地图查询(含源代码)

    备注:由于实现本篇功能的需求,修改了地图数据的dlsearch.mxd,然后更新了地图服务,需要的在文章最后有提供最新的mxd以及源代码下载的 上一篇实现了demo的地图工具栏,本篇新增地图查询功能, ...

  8. RMS Server打开或关闭日志记录

    原文: https://technet.microsoft.com/zh-cn/library/cc732758 在 Active Directory Rights Management Servic ...

  9. 【转】组件化的Web王国

    本文由 埃姆杰 翻译.未经许可,禁止转载!英文出处:Future Insights. 内容提要 使用许多独立组件构建应用程序的想法并不新鲜.Web Component的出现,是重新回顾基于组件的应用程 ...

  10. linux下 lvm 磁盘扩容

    打算给系统装一个oracle,发现磁盘空间不足.在安装系统的时候我选择的是自动分区,系统就会自动以LVM的方式分区.为了保证系统后期的可用性,建议所有新系统安装都采用LVM,之后生产上的设备我也打算这 ...