关于 css 伪类选择器:nth-child(n)
这几天面试在一个简单的问题上翻车了。
问题大概是这样,问我哪个部分被标红
天真的我回答的是 p 元素 。
答案当然是没有任何元素被标红,原因是 nth-child 会先找到所有父元素下第 n 个子元素,再找其中的 p,
也就是它第一步找到的集合是两个 span,其中没有 p 元素。
如果要标红那个 p,须要这么写选择器:
p:nth-of-type(1)
这样是 先选择父元素下的 p,再找到其中的第一个 p。
但是
故事到这里并没有完结,我尝试去选择嵌套 p 标签下的 p 标签
令人震惊的是没有任何元素被选中,
尝试了 p > p :nth-child(1)
也没有元素被选中p:nth-of-type(1)
也不能选择到元素。
只有这样才能成功选择到 p1 。
在这里我已经想到可能是违背了 HTML 标准之类的东西,但 p 是块状元素,不知道为什么不能嵌套另外一个 p 呢?所以去 mozilla 查看一下。看到了
每一个 HTML 元素都必须遵循定义了它可以包含哪一类内容的规则。 这些规则被归类为几个常见的元素内容模型(content model)。每个 HTML 元素都属于 0 个、1 个或多个内容模型,每个模型都有一些规则使得元素中的内容必须遵循一个 HTML 规范文档( HTML-conformant document)。
其中关于 p 元素的定义
描述是 p 元素表示文本的一个段落,重点是允许的内容是 Phrasing content,再看这个 Phrasing content。
其中不包含 p 标签,所以我认为是 nth-child
选择器 按照 HTML 规范进行了选择上的优化,所以不会在 p 元素下面再去找 p 元素了,吗?
我们再看一下这个结构
在浏览器是怎么渲染的
可以看到,外面包裹的 p,被浏览器渲染成了两个 p 元素。可以猜想到,如果 CSS 写成
1 | p { |
span2 也不会被选择中的。
所以最后的总结就是,HTML 代码不规范会使浏览器做出错误的渲染,所以选择器选择出现问题 。