1. 参考
  2. 结构
  3. 分类
    1. 元素选择器(标签选择器)
    2. class选择器
    3. id选择器
    4. 通配选择器
    5. 属性选择器
      1. [attribute]
      2. [attribute~="value"]
      3. [attribute*="value"]
      4. [attribute^="value"]
      5. [attribute$="value"]
      6. [attribute|="value"]
    6. 后代选择器
    7. 子元素选择器
    8. 相邻元素选择器
    9. 伪类选择器
      1. target
      2. :not()
    10. 伪元素选择器
      1. :first-child
      2. :last-child
      3. :nth-child(n)
      4. :nth-last-child(n)
      5. :nth-of-type(n)
      6. :nth-last-of-type(n)
      7. :first-letter
      8. :first-line
      9. :before
      10. :after
      11. :root
      12. ::selection
  4. 优先级
    1. 特殊性/优先级(specificity)
    2. !important
    3. not()

CSS选择器

参考

选择器 MDN
选择器详解 MDN
优先级 MDN
css属性选择器

结构

一个标准的CSS规则(rule)结构如下

body {
    color: yellow;
    margin: 40px;
}

其由两部分组成,选择器(selector) 和声明块(declaration block)."声明块"由许多个"声明"(declaration)组成,写在"选择器"后,被一对大括号包裹.

selector {declaration block};

声明由"属性: 值"组成,这样的结构叫"名值对"(property-value pairs),两个"声明"间用分号分隔.

{
  property1: value;
  property2: value;
}

允许多个选择器使用同一个声明块,选择器间由英文逗号分隔(,)
为div和a元素设置样式

div,
a {
  color: yellow;
}

分类

元素选择器(标签选择器)

元素选择器以元素名开头

1
htmlTag {}
1
2
3
body {
background:yellow;
}

class选择器

class选择器以英文句号(.)开头,后接元素class名.

1
.className {}

假设有以下html结构

1
2
<div class="content"><div>
<p class="content"><div>

如果想同时为div和p设置背景样式,这时可以使用class选择器

1
2
3
.content {
background: yellow;
}

id选择器

id选择器以井号开头(#),后接元素id名.

.idName {}

在html中,class可以重复,但id只能有一个.因此建议尽量多用class,少用id

正确
<div class="content"><div>
<p class="content"><div>
错误
<div id="content"><div>
<p id="content"><div>

通配选择器

通配选择器可以选择任意元素,在CSS中,用星号(*)表示通配选择器

<span>a</span>
<span>b</span>

* {background: yellow};

属性选择器

以元素名开头,后接"[html属性选择器]"

[attribute]

为所有拥有type属性的元素设置样式

<input type="text">
<input type="text">
*[type]{color: yellow};

[attribute~="value"]

选择class属性值含有name的元素,属性值必须被空格分隔

<span class="name">a</span>
<span class="name last">b</span>
<span class="namelast">没有被空格分隔,选不到</span>

span[class~="name"] {color: yellow};

[attribute*="value"]

选择class属性值含有name的元素

<span class="namelast">a</span>
<span class="name last">b</span>

span[class*="name"] {color: yellow};

[attribute^="value"]

选择class属性值以name开头的元素

<span class="name last">a</span>
<span class="namelast">b</span>
<span class=" name last">开头多了个空格,选不到</span>
<span class="last name">选不到</span>

span[class^="name"] {color: yellow};

[attribute$="value"]

选择class属性值以name结尾的元素

<span class="last name">a</span>
<span class="lastname">b</span>
<span class="last name ">结尾多了个空格,选不到</span>
<span class="namelast">选不到</span>

span[class$="name"] {color: yellow};

[attribute|="value"]

选择class属性值为en或以en-开头的元素

<span class="en-us">a</span>
<span class="en">b</span>
<span class="en cn">选不到</span>
<span class="encn">选不到</span>

span[class|="en"] {color: yellow};

可以同时使用多个属性选择器

htmlTag[][]... {}

选择class属性值为last和name的元素

<span class="last name">a</span>
<span class="last">选不到</span>

span[class~="last"][class~="name"] {
    color: yellow;
}

后代选择器

选择div元素中的所有p元素

<div>
    <span>a</span>
    <p>
        <span>b</span>
    </p>
</div>

div span {color: yellow};

子元素选择器

选择div元素中元素标签为p的子元素

<div>
    <span>a</span>
    <p>
        <span>选不到</span>
    </p>
</div>

div > span {color: yellow};

相邻元素选择器

选择紧接在元素后的另一个元素,两元素间不能有别的元素(匿名文本除外)

element + nextelement {}

选择span后的del元素

<span>a</span>
匿名文本不影响选择
<del>b</del>
<del>选不到</del>

span + del {color:yellow}

选择元素后的所有同级元素(不包括子元素)

element ~ nextelement {}

选择span元素后的所有del元素

<del>选不到</del>
<span>a</span>
<del>b</del>
<p>
    <del>非同级元素,选不到</del>
</p>
<del>b</del>

span + del {color:yellow}

伪类选择器

:link 未访问(未点击)的链接
:visited 访问过(已被点击)的链接
:active 链接被激活(鼠标按下-松开)
:hover 鼠标在元素上
:focus 获得焦点(如点击输入框后)

声明伪类的顺序应为:link :visited :hover :active
如果反过来,前边的伪类样式可能被后边的覆盖

1
2
3
/*active样式被hover覆盖.点击a标签时,文字颜色为黄色*/
a:active {color: #f00;}
a:hover {color: #ff0;}

target

选择片段标识符指向的元素/a标签href属性指向的id元素
例如 www.github.com/#a 中的"#a",即id为a的元素

1
2
3
p:target {
background-color: yellow;
}

MDN

:not()

选择p标签中的内容,del标签除外

1
2
3
4
5
6
7
<p>
<span>a</span>
<del class="a">选不到</del>
</p>
p :not(del) {color: yellow};
// or
p :not(.a) {color: yellow};

注意
1 not不支持多个选择器

1
2
<!-- 无效果 -->
p :not(del.a) {color: yellow};

2 not不能用于排除所有祖先元素,例如

1
2
3
4
5
6
7
8
<div>
<p>
<span>a</span>
<del class="a" id="a">选不到</del>
</p>
</div>
<!-- 这个not(span)是没效果的,因为p标签也会被选中 -->
div :not(span) {color: yellow};

3 not选择器没有优先级,但其后括号内的选择器参与优先级计算

伪元素选择器

:first-child

选择p元素的第一个子元素(不包括匿名文本),而且这个元素必须是span

<p>
    匿名文本
    <span>a</span>
    <span>选不到</span>
</p>

p span:first-child {color: yellow}

作为对比,下面这个就选不到,因为span不是p的第一个子元素

<p>
    <del></del>
    <span>选不到</span>
</p>
p span:first-child {color: yellow}

:last-child

同上,区别为选择最后一个子元素

:nth-child(n)

选择p元素的第n个子元素(不包括匿名文本),且这个子元素必须是span元素 从1开始计数,例如第一个元素为::nth-child(1)

<p>
    匿名文本
    <span>a</span>
    <span>选不到</span>
</p>

p span:nth-child(1) {color: yellow};

作为对比,下边这个就选不到.因为span是第二个元素

<p>
    <del></del>
    <span>选不到</span>
</p>

p span:nth-child(1) {color: yellow};

:nth-last-child(n)

规则同上,区别为从最后一个子元素往前算

<p>
    <del></del>
    <span>a</span>
</p>

p span:nth-last-child(1) {color: yellow};

:nth-of-type(n)

选择p元素的第n个子span元素

<p>
    <del></del>
    <span>a</span>
</p>

p span:nth-of-type(1) {color: yellow};

:nth-last-of-type(n)

同上,区别为从最后一个子元素往前算

<p>
    <span>a</span>
    <del></del>
</p>

p span:nth-last-of-type(1) {color: yellow};

:first-letter

选择p元素中字符的第一字符

<p>
    <span>a</span>
    b c
</p>
p:first-letter {color:yellow};

:first-line

选择p元素中的第一行字符

<p>
    mew mew mew
    <br>
    选不到
</p>
p:first-line {color:yellow};

:before

在p元素前插入内容

<p>a</p>
p:before {
    content:"b";
}

通过display属性,也可以在p元素前插入块状/行内元素

<p>a</p>
p:before {
    content:"";
    display:inline-block;
    width: 10px;
    height: 10px;
    background: yellow;
}

:after

同上,区别为在p元素前插入内容

<p>a</p>
p:after {
    content:"b";
}

:root

选择根元素

:root {
background: yellow;
}

::selection

用于设置用户鼠标选中文本的样式

设置用户选择文本的背景颜色

<p>a</p>
::selection{background:yellow};

更多资料

优先级

特殊性/优先级(specificity)

当一个元素有多个样式声明时,由优先级决定哪个声明起决定作用.
优先级表

选择器 优先级
* + ~ > " " :not 0, 0, 0, 0
元素选择器 0, 0, 0, 1
伪元素选择器 0, 0, 0, 1
属性选择器 0, 0, 1, 0
伪类选择器 0, 0, 1, 0
class选择器 0, 0, 1, 0
id选择器 0, 1, 0, 0
内联样式 1, 0, 0, 0
<p>
    <span>a</span>
</p>
p span {color:yellow} /* 0, 0, 0, 2 */
span {color: green} /* 0, 0, 0, 1 */

规则1优先级大于规则2,因此span元素颜色为黄色

<div><div><div><div><div><div><div><div><div><div>
    <span class="content">a</span>
</div></div></div></div></div></div></div></div></div></div>

/*0, 0, 0, 11*/
div div div div div div div div div div span {background:yellow}
/*0, 0, 1, 0*/
.content {background:green}

计算优先级时,不会像十进制数字一样进位
无论在外边套多少个div,第二个选择器的优先级还是比第一个大

<p>
    <span>a</span>
</p>

p * {background: yellow} /* 0, 0, 0, 1 */
span {background: green} /* 0, 0, 0, 1 */

通配符选择器优先级为0,因此两个规则优先级相等. 前面选择器的样式被后面的覆盖,背景颜色为绿色.

<p>
    <span>a</span>
    <span>a</span>
</p>

p > span {background: yellow} /* 0, 0, 0, 2 */
p span {background: green} /* 0, 0, 0, 2 */

同样 > 符号的优先级为 0, 0, 0, 0

!important

当样式声明!important时,该样式将覆盖其他任何样式
当存在多条含有的!important的样式时,采用最大优先级声明

<p>
    <span style="background:yellow">a</span>
</p>
!important权重高于内联样式,因此背景颜色为绿色
span {background:green!important;}

!important应写在分号前,否则无效

not()

:not()不参与优先级计算,但其后括号内的选择器参与计算

1
2
3
4
<span id="i-a" class="c-a">a</span>

span:not(.c-a) {color: yellow;}
span {color: red;}

最终span元素内容颜色显示为黄色
因为选择器"span:not(.c-a)"中的".c-a"也参与计算,权重是 0, 0, 1, 1