:first-child 选中了什么
如题,在学习:first-child伪类的时候,我使用如下语法,但是产生的结果在预料之外。
codepen链接
html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS选择器学习</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>CSS选择器学习示例</h1>
<p class="highlight">这是一个带有 class="highlight" 的段落。</p>
<p id="unique">这是一个带有 id="unique" 的段落。</p>
<p>这是一个普通的段落。</p>
<p>这是另一个普通的段落。</p>
<div>
<p>这是 `div` 内部的段落。</p>
</div>
<input type="text" placeholder="输入一些文字">
<button>点击我</button>
</body>
</html>
css
body :first-child{
background-color: red
}
按照:first-child语法,body :first-child选中的应该是body的第一个子元素,也就是
<h1>CSS选择器学习示例</h1>
结果选中了这个元素
<div>
<p>这是 `div` 内部的段落。</p>
</div>
网上搜索无果,所以来这里提问了,body :first-child的选择逻辑是什么?
首先我非常不建议你写这种容易引起歧义的选择器,要么你就把通配符写全
body *:first-child
。否则非常容易看岔了,body :first-child
和body:first-child
就差一个空格,但含义完全不同。其次你理解的“选中的应该是 body 的第一个子元素”,是对的。那么为什么没选中 h1 呢?我们 F12 看一下网页源码:
看到了吗?h1 并不是 body 的第一个子元素,在它前面被 WebIDE 插入了其他元素。
你把这坨都删掉就能看到效果了。
最后,
body *
只要求*
是body
的后代(Descendant),但并未要求是子元素(Child)、即一级后代。因此那个 p 既是 body 的后代,同时它也是其父元素的第一个子元素,因此body *:first-child
选择器会匹配到它。