likes
comments
collection
share

容易被误用的 nth-of-type 伪类

作者站长头像
站长
· 阅读数 19

我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第3篇文章,点击查看活动详情

单独讲这个伪类,是因为它很容易被新手错误地用于选择第 n 个拥有某类名的元素,但实际上是无法做到这一点的,例如下面的列表页面:

容易被误用的 nth-of-type 伪类

其 HTML 结构为:

<dl class="product-list">
  <dt class="name">番茄</dt>
  <dd class="price">价格3元/斤</dd>
  <dd class="quantity">库存50斤</dd>

  <dt class="name">黄瓜</dt>
  <dd class="price">价格2元/斤</dd>
  <dd class="quantity">库存100斤</dd>

  <dt class="name">苹果</dt>
  <dd class="price">价格6元/斤</dd>
  <dd class="quantity">库存30斤</dd>

  <dt class="name">西瓜</dt>
  <dd class="price">价格2元/斤</dd>
  <dd class="quantity">库存500斤</dd>
</dl>

初始样式为:

.product-list {
  width: 300px;
  height: 300px;
  border: 1px solid #ccc;
  margin: 50px auto;
  padding: 10px;
}

dt {
  font-weight: bold;
}

dd {
  color: gray;
}

假如现在的需求是:把第二个商品的价格为红色,库存为蓝色,也就是下面的效果:

容易被误用的 nth-of-type 伪类

当然你可以给第二个商品添加额外的类名以示区分,如果不增加新的类名,而是借助 nth-type-of 伪类的话,可能会写出如下的 CSS 代码:

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

.quantity:nth-of-type(2) {
  color: blue;
}

但是上面的代码不起任何的作用,这也是很多新手容易误用的原因,因为:

  • nth-of-type 选择器的第 n 个元素,不是根据选类名(例如price或quantity)而是类型(dd)来计算的!

所以 .price:nth-of-type(2) { color: red; } 这行代码的意思是:如果某个元素拥有 price 类,且是其兄弟节点中第二个拥有 dd 类型的元素,那么就选中它并把颜色设置成红色,并非我们想象的第二个具有 .price 类名的元素,而是第二个 .price 类名对应 DOM 元素节点类型,也就是 dd 的元素!

很明显,没有任何元素会被选中,自然没有任何效果,正确的写法应该是:

dd:nth-of-type(3) {
  color: red;
}

dd:nth-of-type(4) {
  color: blue;
}

分别设置第 3 个和第 4 个 dd 类型的元素,但是这样的代码非常脆弱,假如我们给第一个商品再增加一条内容为:产地山东,那么选择的元素就会乱掉:

容易被误用的 nth-of-type 伪类

所以比较严谨的写法是:

dt:nth-of-type(2) + dd {
  color: red;
}

dt:nth-of-type(2) + dd + dd {
  color: blue;
}

这样只会选择第二个商品 dt 元素后面紧跟的两个 dd,第一个设置成红色,第二个设置成蓝色,这样就达到我们想要的效果了。

不过话说回来,虽然这个伪类容易被误用,但其功能还是很强大的,如果用得好,会让视觉更加层次分明。例如给标题的奇偶行分别添加不同的背景颜色,让每一个区块看起来更加清晰:

容易被误用的 nth-of-type 伪类

代码非常简单:

dt:nth-of-type(odd) {
  background-color: gold;
}

dt:nth-of-type(even) {
  background-color: cyan;
}