Skip to main content

选择器

名词概念

  • xxx 内的所有元素:等价于 xxx 的所有后代元素
  • 后代元素:元素内部的所有元素都是它的后代元素
  • 子元素:元素内部嵌套的第一层级的元素就是它的子元素
  • 同胞元素:和当前元素同级别的元素就是它的同胞元素

基础选择器(4个)

选择器别名例子说明
tag标签选择器p选择所有的 <p> 元素
#idID选择器#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选择所有的 pdivh1 元素/
elem.class交集选择器p.intro选择 p 标签中 class='intro' 的元素3
.class1.class2/看下面的 Tips//

Tips:

这里要注意下面两个选择器的区别:

  • .test1.test2,表示同时具有 test1test2 类名的元素
  • .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-childul > li:first-child选中 ul 里面首个 li 标签17
:last-childul > 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,并且除了数字还可以是 oddeven2n+12n3n...
  • 关于 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='#']选中 .wraphref 属性为 # 的所有后代元素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 元素内文本的首行
::selectionp::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