选择器
名词概念
- xxx 内的所有元素:等价于 xxx 的所有后代元素
 - 后代元素:元素内部的所有元素都是它的后代元素
 - 子元素:元素内部嵌套的第一层级的元素就是它的子元素
 - 同胞元素:和当前元素同级别的元素就是它的同胞元素
 
基础选择器(4个)
| 选择器 | 别名 | 例子 | 说明 | 
|---|---|---|---|
tag | 标签选择器 | p | 选择所有的 <p> 元素 | 
#id | ID选择器 | #content | 选择 id 为 content 的元素 | 
.class | 类选择器 | .wrap | 选择类名为 .wrap 的元素 | 
* | 通配选择器 | * | 选择所有的元素 | 
层次选择器(4个)
<div class="wrap">
  <p>1</p>
  <div>
    <p>2</p>
    <div>6</div>
  </div>
  <p>3</p>
  <p>4</p>
</div>
<p>5</p>
<p>7</p>
| 选择器 | 别名 | 例子 | 说明 | 被选中行 | 
|---|---|---|---|---|
elemP elemC | 后代选择器 | .wrap p | 选择类名为 .wrap 的元素内所有的 <p> 标签 | 2,4,7,8 | 
elemP>elemC | 子代选择器 | .wrap > div | 选择类名为 .wrap 的元素内所有的 div 子元素 | 3 | 
elem1+elem2 | 相邻同胞选择器 | .wrap + p | 选择 .wrap 后面的 紧挨着 的首个同胞 p 元素 | 10 | 
elem1~elem2 | 通用同胞选择器 | .wrap ~ p | 选择 .wrap 后面的所有同胞 p 元素 | 10,11 | 
important
这里要注意一下相邻同胞选择器,相邻顾名思义需要元素紧挨着,如果在第 9 行和第 10 行再插入一个别的元素,那么 .wrap + p 就选不了内容为 5 的 p 元素了,因为此时它和 .wrap 已经不相邻。
集合选择器(3个)
<div class='wrap'>
  <h1>hello</h1>
  <p class='intro'>123</p>
</div>
| 选择器 | 别名 | 例子 | 说明 | 被选中行 | 
|---|---|---|---|---|
elem1,elem2 | 并集选择器 | p, div, h1 | 选择所有的 p、div、h1 元素 | / | 
elem.class | 交集选择器 | p.intro | 选择 p 标签中 class='intro' 的元素 | 3 | 
.class1.class2 | / | 看下面的 Tips | / | / | 
Tips:
这里要注意下面两个选择器的区别:
.test1.test2,表示同时具有test1和test2类名的元素.test1 .test2,表示test1元素内部所有类名为test2的子代元素一个元素的类名可以有多个,使用空格划分:
<div class='test1 test2 test3'>123</div>这个
div具有三个类名,我们分别可以使用.test1/.test2/.test1.test2... 这些选择器选中它。
结构选择器
<div class="wrap">
  <div class="intro">
    <p>hello world</p>
    123
  </div>
  <p>DwD is a bear.</p>
  <div>
    <p>today i am so happy</p>
    <p>because i ate a banana</p>
  </div>
  <div>bad apple</div>
  <ul>
    <li>li1</li>
    <li>li2</li>
    <li>li3</li>
    <li>li4</li>
  </ul>
</div>
| 选择器 | 例子 | 说明 | 被选中行 | 
|---|---|---|---|
:root | / | 选中的就是 <html> 标签 | / | 
:empty | / | 选中所有没有子元素的元素(包括单闭合元素) | / | 
:nth-child(n) | ul > li:nth-child(2) | 选中 ul 里面顺序第二个 li 标签 | 18 | 
:nth-last-child(n) | ul > li:nth-child(2) | 选中 ul 里面逆序第二个 li 标签 | 19 | 
:first-child | ul > li:first-child | 选中 ul 里面首个 li 标签 | 17 | 
:last-child | ul > li:last-child | 选中 ul 里面最后一个 li 标签 | 20 | 
:only-child | / | 父元素仅有该元素的元素,具体看下面的 Tips | / | 
:nth-of-type(n) | .wrap > div:nth-of-type(3) | 选中 .wrap 中第三个类型为 div 的元素 | 14 | 
:nth-last-of-type(n) | / | 和上面逆序 | / | 
:first-of-type | / | / | / | 
:last-of-type | / | / | / | 
:only-of-type | / | 父元素仅有该标签的标签,具体看下面的 Tips | / | 
Tips:
- 结构选择器前面有些需要加上其他选择器有些不用,但是一定要记住一点,就是结构选择器前面加上的选择器表示在父级元素内部选择的子代元素,其会结合 后代选择器 或者 子代选择器 使用,比如
 ul > li:nth-child(2)表示的就是ul内部的所有li元素子代,并且该元素是所有子代元素中的第二个元素。n的最小值可以取 0,但是第一个元素的n=1,并且除了数字还可以是odd、even、2n+1、2n、3n...- 关于
 nth-of-type(n)和nth-child(n)的区别,前者是通过 tag 名称排序,后者是通过所有子元素排序。:only-child可能不是很好理解它的作用,可以看下面这个例子:<ul>
<li>1</li>
</ul>当
ul里面只有一个元素的时候,我们可以使用ul > li:only-child获取这个li,对其添加特定样式,如果增加了li标签数量,那么样式就会失效。
- 关于
 :only-of-type的用法,它指的父元素内部它这种类型的元素仅有一个时就会被选中,看下面的例子:<div>
<h1>test</h1>
<p>1</p>
<p>2</p>
</div>此时
div > p:only-of-type不会选中任何元素。<div>
<h1>test</h1>
<p>1</p>
</div>此时
div > p:only-of-type可以选中第 3 行的元素。
属性选择器
属性选择器的作用主要是通过 html 标签属性的 key-value 来匹配元素,属性的 value 一定是个字符串,所以属性选择器利用了 匹配字符串的相关机制 ( 正则 ) 来选择元素。
我们先来复习几个正则表达式规则:
| 规则 | 说明 | 
|---|---|
* | 前面的子表达式出现 0 次或多次,比如 zoo* 能匹配 z | 
^ | 以输入的字符开头 | 
$ | 以输入的字符结尾 | 
| | | 指明两项之间的一个选择 | 
<div class="wrap">
  <ul>
    <li>
      <a href="#">123</a>
    </li>
    
    <li>
      <a href="https://www.baidu.com">baidu</a>
    </li>
    
    <li>
      <button data-mybutton="button">click</button>
    </li>
  </ul>
</div>
| 选择器 | 例子 | 说明 | 被选中行 | 
|---|---|---|---|
[attr] | .wrap [href] | 选中 .wrap 中具有 href 属性的所有后代元素 | 4,8 | 
[attr=val] | .wrap [href='#'] | 选中 .wrap 中 href 属性为 # 的所有后代元素 | 4 | 
[attr*=val] | .wrap [href*='https'] | 选中 href 取值具有 https 子串的元素 | 8 | 
[attr^=val] | / | 选择 attr 属性的值以 val 开头(包括 val)的元素 | / | 
[attr$=val] | / | 选择 attr 属性的值以 val 结尾(包括 val)的元素 | / | 
[attr~=val] | / | 选择 attr 属性的值以空格 spilt 后返回的列表中的其中一个,详见 Tips | / | 
[attr\|=val] | / | 选择 attr 属性的值以 "-" split 后返回的列表中的其中一个,详见 Tips | / | 
Tips:
- 关于
 [attr ~= val]的使用:<div class='test1 test2'>123</div>我们可以使用
[class ~= 'test1']来选中它
- 关于
 [attr |= val]的使用:<div class='test1-test2'>123</div>我们可以使用
[class |= 'test2']来选中它
- 自定义属性,我们可以在任何标签中使用
 data-xxx来自定义一个属性<button data-mybutton="button">click</button>这样就可以通过
[data-mybutton='button']来获取这个元素了
伪元素
| 选择器 | 例子 | 说明 | 
|---|---|---|
::before | 见 Tips | 在元素前插入的内容 | 
::after | 见 Tips | 在元素后插入的内容 | 
::first-letter | .wrap > div.intro::first-letter | 选中 .wrap 内类名为 intro 的 div 子元素内文本首个字符 | 
::first-line |  .wrap > div.intro + div::first-line | 选中 .wrap 内类名为 intro 的 div 子元素的后面紧挨着的第一个 div 元素内文本的首行 | 
::selection | p::selection | 给鼠标选中的p标签内的文本添加样式 | 
Tips:
- 关于
 ::first-letter和::first-line都是文本选中,不需要关心标签嵌套什么的,只要看文本是否是第一个字母,是否属于第一行就行了。另外这两个伪元素 只能用于块级元素。elem::after / elem::before需要知道的内容:
- 可以使用
 content属性向elem的前 / 后插入内容content的取值必须为字符串,我们也可以使用attr(key)函数来获取标签传入的属性值- 插入的内容默认为
 inline,我们可以通过dispaly: block修改- 插入的内容会作为
 elem的首个/最后一个位置的元素- 只有一小部分CSS属性可以用于
 ::selection选择器:
条件选择器
| 选择器 | 说明 | 
|---|---|
:lang() | 指定标记语言的元素 | 
:is() | 指定条件的元素 | 
:not() | 非指定条件的元素 | 
:lang() 的基本用法如下:
// 选中所有具有 lang="en" 属性的 p 元素
p:lang("en") {
  color: red;
}
:is() 的基本用法如下:
/* 选择header, main, footer里的任意一个鼠标悬浮状态的段落(p标签) */
:is(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}
/* 以上内容相当于以下内容 */
header p:hover,
main p:hover,
footer p:hover {
  color: red;
  cursor: pointer;
}
:not() 的基本用法:
.fancy {
  text-shadow: 2px 2px 3px gold;
}
/* 类名不是 `.fancy` 的 <p> 元素 */
p:not(.fancy) {
  color: green;
}
/* 非 <p> 元素 */
body :not(p) {
  text-decoration: underline;
}
/* 既不是 <div> 也不是 <span> 的元素 */
body :not(div):not(span) {
  font-weight: bold;
}
// 上面等价于
/* 注意,此语法尚未获广泛支持。 */
body :not(div, span) {
  font-weight: bold;
}
行为选择器
| 选择器 | 说明 | 
|---|---|
:active | 鼠标激活的元素 | 
:hover | 鼠标悬浮的元素 | 
:active 一般用于 a 标签和 button 标签。
状态选择器
| 选择器 | 说明 | 版本 | 
|---|---|---|
:target | 当前锚点的元素 | 3 | 
:link | 未访问的链接元素 | 1 | 
:visited | 已访问的链接元素 | 1 | 
:focus | 输入聚焦的表单元素 | 2 | 
:required | 输入必填的表单元素 | 3 | 
:valid | 输入合法的表单元素 | 3 | 
:invalid | 输入非法的表单元素 | 3 | 
:in-range | 输入范围以内的表单元素 | 3 | 
:out-of-range | 输入范围以外的表单元素 | 3 | 
:checked | 选项选中的表单元素 | 3 | 
:optional | 选项可选的表单元素 | 3 | 
:enabled | 事件启用的表单元素 | 3 | 
:disabled | 事件禁用的表单元素 | 3 | 
:read-only | 只读的表单元素 | 3 | 
:read-write | 可读可写的表单元素 | 3 | 
:target-within | 内部锚点元素处于激活状态的元素 | 4 | 
:focus-within | 内部表单元素处于聚焦状态的元素 | 4 | 
:focus-visible | 输入聚焦的表单元素 | 4 | 
:blank | 输入为空的表单元素 | 4 | 
:user-invalid | 输入合法的表单元素 | 4 | 
:indeterminate | 选项未定的表单元素 | 4 | 
:placeholder-shown | 占位显示的表单元素 | 4 | 
:current() | 浏览中的元素 | 4 | 
:past() | 已浏览的元素 | 4 | 
:future() | 未浏览的元素 | 4 | 
:playing | 开始播放的媒体元素 | 4 | 
:paused | 暂停播放的媒体元素 | 4 | 
| 选择器 | 说明 | 版本 | 
|---|---|---|
:link | ||
:hover | ||
:active | ||
:focus | ||
:visited |