百度前端技术学院 第四天学习笔记(选择器的优先级、了解级联、!important)(4)

选择器的优先级

级联(cascade)

  • 对于相同的选择器,在CSS中排在最后的那个将被使用

  • 例子:

1
2
3
4
5
6
h1 { 
color: red;
}
h1 {
color: blue;
}
1
2
<!-- 蓝色字体 -->
<h1>This is my heading.</h1>

特异性

  • 有多个选择器作用于同一元素时,类选择器的优先级高于元素选择器。(但这个是针对同一属性的时候,两个选择器没有重合的属性实际都作用于该元素)
  • 例子中有两个适用于h1的规则。类选择器为其规则赋予了更高的特异性,下面的内容h1最终变为红色。因此即使带有颜色的元素选择器的规则在源顺序中排在更下方,类选择器的颜色也将被应用。但元素选择器的其他属性还是会生效。
1
2
3
4
5
6
7
8
.main-heading { 
color: red; /*生效*/
}

h1 {
color: blue; /*未生效*/
text-decoration:underline;/*生效*/
}
1
2
<!-- 红色 + 下划线 -->
<h1 class="main-heading">This is my heading.</h1>

继承(Inheritance)

  • 如果在元素上设置color和font-family,除非它直接应用了不同的颜色和字体值,否则其中的每个元素也将使用该颜色和字体的样式。
  • 某些属性不会继承。width, margin, padding,border 等内容不会继承。例如,如果在width元素上设置50%的值,则其所有后代的宽度都不会达到其父级宽度的50%。
  • 例子:
1
2
3
4
5
6
7
body {
color: blue;
}

span {
color: black;
}
1
2
3
4
5
6
7
8
<!-- 蓝色 -->
<p>As the body has been set to have a color of blue this is inherited through the descendants.</p>
<!-- 蓝色 -->
<p>We can change the color by targetting the element with a selector, such as this
<!-- 黑色 -->
<span>span</span>
<!-- 蓝色 -->
.</p>
  • 提示:在MDN CSS属性参考页上,通常可以在规格部分的底部找到一个技术信息框,其中列出了有关该属性的许多数据点,包括是否继承。例如,MDN颜色属性写了“Inherited yes”

通过四个属性值控制继承

CSS提供了四个特殊的通用属性值来控制继承。每个CSS属性都接受这些值

属性值 作用
inherit继承 将应用于选定元素的属性值设置为其父元素的属性值
initial 最初的 将应用于所选元素的属性值设置为与浏览器默认样式表中为该元素设置的值相同。如果浏览器的默认样式表未设置任何值,就会继承该属性,相当于将属性值设置为inherit。
unset 重置 将属性重置为其自然值,这意味着,如果该属性是自然继承的,则其行为类似于inherit,否则,其行为类似于initial
新值 revert 它对浏览器的支持有限。revert
  • 例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
body {
color: green;
}

.my-class-1 a {
color: inherit/*设置为其父元素的属性值*/
}

.my-class-2 a {
color: initial;/*设置为与浏览器默认样式表中为该元素设置的值相同*/
}

.my-class-3 a {
color: unset;/*重置为其自然值.如果该属性是自然继承的,则其行为类似于inherit,否则,其行为类似于initial*/
}
1
2
3
4
5
6
<ul>
<li>Default <a href="#">link</a> color</li>
<li class="my-class-1">Inherit the <a href="#">link</a> color</li>
<li class="my-class-2">Reset the <a href="#">link</a> color</li>
<li class="my-class-3">Unset the <a href="#">link</a> color</li>
</ul>

效果图

  • 如果添加a { color: red; }只有第一行超链接字体变红色

通过all属性重置所有属性值

  • all速记属性一次控制(几乎)所有属性的继承,该属性将其值应用于所有属性。这是撤消对样式所做的更改的便捷方法
  • 属性值:inherit,initialunset,和revert
  • inherit关键字允许作者显式指定的继承,它适用于继承和非继承属性。可以使用all速记属性一次控制所有属性的继承,该属性将其值应用于所有属性。例如:
1
2
3
4
5
font: {
all: revert;
font-size: 200%;
font-weight: bold;
}
  • 这会将font属性的样式还原为用户代理的默认样式,除非存在用户样式表,否则将使用该样式表。然后将字体大小加倍,并应用font-weight的”bold”。

    默认样式表由浏览器供应商提供。(浏览器默认的CSS)

    用户样式表由浏览器的用户提供,用户自定义的CSS(用户自己写的)。

    作者样式表由网页作者提供(前端开发人员写的CSS)。

  • 例子:
1
2
3
4
5
6
7
8
blockquote {
background-color: red;
border: 2px solid green;
}

.fix-this {
all: unset;
}
1
2
3
4
5
6
7
<blockquote>
<p>This blockquote is styled</p>
</blockquote>

<blockquote class="fix-this">
<p>This blockquote is not styled</p>
</blockquote>

效果图


了解级联

  • 要考虑三个因素,这里按重要性从高到低的顺序列出。较早的优先于较晚的:重要性、特异性、源顺序
  • 注意:并不是整个规则都会被覆盖,只是相同的属性。

源顺序(Source order)

如果有多个选择器作用于同一个元素,则靠后的将获胜,也就是说靠后的选择器更加接近元素,他们将覆盖早期的规则,直到最后一个规则获胜并开始为元素设置样式。

特异性(Specificity)

  • 选择器具有的特异性程度是使用四个不同的值(或成分)来衡量的,可以将其视为千位,百位,十位和个位这四列中的四个个位数:
范围
如果声明位于style属性内(也称为内联样式)内,则在此列中得一千分。这样的声明没有选择器,因此它们的特异性始终只是1000
在此列中为整体选择器中包含的每个 ID选择器打分(有几个ID选择器就几百分
在此列中为整体选择器中包含的**每个 类选择器,属性选择器或伪类**计分(注意属性选择器的书写方法)
在此列中为整体选择器中包含的每个元素选择器或伪元素打一分。

计算举例

  • 例子:
1
2
3
4
5
6
7
8
<div id="outer" class="container">
<div id="inner" class="container">
<ul>
<li class="nav"><a href="#">One</a></li>
<li class="nav"><a href="#">Two</a></li>
</ul>
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

/* specificity: 0101 */
#outer a {
background-color: red;
}

/* specificity: 0201 */
#outer #inner a {
background-color: blue;
}

/* specificity: 0104 */
#outer div ul li a {
color: yellow;
}

/* specificity: 0113 */
#outer div ul .nav a {
color: white;
}

/* specificity: 0024 */
div div li:nth-child(2) a:hover {
border: 10px solid black;
}

/* specificity: 0023 */
div li:nth-child(2) a:hover {
border: 10px dashed black;
}

/* specificity: 0033 */
div div .nav:nth-child(2) a:hover {
border: 10px double black;
}

a {
display: inline-block;
line-height: 40px;
font-size: 20px;
text-decoration: none;
text-align: center;
width: 200px;
margin-bottom: 10px;
}

ul {
padding: 0;
}

li {
list-style-type: none;
}

解释

  • 前两个选择器在争夺链接背景颜色的样式上竞争,第二个选择器获胜并使背景颜色变成蓝色,因为它在链中有一个额外的ID选择器,其特异性是201对101。
  • 第三和第四个选择器正在争夺链接文本颜色的样式,第二个选择器获胜并使文本变成白色,因为尽管元素选择器(1分)少了一个,但缺少的选择器却换成了一个类选择器(10分)。因此获胜的特异性是113比104。
  • 选择器5–7在争夺链接边框的样式。选择器6显然输给了5,特异性为23 vs. 24,链中元素选择器少了一个。但是,选择器7击败了5和6,它在子链中具有与五个相同的子选择器数量,但是一个元素已换成类选择器。因此获胜的特异性是33 vs. 23和24。
  • 最终展现蓝底白字效果

重要性(!important

  • 他可以用来推翻所有上述计算,但是使用它时应格外小心。!important用于使特定属性和值成为最特定的事物,从而超越了级联的常规规则
  • 语法:选择器{属性: 属性值 !important;}
  • 注意:覆盖此!important声明的方法是在源顺序中稍后的同样特异性的声明中包含另一个!important声明,或者在更高特异性的声明中包含另一个!important声明
  • 强烈建议除非绝对必要,否则不要使用它!important更改了级联的正常工作方式,因此可能很难解决调试CSS问题.
  • 例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#winning {
background-color: red;
border: 1px solid black;
}

.better {
background-color: gray;
border: none !important;
}

p {
background-color: blue;
color: white;
padding: 5px;
}
1
2
3
4
<!-- 灰底白字 -->
<p class="better">This is a paragraph.</p>
<!-- 红底白字 -->
<p class="better" id="winning">One selector to rule them all!</p>

解释

  1. 可以看到已应用了第三条规则color和padding值,但尚未应用background-color。为什么?确实应该确实适用所有这三个规则,因为源顺序中的后面的规则通常会覆盖前面的规则。
  2. 但是,上面的规则会获胜,因为类选择器比元素选择器具有更高的特异性。
  3. 这两种元素都有class的better,但第二个一个有一个id的winning了。由于ID 比类具有更高的特异性(页面上每个ID只能具有一个元素,但是具有相同类的许多元素-ID选择器针对的对象非常具体),红色背景色和1像素黑色边框应同时应用于第二个元素,第一个元素将获得灰色背景色,并且没有边框(如该类所指定)。
  4. 第二个元素的确获得红色背景色,但没有边框。为什么?由于!important第二条规则中的声明-后面加上该字符串border: none意味着即使ID具有更高的特异性,此声明也将超过上一条规则中的边界值。

声明覆盖顺序(针对冲突声明)

冲突声明将按以下顺序应用,后面的声明将覆盖前面的声明

  • 用户代理样式表中的声明(例如,浏览器的默认样式,未设置其他样式时使用)。
  • 用户样式表中的常规声明(用户设置的自定义样式)。
  • 作者样式表中的常规声明(这些是我们,Web开发人员设置的样式)。
  • 作者样式表中的重要声明。
  • 用户样式表中的重要声明。

最后,注意到CSS声明的重要性取决于在其中指定的样式表,这也是有用的。用户可以设置自定义样式表中的!important来覆盖开发人员的样式

说明:

  • Web开发人员的样式表覆盖用户样式表是有意义的,因此可以按预期进行设计。
  • 但是如上所述,用户有充分的理由覆盖Web开发人员样式时可以通过!important在其规则中使用来实现。例如,用户可能在视觉上有缺陷,并且想要将所访问的所有网页上的字体大小设置为正常大小的两倍,以便于阅读

,