CSS 选择器(二)
上一篇的三种选择器只能选”单个类型”的元素,这一篇的选择器能表达元素之间的关系,选得更精确。内容包括组合器、属性选择器、伪类和伪元素。
组合器
组合器通过空格和符号,把多个简单选择器串起来,表达元素之间的位置关系。一共四种。
/* 后代选择器,空格,选中 .card 内部所有的 p,不管嵌套多深 */
.card p { color: #555; }
/* 子代选择器,大于号,只选中 .card 的直接子元素 p,孙子不管 */
.card > p { color: #555; }
/* 相邻兄弟选择器,加号,选中紧跟在 h2 后面的第一个 p */
h2 + p { font-size: 18px; }
/* 通用兄弟选择器,波浪号,选中 h2 之后所有的 p */
h2 ~ p { color: #999; }
后代和子代最容易混,记住一句,空格管所有后代,大于号只管亲生儿子。兄弟选择器用得少,但做标题和首段的联动效果时很顺手。
属性选择器
属性选择器按元素的属性来选,用方括号包住条件。
/* 有 href 属性的元素 */
a[href] { color: #2980b9; }
/* href 精确等于某个值 */
a[href="https://example.com"] { color: red; }
/* href 以指定开头,外链识别 */
a[href^="https://"] { font-weight: bold; }
/* href 以指定结尾,下载链接识别 */
a[href$=".pdf"] { color: #c0392b; }
/* href 包含指定字符 */
a[href*="blog"] { font-style: italic; }
四个符号分别对应存在、精确、开头、结尾、包含,[]、=、^=、$=、*=,一共五种写法,在表格类数据和表单校验的样式里很常用。
伪类
伪类以单冒号开头,选中处于特定状态的元素,而不是某个具体的标签或类。比如鼠标悬停的链接、被选中的输入框、父元素下的第一个孩子。
a:hover { color: #e67e22; }
input:focus { border-color: #3498db; }
li:first-child { font-weight: bold; }
:hover、:focus、:first-child、:nth-child 这几个是入门必会的。完整的伪类清单很长,按位置、交互、表单状态分了好几类,详见CSS 伪类那篇速查手册。
伪元素
伪元素以双冒号开头,它选中的不是元素,而是元素内部的一块区域,或者一个虚拟的位置。最常用的是 ::before 和 ::after,它们能在元素内容的前面和后面插入一个虚拟盒子。
<p class="tip">记得保存文件</p>
.tip::before {
content: "⚠ ";
color: #e67e22;
}
.tip::after {
content: "";
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
background: #27ae60;
}
注意两个细节。content 属性是必须的,哪怕内容是空字符串,没有它伪元素不会显示。伪元素默认是行内元素,想让它有宽高,记得改 display。除了 before 和 after,还有 ::first-line 选中首行、::first-letter 选中首字母,场景比较小众。
伪类和伪元素怎么区分
一句话,伪类表示状态,伪元素表示部分。单冒号还是双冒号,历史上有一段混乱期。CSS2 时代伪元素用单冒号,CSS3 统一改成双冒号,现代浏览器两种写法都支持,但 ::before 这种双冒号写法是官方推荐,新代码统一用双冒号。
小结
这一篇的选择器各有分工,组合器表达关系,属性选择器匹配属性,伪类管状态,伪元素管部分。连同上一篇的标签、类、ID,选择器的版图就完整了。下一篇进入 CSS 最核心也最烧脑的概念,层叠与优先级,搞清楚多条规则打架时谁说了算。