CSS3学习之选择器

本文标题虽然取了 CSS3学习之选择器 ,但不会只说CSS3新增的选择器;除了CSS3新增选择器外,还会将自己不熟悉的选择器都介绍和测试一下

目前在CSS中一共定义了52种选择器。

基本选择器

选择器 说明 CSS
.class 类选择器,选择带有指定类名的元素 1
#id ID选择器 1
* 通配符选择器,选择所有元素,也可以选择某元素下的所有元素 2
E 元素选择器,其实就是文档的元素,如html,body,p,div等 1
E,F 群组选择器,对一组选择器应用相同的样式 1

层次选择器

选择器 说明 CSS
E F 后代选择器,F不管是E的子元素还是孙元素还是更深层次的关系,都将被选中 1
E>F 子元素选择器,只选择子元素,不包括孙子元素或更深层次的元素 2
E+F 相邻兄弟元素选择器,选择紧跟在E后面的F元素,且它们具有共同父元素 2
E~F 通用兄弟选择器,选择E元素后面的所有F兄弟元素,E和F属于同一父元素之内,且F元素在E元素之后 3

属性选择器

选择器 说明 CSS
[attr] 选择所有具有目标属性的元素 2
[attr=”value”] 选择所有attr属性值等于value的元素 2
[attr~=”value”] 属性是一个词或多个词列表时使用,是词列表时多个词之间用空格分开,只要其中一个词为value即可选中该元素 2
[attr|=”value”] 特定属性选择器,选择attr属性值等于value或以value单词开头的元素,value必须是整个词,或value与后面词之间用连字符(”-“)连接 2
[attr^=”value”] 选择所有attr属性值以value子串开头的元素 3
[attr$=”value”] 选择所有attr属性值以value子串结尾的元素 3
[attr*=”value”] 选择所有attr属性值包含value子串的元素 3

伪类选择器

伪类存在的意义是为了通过选择器找到那些不存在与DOM树中的信息以及不能被常规CSS选择器获取到的信息。

任何常规选择器可以在任何位置使用伪类。伪类语法不区别大小写。一些伪类的作用会互斥,另外一些伪类可以同时被同一个元素使用。并且,为了满足用户在操作DOM时产生的DOM结构改变,伪类也可以是动态的。

动态伪类

这些伪类并不存在于HTML中,只有当用户和页面元素交互的时候才能体现出来,动态伪类包含两种,第一种是我们在链接中常看到的锚点伪类,如 :link:visited;另外一种被称作用户行为伪类,如 :hover:active:focus

选择器 说明 CSS
:active 匹配所有被激活(鼠标点击)的元素,常用于链接和按钮上 1
:focus 匹配获取焦点的元素 2
:hover 匹配鼠标停留在其上的元素 1
:link 匹配元素定义了超链接且未被访问过,常用于链接锚点上 1
:visited 匹配元素定义了超链接且已被访问过,常用于链接锚点上 1

状态伪类

本部分列举的是UI元素的状态伪类,这些主要是针对于HTML中的Form元素的,根据Form元素的状态来选择目标元素。

选择器 说明 CSS
:checked 状态伪类,选择checked状态的元素,一般用于checkbox或radio 3
:disabled 状态伪类,选择禁用状态的元素 3
:enabled 状态伪类,选择启动状态的元素 3
:optional 匹配可选的输入元素,即未设置required属性的表单元素 3
:required 匹配设置了required属性的元素 3
:valid 匹配输入值合法的元素 3
:invalid 匹配输入值非法的元素 3
:in-range 匹配输入值在指定区间内的元素,仅用于input元素 3
:out-of-range 匹配输入值在指定区间外的元素,仅用于input元素 3
:read-only 匹配只读的元素,即设置了 readonly 属性的元素,只用于input和textarea元素 3
:read-write 匹配可读写的元素,即未设置 readonly 属性的元素,只用于input和textarea元素 3

required属性是 HTML5 新增的表单元素属性,用于规定必需在提交表单之前填写的字段,表单元素中如果没有特别设置required属性即为可选的。

:optionalrequired 选择器只适用于表单元素(input、select 和 textarea)

:validinvalid 选择器只能作用于能指定区间值的元素,例如 input 元素中的 min 和 max 属性,及正确的 email 字段、合法的数字字段等

结构伪类

选择器 说明 CSS
:first-child 匹配某元素,该元素是其父元素的第一个子元素 2
:last-child 匹配某元素,该元素是其父元素的最后一个子元素 3
:nth-child() 匹配某元素的一个或多个特定子元素 3
:nth-last-child() 匹配某元素的一个或多个特定子元素,从该元素最后一个子元素开始计算 3
:nth-of-type() :nth-child() 一样,但限定了元素类型 3
:nth-last-of-type() :nth-last-child() 一样,但限定了元素类型 3
:first-of-type :first-child 一样,但是限定了元素类型 3
:last-of-type :last-child 一样,但是限定了元素类型 3
:only-child 匹配某元素,该元素是其父元素唯一的子元素 3
:only-of-type :only-child 类似,匹配某元素,该元素的父元素可以有很多子元素,但该元素是唯一一个限定类型的元素 3
:empty 匹配没有任何内容的元素,没有内容指的是一点内容都没有,哪怕是一个空格 3
:root 匹配元素的根元素,在HTML中,根元素始终是html元素 3

:nth-child

:nth-child() 选择器用来选择某个元素的一个或多个特定的子元素,它在 W3 官网上的完整定义是 :nth-child(an+b),关于这个语法有以下几点:

  • a和b的值必须是整数(正负零)
  • 子元素索引从1开始计算

:nth-child(an+b) 最基本的解释是把所有子元素按每组a个进行分组,直到不够再分时将剩下的子元素作为最后一组,然后选取每组的第b个元素。

上面的解释要求a大于0,但由于a和b都可以取正数、负数和零,实际情况比较复杂

W3 关于此选择器的解释比较繁琐,很容易令人困惑,在这采用网上常的总结来理解 :nth-child(an+b) 选择器的用法,这几种用法其实都是 an+b 的变化形式,就是a和b取不同值时的组合。

这里的“n”只能是”n”,不能使用其他字母代替,不然会没有任何效果的。

:nth-child(number)

参数为简单的正整数数字(大于0),表示匹配第 number 个子元素,这是最简单的用法。这种情况其实就是a=0,导致an部分被忽略的变体,此时表达式中只剩下b,且要求b必须大于0。

1
li:nth-child(3){background:orange;} /* 把第3个li的背景设为橙色 */

:nth-child(an)

这种情况其实是b=0时,b被忽略的变体。

匹配所有倍数为a的元素,例如3n会匹配到第3个、第6个、第9个等3的倍数个元素;其实这里会有计算过程,n的值从0开始,依次与3进行乘积运算,然后将结果放到 nth-child() 中用来匹配元素,直到乘积结果大于元素的个数。下面描述一下 :nth-child(3n) 计算过程:

1
2
3
4
5
n=0 => 3*n=0 => 匹配不到任何元素
n=1 => 3*1=3 => 匹配第3个元素
n=2 => 3*2=6 => 匹配第6个元素
n=3 => 3*3=9 => 匹配第9个元素
...

通过上面的计算过程可以了解到 an 与 an+a 效果是一样的。

另外当a=1时,该选择器又变为 :nth-child(n) ,根据上面的算法可以得知这会选择所有元素,与不加该伪类选择器一样。

:nth-child(an+b)

该用法是 :nth-child() 选择器最完整的用法,当b小于等于a时,就是把所有元素每组a个进行分组,匹配每组中的第b个元素,例如3n+2会匹配第2个、第5个、第8个等元素;当b大于a时,其效果是先匹配到第b个元素,然后将b后面的元素每组a个进行分组,匹配每组的第a个元素。

用计算步骤理解一下,:nth-child(3n+5) 的计算步骤:

1
2
3
4
5
n=0 => 3*0+5=5 => 匹配第5个元素
n=1 => 3*1+5=8 => 匹配第8个元素
n=2 => 3*2+5=11 => 匹配第11个元素
n=3 => 3*3+5=14 => 匹配第14个元素
...

当b<0时该选择器变成 :nth-child(an-b) 形式,当a=1时会变成 :nth-child(n+b) 形式,表示匹配第b个之后的元素。

:nth-child(-an+b)

由于-an的结果小于等于0,因此当b<=a时,只能匹配第b个元素;当b>a时,首先匹配到第b个元素,然后从第b个元素往前算,每组a个进行分组,匹配每组的第-a个元素(即反向第a个元素)。例如 :nth-child(-3n+8) 的计算过程:

1
2
3
4
n=0 -> -3n+8=8 -> 匹配第8个
n=1 -> -3n+8=5 -> 跳过第7个和第6个匹配到第5个
n=2 -> -3n+8=2 -> 跳过第4个和第3个匹配到第2个
n=3 -> -3n+8=-1 -> 结果开始为负值

当a=1时该选择器变成 :nth-child(-n+b) 形式,表示匹配前b个元素。

:nth-child(odd) 和 :nth-child(even)

:nth-child() 选择器还可以接受 oddeven 两个关键字作为参数:

  • :nth-child(odd):与 :nth-child(2n+1) 效果一样,匹配第奇数个元素
  • :nth-child(even):与 nth-child(2n) 效果一样,匹配第偶数个元素。

:nth-last-child

:nth-last-child() 选择器和前面的 :nth-child() 选择器很相似,只是这里多了一个last,该选择器是从最后一个元素开始算(即与 :nth-child() 选择器顺序相反),来选择特定元素,它们的算法是一样的。

例如 :nth-last-child(2n):nth-child(2n+1) 是一样的,正好相反。

:nth-of-type

:nth-of-type() 选择器与 :nth-child() 选择器类似,它们的可用参数及参数意义完全一样,不同的是 :nth-of-type() 只计算选择器中指定的那个元素,这个选择器对定位元素中包含了好多不同类型的元素是很有用处,下面用一个例子说明。

看以下HTML代码,我想将第二个p元素的文字颜色设置为红色:

1
2
3
4
5
<div class="selector-demo-1" style="border: 1px dashed green;">
<span>我是第一个span</span>
<p>我是第一个p</p>
<p>我是第二个p</p>
</div>

首先使用 p:nth-child(2) 选择器,可以看到变色的是第一个p元素,这是div的第二个子元素;也就是说,p:nth-child(2) 选择器的意思是:该元素是p元素,并且该元素是父元素的第二个子元素。

1
.selector-demo-1 p:nth-child(2) {color: red}
我是第一个span

我是第一个p

我是第二个p

接下来试一下 p:nth-of-type(2) 选择器,可以看到这次与我们的要求一样了,保证选择的是第二个p元素;也就是说,p:nth-of-type(2) 选择器的意思是:该元素是父元素的第二个p子元素,即匹配所有p元素的第二个,不考虑div下其它类型的子元素。

1
.selector-demo-2 p:nth-of-type(2) {color: red}
我是第一个span

我是第一个p

我是第二个p

参考:CSS3选择器:nth-child和:nth-of-type之间的差异

:nth-last-of-type

:nth-last-of-type() 根据名字容易理解,它与 :nth-last-child() 选择器一样,只不过是它限定了元素的类型。

其它伪类

伪类 说明 CSS
:lang(language) 匹配带有以指定值开始的 lang 属性的元素,该值必须是整个单词,即可是单独的词,如 lang=”en”,也可使用连字符(-)分隔的词如 lang=”en-us” 2
:not(selector) 匹配非指定选择器匹配到的每个元素,可以理解为取反的意思,即除了指定的元素以外所有元素 3
:target 3

伪元素

CSS1和CSS2中对伪类的伪元素的区别比较模糊,CSS3对这两个概念做了相对较清晰地区分,并且在语法上也很明显地将二者区别开。伪元素用 :: 来表示以区分伪类,CSS2中已存的伪元素仍然可以使用一个冒号 : 的语法,但是CSS3新增的伪元素必须使用两个冒号 ::

伪元素在DOM树中创建了一些抽象元素,这些抽象元素是不存在于html文档中的。比如:documen接口不提供访问元素内容的第一个字或者第一行的机制,而伪元素可以使开发者可以提取到这些信息。并且,一些伪元素可以使开发者获取到不存在于源文档中的内容(比如常见的 ::before::after)。

伪元素 说明 CSS
::after 在元素后面插入内容,配合”content”使用,例如清除浮动 2
::before 在元素前面插入内容 2
::first-letter 选择文本块的第一个字母,主要运用于段落排版上,比如首字下沉 1
::first-line 选择元素的第一行 1
::selection 用来改变浏览器网页选中文本的默认效果 3

一个选择器只能使用一个伪元素,并且伪元素必须处于选择器语句的最后。

::selection

The ::selection selector matches the portion of an element that is selected by a user.

::selection 选择器用来匹配一个元素中被用户选中的部分,并设置相应样式;只有很少的CSS属性可以使用在 ::selection 选择器 中,包括:color、background、cursor和outline。

下面是个示例:

1
2
3
4
5
6
7
8
9
.selection-demo {
border: 2px dashed green;
padding: 4px;
}
.selection-demo::selection {
background-color: red;
color: white;
cursor: help;
}
The ::selection pseudo-element was drafted for CSS Selectors Level 3, but removed before the Recommendation status. So, at the moment, the ::selection pseudo-element is not in any specification. (However, it may be re-added to future CSS specifications.)

在上面示例效果中,选中的文本会变成我们设置的样式,这就是 ::selection 伪元素的作用。

文章目录
  1. 1. 基本选择器
  2. 2. 层次选择器
  3. 3. 属性选择器
  4. 4. 伪类选择器
    1. 4.1. 动态伪类
    2. 4.2. 状态伪类
    3. 4.3. 结构伪类
      1. 4.3.1. :nth-child
        1. 4.3.1.1. :nth-child(number)
        2. 4.3.1.2. :nth-child(an)
        3. 4.3.1.3. :nth-child(an+b)
        4. 4.3.1.4. :nth-child(-an+b)
        5. 4.3.1.5. :nth-child(odd) 和 :nth-child(even)
      2. 4.3.2. :nth-last-child
      3. 4.3.3. :nth-of-type
      4. 4.3.4. :nth-last-of-type
    4. 4.4. 其它伪类
  5. 5. 伪元素
    1. 5.1. ::selection
|