选择器
当你看过内部样式和外部样式的写法, 不可避免会牵扯到选择器这个概念.
考虑一个点, 为什么要把CSS和HTML分离, 而不是统一使用内联样式写在标签上? 为什么要这样做, 有哪些优点, 或者缺点?
接下来我们开始详细分析各种选择器. 看能不能从中找到答案?
- 元素选择器(集合):
div跳过 - 类选择器(集合):
.children跳过 - ID选择器(单个元素):
#xiaoming跳过 - 通配符选择器(所有):
*为通配符选择器, 选中所有元素, 即样式对所有元素生效
组合选择器(两个以上的选择器的组合)
逗号分隔: 表示全选, 比如这里color样式会应用于所有的h2和p
h2,p {
color: gray;
}
空格分隔: 表示进一步筛选, 这里选中的是在本篇HTML中所有的div内部的所有的p, 最终选中的是p标签, 但有一个前提条件: p标签外得有div标签
div p {
color: gray;
}
注意父子包含关系: (无论多深都会选中)
<div>
<p>选中</p>
</div>
<div>
<h1>
<p>选中</p>
</h1>
</div>
<p>未选中</P>
无空格分隔: div p 如果去掉空格, 就变成了divp, 这样的会被识别为一个叫divp的标签, 这样的标签在HTML中明显是不存在的, 所以没有意义. 那什么时候才有有意义呢? 如下示例这样的选择器是有意义的. 这样的选择器能被CSS识别为两个类选择器.children,.girl, 但是中间没有空格: 这样会选中的是class同时包含.children,.girl的元素
.children.girl {
color: green;
}
<div class="children girl" >选中</div>
<div class="girl children" >选中</div>
<div class="girl" >未选中</div>
<div class="children" >未选中</div>
以上距离都是两个选择器的组合, 但是三个四个N个都是同理.
属性选择器
简单属性选择器: [xxx]只要标签包含指定的这个属性就会被选中
// (1) 这里其实是一个组合选择器: h1 和 [class] 两个选择器的 无空格组合
h1[class] {
color: silver;
}
// (2) 这里是 a、[href]、[title] 三个选择器的 无空格组合
a[href][title] {
font-weight: bold;
}
<h1>(1)未选中</h1>
<h1 class>(1)选中</h1>
<h1 class="name">(1)选中</h1>
<a>(2)未选中</a>
<a hlef>(2)未选中</a>
<a title>(2)未选中</a>
<a href title>(2)选中</a>
<a href title style>(2)选中</a>
<a href="/" title="小明">(2)选中</a>
基于属性的值进一步筛选的属性选择器
这里给了选中和未选中示例, 尽量模拟了一些边界情况, 可以对比看更容易理解.
| 类型 | 描述 | 选中属性 | 未选中属性 |
|---|---|---|---|
[foo~="bar"] | 所有带有foo属性、且foo属性的值严格等于bar的元素 | foo="bar" | foo="barr" |
[foo~="bar"] | 选择所有带有foo属性、且foo属性被空白分隔的单词列表中含有单词bar的元素。 | foo="bar"、foo="bar xxx" | foo="barr" |
[foo*="bar"] | 选择所有带有foo属性、且foo属性值中含有子串bar的元素。 | foo="bar"、foo="barr"、foo="abarr" | foo="bxar" |
[foo^="bar"] | 选择所有带有foo属性、且foo属性值以bar开头的元素(严格意义的开头)。 | foo="bar"、foo="barr" | foo="abar"、foo="xxx bar" |
[foo$="bar"] | 选择所有带有foo属性、且foo属性值以bar结束的元素(严格意义的结尾)。 | foo="bar"、foo="abar" | foo="barr"、foo="bar xxx" |
[foo|="bar"] | 选择所有带有foo属性、且foo属性等于bar或以bar-开头的元素(严格意义的开头) | foo="bar"、foo="bar-x"、foo="bar-xx aa" | foo="barr-xxx"、foo="aa bar-xxx" |
衍生一下: [class~="bar"]与 .bar等同
注意一下,选择器不能以-开头或结束,-只能放在名称中间
忽略大小写标识符i
a[href$='.PDF' i]
选中所有href以.PDF且不分大小写(.pdf、.PDF、.PdF、.pDF等)结尾的a标签
选择子元素
只会选择下一级子节点, 再往下就不会选中了
h1 > strong {
color: red;
}
<h1>This is <strong>选中</strong> important.</h1>
<h1>
This is <em>really <strong>未选中</strong></em> important.
</h1>
选择相邻兄弟元素(弟弟节点) +
h1 + p {
margin-top: 0;
}
选中的是拥有共同的父节点、且和h1相邻、且是跟在h1后面的节点(最多只有一个).
思考一下为什么不能选中h1之前的兄弟节点?
选择所有的弟弟节点~
h2 ~ ol {font-style: italic;}
选中拥有共同的父节点、且在h2之后的所有ol节点(可以有很多个)
伪类选择器:``::
为了文章的尽可能的简洁和全面, 对细分具体内采取引用现有成熟文章方式进行.
总结一下伪类做了什么事情:
1. 用于指定所选元素的特殊状态
- 比如涉及键盘/鼠标行为的
:hover、:active、:focus(聚焦)、:focus-visible(通过键盘/tab等导航导致的聚焦的样式, 或通过编程聚焦的样式)、:hocus-within(当前元素或其子孙元素聚焦导致导致的样式,常用于输入框前的label)、:in-range:input输入框的数字在max和min中间、:indeterminate: 比如checkbox中间态(半选状态)、:invalid(表单验证错误)、 - 涉及
A标签的:link、:visited、:any-link; - 涉及表单控件的
:autofill、:blank、:checked、:disabled、:default(默认被选中节点)、:empty(空输入)、:enabled、:focus(聚焦)、 - 涉及到播放器
audio/video缓冲状态的:buffering; - 涉及时间维度的(WebTT、视频实时字幕)
:future(将来的、前途)、:current(当前的、现在)、:past(过去的) - 涉及到自定义控件的
:defined(用户自创建的控件、且已经定义好的) - 其他: 涉及语言排版方向的
:dir,:fullscreen:当前处于全屏的元素(只能是根节点、且全屏),:host,
2. 关系查找选择器
通过<current-selector>:伪类-->选择其他节点元素
:last-child:current-selector是否为父元素最后一个子节点:first-child: 同上, 第一个子节点:nth-child(): (函数式的下面讲):last-of-type: 相对于last-child有两点区别, 可以指定元素的类型通过current-selector, 这样的话查找只能往上一级查找, 所有以parent-selector.:firt-of-type:同上, 第一个节点:nth-of-child():(函数式的下面讲):nth-last-of-type:(函数式的下面讲)
3. 函数式伪类
函数式伪类主要用于逻辑筛选. <current-selector>:函数名(<relative-selector-list>), 其中current-selector可为空(这时候相当于*,整篇文档), 作用是: 在parent-selector元素内, 找到符合函数名(<relative-selector-list>)的节点并应用样式.
:has(): 能否在current-selector找到至少一个符合relative-selector-list元素。当current-selector不存在则全局搜索,最后结果是选中的是current-selector或没选中。:host(): 用于在自定义元素、Shadow DOM的根节点设置样式,:host可无条件选择根节点。:host-context(): 用于定义自定义元素、Shadow DOM的内部元素(根节点的后代节点)的样式,传入根节点的后代节点选择器,选中的是后代节点。:is(): 又称为:any()/:matches():传入一个,分隔的选择器列表,内部元素能在列表中找到既被选中。:lang(): 语言选择器:传入语言如en-US,符合即选中current-selector。:not(): 用于选择不符合指定选择器的元素。传入一个选择器,选中所有不匹配该选择器的元素。:nth-child(): 用于选择父元素下的特定子元素。接受一个参数,可以是数字、关键字(如odd或even)或公式(如2n+1)。:nth-of-type(): 类似于:nth-child(),但只考虑同类型的元素。选择父元素下特定类型的子元素。:nth-last-of-type(): 与:nth-of-type()相似,但从父元素的最后一个子元素开始计数,选择特定类型的子元素。:state(): 用于表示元素的状态,通常用于用户交互的状态(如:hover、:focus等)。注意,state并不是标准的CSS伪类。where(): 类似于:is(),但具有更高的优先级。用于选择符合指定选择器列表的元素,但不会影响其他选择器的优先级。