假设我们有以下 HTML 代码
<section>
<p>Little</p>
<p>Piggy</p> <!-- We want this one -->
</section>
它们将执行完全相同的事情
p:nth-child(2) { color: red; }
p:nth-of-type(2) { color: red; }
当然,它们之间还是有区别的。
上面的 :nth-child
选择器,用“白话文”来说,意味着如果满足以下条件,则选择一个元素:
- 它是段落元素
- 它是父元素的第二个子元素
上面的 :nth-of-type
选择器,用“白话文”来说,意味着
- 选择父元素的第二个段落子元素
:nth-of-type
是… 怎样才能说清楚呢… 条件较少 。
假设我们的标记更改为以下内容
<section>
<h1>Words</h1>
<p>Little</p>
<p>Piggy</p> <!-- We want this one -->
</section>
这会失效
p:nth-child(2) { color: red; } /* Now incorrect */
但这仍然有效
p:nth-of-type(2) { color: red; } /* Still works */
“失效”是指上面的 :nth-child
选择器现在选择单词“Little”,而不是“Piggy”,因为该元素满足这两个条件:1) 它是第二个子元素,2) 它是段落元素。 “仍然有效”是指“Piggy”仍然被选中,因为它是在该父元素下的第二个段落。
如果我们在 <h1>
之后添加一个 <h2>
, :nth-child 选择器 将完全不会选择任何内容 ,因为现在第二个子元素不再是段落,因此该选择器找不到任何内容。 :nth-of-type
仍然有效。
我觉得 :nth-of-type
不太容易出错,而且一般情况下更有用,尽管 :nth-child
更为常见(在我看来)。 你觉得有多少次会想“我想选择父元素的第二个子元素,只要它恰好是一个段落”。 也许有时候会,但更有可能的是你想“选择第二个段落”或“选择每个第三个表格行”,在这些情况下 :nth-of-type
是(在我看来)更强大的选择。
我发现我大部分的“ 糟糕,为什么这个 :nth-child 选择器不起作用?!” 时刻都是因为我最终用标签限定了选择器,而该数字子元素实际上并不是那个标签。 因此,在使用 :nth-child
时,我发现通常最好是指定父元素,并将 :nth-child
保持为非标签限定的。
dl :nth-child(2) { } /* is better than */
dd:nth-child(2) { } /* this */
但是,当然,这完全取决于具体情况。
对 :nth-of-type
的浏览器支持相当不错… Firefox 3.5+、Opera 9.5+、Chrome 2+、Safari 3.1+、IE 9+。
我本来想说,如果你需要更深层的支持,jQuery 可以帮上忙(在那里使用选择器,应用一个类,然后用该类进行样式设置),但事实上 jQuery 放弃了对 :nth-of-type 的支持。 我觉得很奇怪。 我听说这是因为使用率低。 如果你想走这条路, 这里有一个插件可以帮你找回来 。 jQuery 1.9 现在再次支持 :nth-of-type
(回到 IE 6),所以这也是一个选择。
相关内容:不要忘记很棒的兄弟姐妹 :first-of-type
、 :last-of-type
、 :nth-last-of-type
和 :only-of-type
。 在此了解更多信息。
如果你想玩一个视觉示例, 查看这个工具!
说到这里,:last-child 也可以使用…
很棒的解释。 信不信由你,我今天才遇到这个问题,而且还纠结了一个小时!
我也必须说,这种行为令人困惑!
如果你想在悬停时应用 CSS,你会添加
p:hover {}
因此,如果你想对每个第 n 个 p 应用 CSS,你会使用
p:nth-child(2)
当然,情况并非如此。
没错,它有点古怪,并不总是与自然假设一致。
我现在真的需要检查几十张样式表 ><
说句公道话,我同意你的看法,nth-of-type 确实很有用。
为了确保它与官方不支持的浏览器兼容:这是强大的 selectivzr 的职责。
哎呀! 链接里有个小错误。 试试 http://selectivizr.com/ 。
Selectivizr 实际上是由 Keith Clark 开发的,他也开发了 Chris 在帖子中链接的 jquery 插件,所以我猜 Selectivizr 可能更新了。
上周我实际上遇到了这个问题。 我花了一个小时才意识到我应该使用 :north-of-type。
直到现在我还没弄明白为什么是这样的 :)
好文章。 我认为大多数时候你会想要使用 nth-of-type 而不是 nth-child。
然而,nth-child 确实有用的一种情况是,你想要选择第 n 个元素,而不关心元素的类型。 例如:
.some-parent :nth-child(n)
然后,它里面是 span、div 还是其他任何元素都不重要,你始终会得到第 n 个元素。
是的,这是技术上的用例,但现实中的用例是什么? 我敢肯定这里和那里有一些,但并不常见。
实际用例可能有限,但可以预测——例如使用 tin 突出显示特定表格行或列… 或者某些列表项。 在这些情况下,你可以确定 tr 保持为 tr,或者 li 保持为 li,因此 nth-child 成为一个选择。 但正如你提到的,nth-of-type 也能正常工作。
真的太棒了,Chris。 感谢你的建议。
清澈如水晶! 感谢你提供如此精彩的示例和描述!
非常有用。 我把它打印出来放进了我的随机“代码片段”文件夹中。 非常感谢。
有 :first-child
有 :first-of-type 吗?
只是好奇,既然有 :first-child
有 :first-of-type 吗?
只是好奇 ^^
Julian,没有,
First-of-type 不适用,该属性在 css3 中没有更新
抱歉… 关于前一篇文章…
http://reference.sitepoint.com/css/pseudoclass-firstoftype
看看这个,你会找到解决方案。
jQuery 放弃 nth-of-type 真可惜。 最近,我发现自己经常使用它来减少在标记中使用的类数。 使用 nth-of-type 可以轻松地微调要定位的元素。 希望他们能尽快恢复它,一旦人们意识到它是多么强大的工具。
我对 nth-of-child 的段落要求感到好奇。 昨天我使用 nth-child 来设置以下标记的样式
因此,例如,我使用 #company li:nth-child(2) 来指定“注册”按钮。 在 FF 和 Safari 中效果很好,我还没有进行其他测试,只是一些粗略的编辑模型…
我的理解是 nth-child 对任何子元素都有效,无论元素类型如何。 我错过了什么?
谢谢!
本文中只是以段落为例。 在你的示例中,你使用了 li:nth-child(2),因此该选择器只会在第二个子元素是列表项时进行选择。 如果第二个子元素是任何其他元素,它将不会匹配。
酷,明白了。 并且只想感谢你创建了这个很棒的资源。 每周肯定要来这里几次,研究如何做这个或那个…
谁能解释一下“为什么”决定 nth-child 不应该忽略 display:none 元素?
CHRIS,感谢你的帮助!我快疯了,因为我听了你的一个播客(3 月 13 日的“Sass 数学和 Mixin 的快速实用案例”),然后我在方括号前加了一个引号,一切都乱了套……这真是帮了大忙!