文章目录
- 前言
- 元素选择器
- 类选择器
- ID选择器
- 属性选择器
- 简单属性选择器
- 属性值完全匹配选择器
- 属性值部分匹配选择器
- 属性值包含字符串选择器
- 属性值匹配起始字符串选择器
- 属性值匹配结尾字符串选择器
- 属性值匹配连字符字符串选择器
- 结构选择器
- 后代选择器
- 直接后代选择器
- 兄弟选择器
- 相邻兄弟选择器
- 伪类选择器
- 结构伪类
- :root
- :empty
- :only-child
- :only-of-type
- :first-child
- :last-child
- :first-of-type
- :last-of-type
- :nth-child(an±b)
- :nth-last-child(an±b)
- :nth-of-type(an±b)
- :nth-last-of-type(an±b)
- 动态伪类
- :link
- :visited
- :focus
- :hover
- :active
- UI状态伪类
- :enabled
- :disabled
- :checked
- :indeterminate
- :default
- :valid
- :invalid
- :in-range
- :out-of-range
- :required
- :optional
- :read-write
- :read-only
- 目标伪类
- :target
- 语言伪类
- :lang(xx)
- 否定伪类
- :not(element)
- 伪元素选择器
- ::before
- ::after
- ::first-letter
- ::first-line
- 群组选择器
- 通用选择器
前言
CSS
之所以强大,很大一部分原因都要归结于它的选择器,非常丰富,特别灵活。
本文不讲选择器的机制和原理,只对选择器进行汇总,把经常使用的列举出来,作为工具类文章,方便日后参考和查阅。
元素选择器
匹配文档中同一类型的所有元素。
/* 匹配文档根元素 */
body {font-size: 20px;
}/* 匹配文档中所有的<div>元素 */
div {border: solid 1px red;
}
类选择器
元素必须要有class
属性,属性值可以有多个,其中一个或多个属性值能和选择器匹配即可。
/* 匹配class属性值含有"info"的任意元素 */
.info {border: solid 1px red;
}/* 匹配class属性值含有"info"的<div>元素 */
div.info {font-size: 24px;
}/* 匹配class属性值含有"photo"和"image"的任意元素,属性值顺序不重要 */
.image.photo {width: 100px;height: 100px;
}
ID选择器
元素必须要有id
属性。
/* 匹配id属性值为"content"的任意元素 */
#content {border: solid 1px red;
}/* 匹配id属性值为"content"的<div>元素 */
div#footer {border: solid 1px red;
}
属性选择器
简单属性选择器
元素声明了某个属性即可,不用关心属性值是什么。
/* 匹配具有title属性的任意元素 */
[title] {color: red;
}/* 匹配具有title属性的<a>元素 */
a[title] {color: green;
}
属性值完全匹配选择器
元素具有某个属性,且属性值完全相等。
/* 匹配具有title属性,且属性值为"content"的任意元素 */
[title="content"] {border: solid 1px red;
}/* 匹配具有title属性,且属性值为"content"的<a>元素 */
a[title="content"] {border: solid 1px red;
}
属性值部分匹配选择器
针对可以设置多个值(空格分隔)的属性,其中一个属性值能匹配即可。
/* 匹配具有title属性,且属性值含有"any"的任意元素 */
[title~="any"] {border: solid 1px red;
}/* 匹配具有title属性,且属性值含有"any"的<a>元素 */
a[title~="any"] {border: solid 1px red;
}
属性值包含字符串选择器
属性值字符串包含某个子串。
/* 匹配title属性值包含"part"子串的任意元素 */
[title*="part"] {border: solid 1px red;
}/* 匹配title属性值包含"part"子串的<a>元素 */
a[title*="part"] {border: solid 1px red;
}
属性值匹配起始字符串选择器
属性值以某个字符串开始。
/* 匹配title属性值以"start"字符串开始的任意元素 */
[title^="start"] {color: green;
}/* 匹配title属性值以"start"字符串开始的<a>元素 */
a[title^="start"] {color: green;
}
属性值匹配结尾字符串选择器
属性值以某个字符串结尾。
/* 匹配title属性值以"end"字符串结尾的任意元素 */
[title$="end"] {color: green;
}/* 匹配title属性值以"end"字符串结尾的<a>元素 */
a[title$="end"] {color: green;
}
属性值匹配连字符字符串选择器
指定一个字符串string
,属性值等于string
或者以string-
开头,就能匹配。
/* 匹配lang属性值等于"zh"或者以"zh-"开头的任意元素 */
[lang|="zh"] {color: green;
}/* 匹配lang属性值等于"zh"或者以"zh-"开头的<html>元素 */
html[lang|="zh"] {color: green;
}
结构选择器
后代选择器
匹配指定元素的后代子元素,子元素在第几层级都可以。
/* 匹配<div id="app">元素的后代<span>元素 */
div#app span {border: solid 1px red;
}
直接后代选择器
匹配指定元素的直接后代子元素,子元素必须是第一代后代。
/* 匹配<div id="app">元素的直接后代<span>元素,元素<span>必须是第一代元素 */
div#app > span {border: solid 1px red;
}
兄弟选择器
同一层级所有元素都能以兄弟相称,但在这里,只能以某一元素为基准,匹配后面的兄弟,不匹配前面的兄弟。
/* 匹配<div id="app">元素后面的兄弟<p>元素,这些<p>元素和<div>之间可以有其它元素 */
div#app ~ p {border: solid 1px red;
}
相邻兄弟选择器
同一层级所有元素都能以兄弟相称,但在这里,只能以某一元素为基准,匹配紧随其后的第一个兄弟,忽略其它兄弟。
/* 匹配紧跟在<div id="app">元素后面的兄弟<p>元素,最多只会匹配到一个<p>元素,且<div>和<p>之间不能有其它元素 */
div#app + p {border: solid 1px red;
}
伪类选择器
结构伪类
:root
匹配文档根元素,在HTML
文档中根元素就是<html>
元素,所以和html
元素选择器效果是一样的。
/* 匹配文档根元素 */
:root {font-size: 24px
}
:empty
匹配空元素,空元素是指不包含任何东西(可见内容、后代元素、空白字符)的元素,注释不算。自闭合元素<img>、<input>
等也算空元素,没有内容的<textarea>
也算空元素。
/* 匹配任意空元素 */
:empty {border: solid 1px red;
}/* 匹配空的<p>元素 */
p:empty {display: none;
}
:only-child
匹配元素是其父元素的唯一后代元素,也就是说它没有兄弟元素,但是可以有自己的子元素。
/* 匹配具有"唯一后代元素身份"的任意元素 */
:only-child {border: solid 1px red;
}/* 匹配具有"唯一后代元素身份"的<p>元素 */
p:only-child {border: solid 1px red;
}
:only-of-type
匹配同级兄弟元素中,元素类型只有一个实例的元素。
/* 匹配同级兄弟元素中,元素类型实例唯一的任意元素 */
:only-of-type {border: solid 1px red;
}/* 匹配同级兄弟元素中,唯一的段落<p>元素,如果有多于一个的<p>元素,那么所有<p>元素就都不能匹配 */
p:only-of-type {border: solid 1px red;
}/* 注意!对这个选择器的理解很容易出错!!! */
/* 错误理解:匹配同级兄弟元素中唯一具有class属性值含有"unique"的<p>元素 */
/* 正确理解:匹配同级兄弟元素中唯一的段落<p>元素,并且该元素还要满足class属性值含有"unique"的要求 */
p.unique:only-of-type {color: green;
}
:first-child
当一个元素是其父元素的第一个直接后代元素时,匹配该元素。
/* 匹配具有"第一个直接后代元素身份"的任意元素 */
:first-child {border: solid 1px red;
}/* 匹配具有"第一个直接后代元素身份"的<h1>元素 */
h1:first-child {border: solid 1px red;
}
:last-child
当一个元素是其父元素的最后一个直接后代元素时,匹配该元素。
/* 匹配具有"最后一个直接后代元素身份"的任意元素 */
:last-child {border: solid 1px red;
}/* 匹配具有"最后一个直接后代元素身份"的<h1>元素 */
h1:first-child {border: solid 1px red;
}
:first-of-type
同级兄弟元素中,根据元素类型分组,匹配每组第一个元素。
/* 匹配同级兄弟元素中,每个元素类型分组中的第一个实例元素 */
:first-of-type {border: solid 1px red;
}/* 匹配同级兄弟元素中,<p>元素分组中的第一个<p>元素 */
p:first-of-type {border: solid 1px red;
}
:last-of-type
同级兄弟元素中,根据元素类型分组,匹配每组最后一个元素。
/* 匹配同级兄弟元素中,每个元素类型分组中的最后一个实例元素 */
:last-of-type {border: solid 1px red;
}/* 匹配同级兄弟元素中,<p>元素分组中的最后一个<p>元素 */
p:last-of-type {border: solid 1px red;
}
:nth-child(an±b)
同级兄弟元素中,从前往后,匹配第an±b
位置的元素,元素位置从1
开始向后计数。
/* 匹配同级兄弟元素中,正着数,第2、5、8、11、...位置的任意元素 */
:nth-child(3n+2) {border: solid 1px red;
}/* 匹配同级兄弟元素中,正着数,第4、8、12、16、...位置的<p>元素 */
p:nth-child(4n) {border: solid 1px red;
}/* 关键字even等价于表达式2n,偶数 */
p:nth-child(even) {border: solid 1px red;
}/* 关键字odd等价于表达式2n+1,奇数 */
p:nth-child(odd) {border: solid 1px red;
}
:nth-last-child(an±b)
同级兄弟元素中,从后往前,匹配第an±b
位置的元素,元素位置从1
开始向前计数。
/* 匹配同级兄弟元素中,倒着数,第2、5、8、11、...位置的任意元素 */
:nth-last-child(3n+2) {border: solid 1px red;
}/* 匹配同级兄弟元素中,倒着数,第4、8、12、16、...位置的<p>元素 */
p:nth-last-child(4n) {border: solid 1px red;
}/* 关键字even等价于表达式2n,偶数 */
p:nth-last-child(even) {border: solid 1px red;
}/* 关键字odd等价于表达式2n+1,奇数 */
p:nth-last-child(odd) {border: solid 1px red;
}
:nth-of-type(an±b)
同级兄弟元素中,按元素类型分组,从前往后,匹配每组第an±b
位置的元素,每组元素都从1
开始向后计数。
/* 同级兄弟元素,按元素类型分组,正着数,匹配每组第2、5、8、11、...位置的任意元素 */
:nth-of-type(3n+2) {border: solid 1px red;
}/* 同级兄弟元素,按元素类型分组,正着数,匹配<p>元素分组中的第4、8、12、16、...位置的<p>元素 */
p:nth-of-type(4n) {border: solid 1px red;
}/* 关键字even等价于表达式2n,偶数 */
p:nth-of-type(even) {border: solid 1px red;
}/* 关键字odd等价于表达式2n+1,奇数 */
p:nth-of-type(odd) {border: solid 1px red;
}
:nth-last-of-type(an±b)
同级兄弟元素中,按元素类型分组,从后往前,匹配每组倒数第an±b
位置的元素,每组元素都从1
开始向前计数。
/* 同级兄弟元素,按元素类型分组,倒着数,匹配每组第2、5、8、11、...位置的任意元素 */
:nth-last-of-type(3n+2) {border: solid 1px red;
}/* 同级兄弟元素,按元素类型分组,倒着数,匹配<p>元素分组中的第4、8、12、16、...位置的<p>元素 */
p:nth-last-of-type(4n) {border: solid 1px red;
}/* 关键字even等价于表达式2n,偶数 */
p:nth-last-of-type(even) {border: solid 1px red;
}/* 关键字odd等价于表达式2n+1,奇数 */
p:nth-last-of-type(odd) {border: solid 1px red;
}
动态伪类
动态伪类选择器,关注的是当前页面的变化,页面处于某种状态中样式才会生效,和鼠标的动作有很大关系。
其它选择器,关注的是元素结构及位置变化,文档渲染完成后,样式就会立即生效。
:link
适用:超链接<a>
元素。
匹配具有href
属性,且该属性指向资源未被访问(浏览器历史记录中找不到)的<a>
元素。
/* 匹配具有href属性,且指向资源未被访问过的<a>元素 */
:link {color: red;
}/* 效果同上,因为这个伪类只适用于<a>元素 */
a:link {color: red;
}
:visited
适用:超链接<a>
元素。
匹配具有href
属性,且该属性指向资源已被访问(浏览器历史记录中能找到)的<a>
元素。
课外知识:已访问链接的隐私保护。
/* 匹配具有href属性,且指向资源已被访问过的<a>元素 */
:visited {color: red;
}/* 效果同上,因为这个伪类只适用于<a>元素 */
a:visited {color: red;
}
:focus
适用:具有交互效果的元素。例如:超链接、表单控件、可编辑内容的元素。
当鼠标在页面上的最后一次点击操作,作用在交互元素上,这个元素就获取到了焦点。
/* 匹配获得了页面焦点的任意元素 */
:focus {color: red;
}/* 匹配获得了页面焦点的<a>元素 */
a:focus {color: red;
}/* 匹配获得了页面焦点的<input>元素 */
input:focus {color: red;
}
:hover
适用:具有交互效果的元素。例如:超链接、表单控件、可编辑内容的元素。
鼠标指针悬停在交互元素上。
/* 匹配鼠标指针放置其上的任意元素 */
:focus {color: red;
}/* 匹配鼠标指针放置其上的<a>元素 */
a:focus {color: red;
}/* 匹配鼠标指针放置其上的<input>元素 */
input:focus {color: red;
}
:active
适用:具有交互效果的元素。例如:超链接、表单控件、可编辑内容的元素。
鼠标指针作用于元素上,指针按下去还未松开的那段时间内。
/* 匹配鼠标指针按下去的那段时间内,正处于点击状态的任意元素 */
:focus {color: red;
}/* 匹配鼠标指针按下去的那段时间内,正处于点击状态的<a>元素 */
a:focus {color: red;
}/* 匹配鼠标指针按下去的那段时间内,正处于点击状态的<input>元素 */
input:focus {color: red;
}
UI状态伪类
这种选择器关注的是页面UI
元素的各种状态。
:enabled
适用:具有交互效果的元素。
和元素的disabled
属性有关,超链接和href
属性有关。元素可用,处于非禁用状态。
/* 匹配当前可用元素,元素没有disabled属性,超链接有href属性 */
:enabled {color: red;
}/* 匹配当前可用的<a>元素,有href属性 */
a:enabled {color: red;
}/* 匹配当前可用的<input>元素,没有disabled属性 */
input:enabled {color: red;
}
:disabled
适用:具有交互效果的元素。
和元素的disabled
属性有关,超链接和href
属性有关。元素不可用,处于禁用状态。
/* 匹配当前不可用元素,元素有disabled属性,超链接没有href属性 */
:enabled {color: red;
}/* 匹配当前不可用的<a>元素,没有href属性 */
a:enabled {color: red;
}/* 匹配当前不可用的<input>元素,有disabled属性 */
input:enabled {color: red;
}
:checked
适用:具有选中和未选中状态的交互元素。
和元素的checked
属性有关,被选中的复选框、单选按钮、下拉菜单项。
/* 匹配当前处于选中状态的元素,元素有checked属性 */
:checked {background-color: red;
}/* 匹配当前处于选中状态的单选框,元素有checked属性 */
input[type="radio"]:checked {outline: solid 3px red;
}/* 匹配当前处于打开状态的下拉菜单项 */
select:checked {color: red;
}
:indeterminate
适用:元素状态处于既未选中也没有未选中的交互元素。
这个状态只能有DOM
脚本能设置,在浏览器中也就是JavaScript
脚本,用户无法从页面上设定。很少用,仅作了解。
/* 具有相同name属性值的同组单选框<input>元素,如果都没有标记checked属性时,就处于"既未选中也没有未选中"状态 */
input[type="radio"]:indeterminate + label {background: lime;
}
:default
适用:具有交互效果的元素。
在文档中默认就被选中的元素,有checked
属性,后续在页面上切换其选中状态也不影响该效果。
/* 匹配默认选中,具有checked属性的任意元素 */
:default {outline: solid 1px red;
}/* 匹配默认选中,具有checked属性的单选框元素 */
input[type="radio"]:default {outline: solid 1px red;
}
:valid
适用:能校验用户输入数据有效性的表单输入框。
匹配用户输入数据校验通过的输入框元素。
/* 用户在输入框中输入数据,通过校验,就匹配该元素 */
:valid {border: solid 1px green;
}/* 当有<input type="email" />元素时,用户不输入或者输入数据满足邮箱格式,就匹配该元素 */
input[type="email"]:valid {border: solid 1px green;
}/* 当有<input type="text" pattern="[a-z]+" />元素时,用户不输入或者输入数据满足正则,就匹配该元素 */
input[type="text"]:valid {border: solid 1px green;
}
:invalid
适用:能校验用户输入数据有效性的表单输入框。
匹配用户输入数据校验不通过的输入框元素。
/* 用户在输入框中输入数据,校验不通过,就匹配该元素 */
:valid {border: solid 1px green;
}/* 当有<input type="email" />元素时,用户输入数据不满足邮箱格式,就匹配该元素 */
input[type="email"]:valid {border: solid 1px red;
}/* 当有<input type="text" pattern="[a-z]+" />元素时,用户输入数据不满足正则,就匹配该元素 */
input[type="text"]:valid {border: solid 1px red;
}
:in-range
适用:有min
和max
属性的元素。
匹配用户输入数据在最小值和最大值之间的元素。
/* 当有<input type="number" min="1" max="10" />元素时,输入10,就能匹配该元素 */
input[type="number"]:in-range {color: red;
}
:out-of-range
适用:有min
和max
属性的元素。
匹配用户输入数据不在最小值和最大值之间的元素。
/* 当有<input type="number" min="1" max="10" />元素时,输入11,就能匹配该元素 */
input[type="number"]:in-range {color: red;
}
:required
适用:表单控件。
和元素的required
属性有关,匹配必填表单元素。
/* 匹配必填的表单元素 */
:required {border: solid 1px red;
}/* 匹配必填的<input>元素 */
input:required {border: solid 1px red;
}
:optional
适用:表单控件。
和元素的required
属性有关,匹配非必填表单元素。
/* 匹配非必填的表单元素 */
:optional {border: solid 1px red;
}/* 匹配非必填的<input>元素 */
input:optional {border: solid 1px red;
}
:read-write
适用:可读可写的元素。
匹配可读可写的元素,表单元素和disabled
属性有关,元素div
如果有属性contenteditable="true"
也可以匹配到。
/* 匹配可读可写的元素 */
:read-write {background-color: yellow;
}/* 匹配可读可写的<input>元素 */
input:read-write {background-color: yellow;
}/* 匹配有contenteditable="true"属性值的<div>元素 */
div:read-write {background-color: yellow;
}
:read-only
适用:只读元素,就是那些不可编辑内容的元素。
匹配可读不可写的元素,表单元素和disabled
属性有关。
/* 匹配只读元素 */
:read-only {background-color: yellow;
}/* 匹配只读的<input>元素,设置了disabled属性 */
input:read-only {background-color: yellow;
}
目标伪类
:target
适用:所有元素。
跟浏览器地址栏URL
中的片段标识符#fragment
有关系,它所指向的文档片段在CSS
中叫做目标(target
),打开URL
对应的页面,如果有某个<div>
元素的id
属性和target
相等,就会匹配这个元素。
/* 比如URL:http://localhost:8080/index.html#content */
/* 在index.html页面有个<div id="content">元素,就匹配这个<div>元素 */
:target {background-color: yellow;
}/* 特别指定,URL中的片段标识符,只能匹配div类型的元素 */
div:target {background-color: yellow;
}
语言伪类
:lang(xx)
适用:具有语言编码信息lang
属性的任意元素。
匹配属性值等于lang="xx"
,或者属性值开始于lang="xx-"
的元素。和|=
属性选择器作用相同,但是两者略有区别:
- 对
|=
属性选择器来说,元素自身必须有lang
属性才能匹配 - 而
:lang
伪类能匹配有lang
属性的元素及其所有的后代元素
所以多数情况下,:lang
伪类选择器更具有实用性。
/* 匹配属性值为lang="en"或者lang="en-XX"的元素及其后代元素 */
:lang(en) {border: solid 1px red;
}/* 匹配有lang="en"或lang="en-XX"属性值,或者能从父代元素继承lang属性的<p>元素及其后代元素 */
/* 比如有<html lang="en">的父代元素存在,就能匹配到<p>元素及其后代元素 */
p:lang(en) {border: solid 1px red;
}
否定伪类
:not(element)
适用:任意元素,参数element
代表CSS
简单选择器(元素选择器、类选择器、ID
选择器、属性选择器、伪类选择器)。
前面讲的都是表达肯定意义的选择器,匹配应该选择的元素。否定伪类刚好反过来,表达否定意义的选择器,即匹配不应该选择的那些元素。
/* 匹配没有class="info"的所有元素 */
:not(.info) {color: red;
}/* 匹配没有class="info"的<p>元素 */
p:not(.info) {color: red;
}
伪元素选择器
伪元素和伪类很像,为了实现特定效果,它在文档中插入虚构的元素:
CSS2
定义了四个基本伪元素,之后的规范又定义了其它伪元素(暂不讨论)- 伪元素只能出现在选择器最后,类似
p::first-line em
是无效的 - 目前,一个选择器中只能有一个伪元素
::before
适用:所有元素。
在所选元素的前面添加一个伪元素,该伪元素默认为内联元素,可用display
属性修改。
/* 在所有元素前面添加点内容:++ */
::before {content: "++";color: silver;
}/* 在<h2>元素前面加上++符号,content表示伪元素内容,其余样式都是作用于伪元素上的 */
h2::before {content: "++";color: silver;
}
::after
适用:所有元素。
在所选元素的后面添加一个伪元素,该伪元素默认为内联元素,可用display
属性修改。
/* 在所有元素后面添加点内容:++ */
::before {content: "++";color: silver;
}/* 在<h2>元素后面加上++符号,content表示伪元素内容,其余样式都是作用于伪元素上的 */
h2::before {content: "++";color: silver;
}
::first-letter
适用:块级元素,元素display
取值block、inline-block、list-item、table-cell、table-caption
。
为所选元素的内容首字符添加样式,首字符前面如果有标点符号,一并算在首字符之内。注意,可以使用的CSS
属性有限。
/* 所有元素的内容首字符字体颜色统一为红色 */
::first-letter {color: red;
}/* 所有<p>元素的内容首字符字体颜色统一为红色 */
p::first-letter {color: red;
}
::first-line
适用:块级元素,元素display
取值block、inline-block、list-item、table-cell、table-caption
。
为所选元素的内容首行添加样式,首字符前面如果有标点符号,一并算在首字符之内。注意,可以使用的CSS
属性有限。
/* 所有元素的内容首行字体颜色统一为红色 */
::first-line {color: red;
}/* 所有<p>元素的内容首行字体颜色统一为红色 */
p::first-letter {color: red;
}
群组选择器
适用:任意CSS
选择器,用逗号,
分隔多个选择器
如果多个元素具有相同的样式,或者有部分相同样式,想将相同样式抽出来仅写一遍,或许就可以用上这个选择器。
严格意义上讲,这不算是一种新的选择器,它更像是CSS
语言提供的语法糖,最大的好处就是精简抽象CSS
代码。
/* 用逗号分隔两个元素选择器,这两个选择器有相同的color样式 */
h2, p {color: gray;
}/* 等价于分开写,缺点就是相同的color样式要写两遍 */
h2 {color: gray;
}
p{color: gray;
}
通用选择器
在HTML
文档中,这个选择符不常用,因为它的作用范围太大,并且性能最低,仅做了解。
/* 使用*号代表任意元素,设置任意元素字体大小为24px */
* {font-size: 24px;
}