浅析 nth-child(n) 和 nth-of-type(n)

首先看一个例子

<div>
  <p>第一个段落</p>
  <p>第二个段落</p>
</div>

p:nth-child(2) {
   background: red;
}
p:nth-of-type(2) {
  background: yellow;
}

分别执行两段 css, 发现效果是一样的,如下:

但是如果文档的结构变得更加复杂呢?看下面一个例子:

<body>
  <h1>这是标题</h1>
  <p>这是副标题</p>
  <div>
    <p>第一个段落。</p>
    <p>第二个段落。</p>
    <p>第三个段落。</p>
    <p>第四个段落。</p>
  </div>
  <p>这是注释</p>
  <p>Internet Explorer 不支持 :nth-child() 选择器。</p>
</body>
p:nth-child(2) {
  background: red;
}
p:nth-of-type(3) {
  background: yellow;
}

 此时的样式应该是怎样的呢?效果如下:

平时开发中对于 nth-child(n)和 nth-of-type(n) 常用在一些需要单独渲染的列表元素的选取上面,因为结构单一,所以不难区分,久而久之就容易对两者的用法产生混淆,虽然概念和用法都比较简单,但是一些教程和文档上面的描述比较绕,理解起来比较困难,所以这里针对上面的例子,通过集合的方式来简单的辨析一下两种元素选取方式的区别。

ele:nth-child(n)

选取父元素的第 N 个子元素,不论元素的类型。n 可以是数字(从 1 开始),关键词(even/odd),或者公式(3n + 1, 2n + 1...)

元素的选取方式和过程:

  1. 选取 ele 的父元素的所有一级子元素 => 集合 P(不分类型,若有多个 ele,则分别选取,最终生成多个集合)
  2. 在集合 P 中选取第 n 个,判断类型是否为 ele,若是,则返回元素,否则返回空

针对上例子,首先选取 p 元素的父元素的所有一级元素,形成集合,因为有多个 p 元素,所以要分别选取,最终形成两个子元素集合

body 下的所有子元素集合 P

[
  <h1>这是标题</h1>,
  <p>这是副标题</p>,
  <div>...</div>,
  <p>这是注释</p>,
  <p>Internet Explorer 不支持 :nth-child() 选择器。</p>,
]

div 下的所有子元素结合 K

[
  <p>第一个段落。</p>,
  <p>第二个段落。</p>,
  <p>第三个段落。</p>,
  <p>第四个段落。</p>,
]

在 P 中选取第 2 个元素 ——> 判断元素类型是否为 p ——> 是 ——> 返回此元素 

<p>这是副标题</p>

在 K 中选取第二个子元素 ——> 判断元素类型是否为 p ——> 是 ——> 返回此元素

<p>第二个段落。</p>

 

ele:nth-of-type(n)

选取父元素的第 N 个类型为 ele 的子元素。

  1. 选取父元素的所有类型为 ele 的子元素 => 集合 N
  2. 选取这些子元素集合 N 中的第 n 个,并返回

第一步生成集合 M 和 N

[
  <p>第一个段落。</p>,
  <p>第二个段落。</p>,
  <p>第三个段落。</p>,
  <p>第四个段落。</p>,
]
[
  <p>这是副标题</p>,
  <p>这是注释</p>,
  <p>Internet Explorer 不支持 :nth-child() 选择器。</p>,
]

然后分别选取 M 和 N 中的第三项,返回:

<p>第三个段落。</p>
<p>Internet Explorer 不支持 :nth-child() 选择器。</p>

简单总结来说,nth-child(n) 可以理解为先无条件选择子元素,后选择对应序号的元素并判断类型是否符合

nth-of-type(n) 则是先根据类型选择子元素,然后直接选择对应序号的元素即可。

 

参考:https://juejin.im/post/59bce23c51882519777c5eb5

http://www.w3school.com.cn/cssref/selector_nth-child.asp

 

posted @ 2017-09-19 13:38  淳安梁朝伟  阅读(1923)  评论(0编辑  收藏  举报