【後转前要多久】# Day07 CSS - 打架该听谁的?CSS权重、继承

虽然这章节可能有些无聊,迟迟没进入CSS引人兴趣的地方,
但我还是想依我学习时,所想到和纳闷的事物按顺序一个个讲述。

前面介绍了CSS引入的几种方式,
既然分成这麽多种,就好奇他们彼此之间打架会发生什麽事?
如果设定不同,分歧时到底该优先听谁的?

CSS 权重 Specificity

前面一章提到了 选取器 Selector,
因为每个选取器都有不同的计分方式,
遇到设定打架时,就听权重最大的那个人说话!

以下是权重计分由高到低排序:

  1. 最高优先 !important (10000分)
  2. 行内inline style="..." (1000分)
  3. ID选择器 #id (100分)
  4. 类别选择器、属性选择器 两者同分 .class[attr=value] (10分)
  5. 标签选择器 <tag> (1分)
  6. 通用选取器 * (0分,有其他设定就能盖掉)

由此高低差异可见,选择的方式越具体、越有指定性,权重计分就越高。
另外!important 破坏了级联的比较规则,非不得已时尽量少用。

权重计分分数叠加,ex:

  • .container (10分)
  • .container div (11分)
  • .container .menu div (21分)

例子1:

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="index.css">
</head>
<body>

<p class="class" id="id">
    Lorem ipsum dolor sit amet.
</p>

</div>
</body>
</html>

CSS

*{
    color: aqua;
}

p{
    color: blue;
}

.class{
    color: blueviolet;
}

#id{
    color: red;
}

运行结果是红色,果真如计分方式那样,
#id是里面分数最高的(100分)。
出现红色不是因为後面设定覆盖前面设定,而是因为#id权重较大的关系。

例子1运行结果

例子2:

此时将HTML加上一个style行内属性

...
<p class="class" id="id" style="color: yellow">
    Lorem ipsum dolor sit amet.
</p>
...

style行内样式是里面分数最高的(1000分)。
就变黄色(yellow)了,真开心。

例子2运行结果

例子3:

再来将CSS加上一个!important试试

*{
    color: aqua;
}

p{
    color: blue !important;
}

.class{
    color: blueviolet;
}

#id{
    color: red;
}

哇,一下子变成蓝色(blue)
果然!important 10000分,无能人挡啊!!

例子3运行结果

例子4:

听说分数能叠加?
好,那我来试试

在CSS随手加上几个!important

*{
    color: aqua;
}

p{
    color: blue !important;
}

.class{
    color: blueviolet !important;
}

#id{
    color: red !important;
}

结果果然是红色(red)
毕竟拿#id去叠加的分数最高 (10100分)

例子4运行结果

例子5:

!important也可以加在HTML行内!!

HTML

...
<p class="class" id="id" style="color: yellow !important">
    Lorem ipsum dolor sit amet.
</p>
...

哼哼,style行内样式 加上 !important (11000分)
果然是黄色(yellow)胜出
结果不出所料呢

例子5运行结果


坑 - 权重分数累加?

我们来看看以下的例子

例子6:

HTML

...
<p class="class" id="id">
    Lorem ipsum dolor sit amet.
</p>
...

CSS

.class.class.class.class.class.class.class.class.class.class.class.class.class.class.class{
    color: blueviolet;
}

#id{
    color: red;
}

我把15个.class(10分)累加在一起,分数变成150,
这样一来能盖过#id(100分)吧

所以这题会是紫罗兰色(blueviolet)!!

例子6运行结果

淦,啊出来怎麽会是红色(red)的?!


权重分数不是单纯累加

透过WebStorm IDE的提示可以看到,
确实有吃到15个.class、以及1个#id

WebStorm提示

15个10分的class居然不敌1个100分的id?

没错,敌不过。
权重分数的计分并不是单纯累加。

我们将分数划分成五个维度
把上面的计分说明重新修正一下

  1. 最高优先 !important (1|0|0|0|0)分
  2. 行内inline style="..." (0|1|0|0|0)分
  3. ID选择器 #id (0|0|1|0|0)分
  4. 类别选择器、属性选择器 .class[attr=value] (0|0|0|1|0)分
  5. 标签选择器 <tag> (0|0|0|0|1)分
  6. 通用选取器 * (0|0|0|0|0)分

维度相同的权重,计分分数叠加
每个维度互不相干,维度间只存在辗压的份。

ex:

  • .container (1|0)分
  • .container div (1|1)分
  • .container .menu div (2|1)分

先比较最高维度,相同的话再往低维度比较
多别人一个维度,导致的结果就是辗压

无论较小的尺寸再多,只要前面存在一个高次元的差距,
分数就是狠狠的辗过去了。

例子7:

HTML

...
<p class="class" id="id">
    Lorem ipsum dolor sit amet.
</p>
...

CSS

#id#id#id.class{
    color: green;
}

#id#id.class.class{
    color: red;
}

回过头来修改一下CSS,
绿色(3|1|0)前面维度多一个,直接辗压红色(2|2|0)

例子7运行结果

所以出来的答案是绿色(green)。

严格来说 !important(1|0|0|0|0) 不能列入计分之中,
因为!important是将样式提升到最高层次,只会出现一次
没办法同时出现两个或多个!important来叠加计分

所以总共只有四个维度的分数(0|0|0|0)


如果有这麽简单就好了

如果世界如此简单,网页就不会这麽复杂了

终於搞懂了权重是怎麽进行比较,
觉得原来如此简单、世界如此美好、终於可以安稳的睡觉时...

再以权重的角度回头看看这个例子8:

例子8:

HTML

...
<div class="container" id="c1">
    <div class="content" id="c2">
        <p style="color: red">Lorem ipsum dolor sit amet.</p>
    </div>
</div>
...

CSS

#c1#c1{
    color: green;
}

#c2{
    color: pink !important;
}

嗯,虽然这个c2 pink看来只有一个#id,不敌c1 green的两个#id
但人家後天努力认真向上,老天赐予他一个!important
这c2一定狠狠屌打c1 green!!
不要不信邪,这ㄍ出来一定是粉红色辣!!

例子8运行结果

淦~!@#$%^&
怎麽半路跑杀出程咬金,执行结果冒出一个写在HTML中的红色(red)?
难道我又被骗惹吗?


CSS 继承 Inheritance - 关系的远近

其实除了权重之外,还要考虑第二件事情,就是继承。

在CSS中有些属性是可以往下继承下去的,如:colorline-heighttext-...
(当然也有只局限在当前标签的、不会往下继承的属性,如: border)

由於刚刚的例子8中,<p>的style属性直接选中了<p>标签作用的位置。

<p style="color: red">Lorem ipsum dolor sit amet.</p>

自己的属性(直接选用的)优先於继承来的属性

所以要先看父子层结构,若均指定在同一层时再比较权重

文章快要结束了、再忍耐一下看看以下的例子9

例子9:

将HTML中的<p>段落拿掉了inline style,
稍加修改一下CSS,
最终出来会是什麽颜色?

HTML

...
<div class="container" id="c1">
    <div class="content" id="c2">
        <p>Lorem ipsum dolor sit amet.</p>
    </div>
</div>
...

CSS

#c1#c1{
    color: green !important;
}

.content{
    color: pink;
}

虽然green有个!important在,看起来分数好像高的严重...

例子9运行结果

最终结果出来,
虽然pink分数远低於!important、甚至比green的两个#id还要低,
但却是.class粉红色(pink)胜出,
原因是目标标签 离.content描述的标签关系较近,所以优先继承他的样式。


当分数一样、继承顺序也一样呢

当分数一样、继承顺序也一样的时候,
一定会爆炸了吧?因为根本公平到无法比较了。

不。
此时就会发生後面覆盖前面设定的状况。

例子10:

将多个分数一样(都是class)的样式,
通通都指定到同一个元素层级(.container)上

HTML

...
<div class="container">
    <style>
        .container{
            color: blue;
        }
    </style>
    <p>Lorem ipsum dolor sit amet.</p>
</div>

<style>
    .container{
        color: yellow;
    }
</style>
...

CSS

.container{
    color: green;
}

.container{
    color: pink;
}

在HTML中最後才出现的<style>黄色(yellow),
默默静静地把前面所有人都干掉了...

例子10运行结果

相同地,如果把<link>连接CSS样式放在HTML最後面,
则是吃到CSS最後覆盖的样式。

<div class="container">
    <style>
        .container{
            color: blue;
        }
    </style>
    <p>Lorem ipsum dolor sit amet.</p>
</div>

<style>
    .container{
        color: yellow;
    }
</style>
<link rel="stylesheet" href="index.css">

吃到的就会是CSS的粉红色(pink)

把CSS样式放在HTML最後面

例子11:

在同一个元素中加入多个class,
此时每个class分数、层级都一样,
後盖前仍然是以style样式的顺序为主。

...
<style>
    .yellow{
        color: yellow;
    }

    .green{
        color: green;
    }

    .red{
        color: red;
    }
</style>

<div class="red yellow green">
    <p>Lorem ipsum dolor sit amet.</p>
</div>
...

出来是红色(red)而非绿色(green),
因为red是引用到的样式之中最後定义的。
相同元素多个class


嗯,看来CSS的陷阱比想像中的还要多...


<<:  RISC-V: 记忆体提前亮相

>>:  年薪破百的海岛生活,是你想要的吗?

android studio 30天学习笔记-day 1 - 前言

Hi大家好,很高兴参加这次铁人赛,身为大学生的我接触android已经快过一年了,在这期间学习许多,...

Day 08 : Longest Mountain in Array

先来看简述题目的定义 至少要有连续3个以上的整数 从左往右看他要是严格递增直到这些数中的最大值(山顶...

2021-Day26. Serverless(十 四):AWS - SSL / TLS 凭证

影片一录好,就把AWS帐号给关掉了,就不用像昨天一样後制到怀疑人生... ...

自动化 End-End 测试 Nightwatch.js 之踩雷笔记:点击物件

点击特定物件是 E2E 中很常会做到的事,如果本身物件有设定好特定的 ID, Class 或 Att...

D20 - 浓浓咖啡香的深拷贝、浅拷贝

前言 什麽是拷贝? 今天朋友想 copy 你的报告,最简单的就是影印一份给他,但是当你修改报告中的内...