KnightSama‘s Blog

vuePress-theme-reco KnightSama    2021
KnightSama‘s Blog KnightSama‘s Blog

Choose mode

  • dark
  • auto
  • light
首页
分类
  • iOS
  • 集锦
  • JavaScript
  • Github
  • Python
标签
时间线
GitHub
author-avatar

KnightSama

27

文章

14

标签

首页
分类
  • iOS
  • 集锦
  • JavaScript
  • Github
  • Python
标签
时间线
GitHub
  • CSS 学习笔记-继承性与层叠性

    • 继承性
      • 层叠性
        • 选择器权重
        • 根据选择器数量计算权重
        • 未直接选中元素时的权重计算
        • 样式表权重
        • 使用 !important 提高权重
        • 权重总结

    CSS 学习笔记-继承性与层叠性

    vuePress-theme-reco KnightSama    2021

    CSS 学习笔记-继承性与层叠性


    KnightSama 2020-03-24 CSS

    继承性与层叠性是 CSS 的重要特性,继承性就是子组件会继承父组件的某些样式,这样我们就不需要给每个子组件都去设置样式。层叠性是对设置样式过程中可能导致的冲突问题进行处理。

    # 继承性

    继承性是子标签会使用父标签的某些样式,如果我们需要对某个标签下的所有后代标签都需要设置相同的样式,此时我们可以通过继承性将样式设置在父标签上,而不需要对每个子标签进行设置

    <html>
    
    <style>
        .test1 {
            color: red;
            border: 1px green solid;
        }
    </style>
    
    <div class="test1">
        <p>此标签的字体颜色继承自 div 标签</p>
        <p>所有后代标签都会继承</p>
    </div>
    
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    通过上面的例子我们看到设置到 <div> 上的字体样式被两个后代 <p> 标签所继承,但是设置的边框样式只有 <div> 生效,两个后代标签没有继承。因此并不是所有的样式都会被继承,关于字体样式的属性如 color 和以 font- 、 text- 、 line- 开头的属性大多都能继承,但有关定位、布局的属性不能被继承。在使用继承性的时候一定要注意哪些属性会被继承,哪些不会继承。

    # 层叠性

    我们知道 CSS 有多种选择器,不同的选择器可以选中相同的标签,此时如果定义了冲突的样式就需要通过优先级来确定最终应用哪种样式。

    <html>
    
    <style>
        .test2 p {
            color: green;
        }
    
        .test2 .red-color {
            color: red;
        }
        
        .test2 #blue-color {
            color: blue;
        }
    </style>
    
    <div class="test2">
        <p class="red-color" id="blue-color">设置文本颜色</p>
    </div>
    
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    上面的例子中我们通过三种不同的方式设置了 <p> 标签的文本颜色,最终文本显示为蓝色。这里就用到了层叠性,说明将文本设置为蓝色的选择器具有最高的优先级。

    # 选择器权重

    在计算权重时,不同的选择器具有不同的权重。当多个选择器选中某个元素时,按照如下顺序统计权重

    • id 选择器
    • 类选择器、属性选择器、伪类选择器
    • 标签选择器、伪元素选择器

    对于相同方式的样式表,选择器的优先级为: id 选择器 > 类选择器 > 标签选择器

    # 根据选择器数量计算权重

    当多个选择器选中相同元素时,我们可以分别统计这些选中目标元素的选择器中各种选择器的数量,然后按照选择器的权重由高到低依次比较,带有高权重选择器数量多的胜出。

    <html>
    
    <style>
        .test3 #div1 .class2 p {
            /* 1 个 id 选择器,2 个类选择器,1 个标签选择器 */
            color: green;
        }
    
        .test3 div div #div3 p {
            /* 1 个 id 选择器,1 个类选择器,3 个标签选择器 */
            color: red;
        }
        
        .test3 div.class1 div.class2 div.class3 p {
            /* 0 个 id 选择器,4 个类选择器,4 个标签选择器 */
            color: blue;
        }
    </style>
    
    <div class="test3">
        <div class="class1" id="div1">
            <div class="class2" id="div2">
                <div class="class3" id="div3">
                    <p>我的颜色是什么</p>
                </div>
            </div>
        </div>
    </div>
    
    </html>
    
    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

    上面的例子中通过三种选择器选中了 <p> 标签并同时设置了文本颜色,此时各样式的权重计算如下:

    首先统计各选择器中 id 选择器、类选择器、标签选择器的数量,这里以颜色区分

    • 设置绿色字体样式的选择器有 1 个 id 选择器,2 个类选择器,1 个标签选择器
    • 设置红色字体样式的选择器有 1 个 id 选择器,1 个类选择器,3 个标签选择器
    • 设置蓝色字体样式的选择器有 0 个 id 选择器,4 个类选择器,4 个标签选择器

    根据选择器优先级依次比较数量确定整体优先级

    • 绿色样式与红色样式都有 1 个 id 选择器,蓝色字体样式没有 id 选择器,因此蓝色字体样式优先级最低淘汰
    • 绿色样式与红色样式 id 选择器数量相同看下一级选择器,绿色样式有 2 个类选择器,红色样式有 1 个类选择器,绿色样式的类选择器更多故绿色样式优先级最高,最终字体颜色为绿色

    交并集选择器计算

    交集选择器要拆开后共同计算,如 div.class1 是一个类选择器加一个标签选择器

    并集选择器要按 , 隔开后分别计算每一部分的权重,看做多个选择器来计算

    div #test , .class1 div {
        /* 这里要拆成 div #test 与 .class1 div 两部分当做两个选择器分别计算权重 */
        color : red;
    }
    
    1
    2
    3
    4

    # 选择器权重相同时的就近原则

    如果选中标签的选择器权重相同时,则写在后面的样式生效,这就是就近原则。

    <html>
    
    <style>
        .test4 #div1 .class2 p {
            /* 1 个 id 选择器,2 个类选择器,1 个标签选择器 */
            color: green;
        }
    
        .test4 .class2 #div3 p {
            /* 1 个 id 选择器,2 个类选择器,1 个标签选择器 */
            color: red;
        }
    </style>
    
    <div class="test4">
        <div class="class1" id="div1">
            <div class="class2" id="div2">
                <div class="class3" id="div3">
                    <p>我的颜色是什么</p>
                </div>
            </div>
        </div>
    </div>
    
    </html>
    
    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

    上面的例子中绿色样式与红色样式的各类选择器数量相同因此权重相同,因为红色样式写在后面所以红色样式生效

    # 未直接选中元素时的权重计算

    如果样式选择器最终没有直接选中目标元素而是通过继承的方式影响的元素样式也就是选中了目标元素的父元素,此时这个选择器对于该元素权重为 0。

    <html>
    
    <style>
        .test5 #div1 #div2 #div3 {
            /* 没有直接选中 p 因此权重为 0 */
            color: green;
        }
    
        .test5 p {
            color: red;
        }
    </style>
    
    <div class="test5">
        <div class="class1" id="div1">
            <div class="class2" id="div2">
                <div class="class3" id="div3">
                    <p>我的颜色是什么</p>
                </div>
            </div>
        </div>
    </div>
    
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

    上面的例子中虽然绿色样式带有 3 个 id 选择器,但由于其并没有直接选中 <p> 标签,因此其权重为 0,因此最终文本颜色为红色。

    在计算权重的过程中要首先看是否直接选中了目标元素。

    # 继承时权重相同的就近原则

    如果目标选择器权重都为 0,说明其样式完全来自继承的父元素样式,此时只需去计算其父元素样式权重即可

    <html>
    
    <style>
        .test6 .class3 {
            color: green;
        }
    
        .test6 #div2 {
            color: red;
        }
        
        .test6 #div3 {
            color: blue;
        }
    
    </style>
    
    <div class="test6">
        <div class="class1" id="div1">
            <div class="class2" id="div2">
                <div class="class3" id="div3">
                    <p>我的颜色是什么</p>
                </div>
            </div>
        </div>
    </div>
    
    </html>
    
    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

    上面的例子中没有选择器直接选中 <p> 标签,因此权重均为 0,此时 <p> 标签的样式继承自父标签,因此计算父标签的样式。绿色样式选中了 <p> 标签的父标签 <div> 并有 2 个类选择器,红色样式选中了 <p> 标签的祖父标签,没有直接选中父标签权重为 0,蓝色样式选中了 <p> 标签的父标签 <div> 并有 1 个 id 选择器与 1 个类选择器,显然带有 id 选择器的蓝色样式权重最高,故字体为蓝色

    # 样式表权重

    CSS 样式有 3 中引入方式

    1. 行内样式:在标签中直接用 style 属性定义的样式
    2. 内嵌样式表:在页面中用 <style></style> 定义的样式区块
    3. 外部样式表:通过链接引入的外部样式文件

    样式表的优先级为:行内样式 > 内嵌样式表 > 外部样式表

    # 使用 !important 提高权重

    我们可以在样式属性的后面添加 !important 来使其权重变为无穷大。

    <html>
    
    <style>
        .test7 .class1 p{
            color: green;
        }
    
        .test7 #div1 p{
            color: red;
        }
        
        .test7 p{
            color: blue !important;
        }
    
    </style>
    
    <div class="test7">
        <div class="class1" id="div1">
            <p>我的颜色是什么</p>
        </div>
    </div>
    
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

    上面的例子中 3 个选择器都直接选中了 <p> 标签,红色样式由于带有一个 id 选择器故其权重最大,但是由于蓝色样式添加了 !important 权重提升为无穷大,故最终为蓝色

    注意

    !important 书写格式要正确,与要提升权重的属性写在一起用空格隔开,分号写到最后

    • color: red !important; ✅
    • color: red; !important; ❌ 没有写在一起,提前用分号隔开了
    • color: red important; ❌ 丢失了感叹号

    !important 只会提升标记的属性,对其他属性不收影响

    p {
        /* 只会提升颜色样式的权重,对于边框样式按照正常权重计算*/
        color: red !important;
        border: 1px red solid;
    }
    
    1
    2
    3
    4
    5

    !important 不影响通过继承获得的样式权重,如果某个样式的权重为 0,则添加 !important 后其权重依然为 0,最终权重按照前面 未直接选中元素时的权重计算 小节中的方法计算

    # 权重总结

    # 选择器权重

    id 选择器 > 类选择器 > 标签选择器

    # 样式表权重

    行内样式 > 内嵌样式表 > 外部样式表

    行内样式的权重最大,无论内嵌样式表与外部样式表样式如何优先执行行内样式 (带有 !important 的除外)。

    # id 选择器权重最大

    外部样式表的 ID 选择器 > 内嵌样式表的标签选择器

    # 相同样式表权重计算

    • 查看目标标签是否直接选中,如果都没有选中按照继承的权重计算处理
    • 直接选中通过不同选择器的数量计算权重,权重相同谁写在最后听谁的
    • 直接选中的属性如果带有 !important ,则其权重提升

    # 引用多个样式表权重 (就近原则)

    如果一个标签使用了多个相同的内嵌样式表,则定义的样式表中谁最近使用谁

    如果一个标签使用了多个相同的外部样式表,则 html 文件中引用的哪个外部样式表最近使用谁 (后加载的样式表会覆盖之前加载的样式表的相同属性)

    欢迎来到 KnightSama‘s Blog
    看板娘