Skip to content

计算样式

当我们书写任意一个 HTML 元素时,该元素身上会有所有的 CSS 属性。虽然我们没有对这些属性赋值,但这些属性大部分使用了默认值,这点可以在浏览器的 Element 面板中查看。

html
<body>
    <h1>Hello World</h1>
</body>

计算过程

属性值的计算过程,分为如下这么 4 个步骤:

  • 确定声明值
  • 层叠冲突
  • 使用继承
  • 使用默认值

确定声明值

确定声明值,就是确定属性值,这个值就是我们书写的属性值。

html
<body>
    <h1>Hello World</h1>
    <p>我是一个 P 标签</p>
</body>
<style>
    p {
        color: red;
    }
</style>

层叠冲突

声明的样式规则发生冲突时,会进入解决层叠冲突的流程,此过程分为三步:

  • 比较源的重要性
  • 比较优先级
  • 比较次序
比较源的重要性

当不同的 CSS 样式来源拥有相同的声明时,此时就会根据样式表来源的重要性来确定应用哪一条样式规则。

整体来讲有三种来源:

  • 用户代理样式:浏览器会有一个基本的样式表来给任何网页设置默认样式。
  • 页面作者样式:网页的作者可以定义文档的样式,这是最常见的样式表。
  • 用户样式:浏览器的用户,可以使用自定义样式表定制使用体验。

对应的重要性顺序依次为:页面作者样式 > 用户样式 > 用户代理样式

html
<body>
    <h1>Hello World</h1>
    <p>我是一个 P 标签</p>
</body>
<style>
    p {
        color : red;
        display: inline-block;
    }
</style>

比较优先级

如果在同一个源中有样式声明冲突,此时就会进行样式声明的优先级比较。

html
<body>
    <div class="test">
        <h1>test</h1>
    </div>
</body>
<style>
    .test h1{
        font-size: 50px;
    }

    h1 {
        font-size: 20px;
    }
</style>

比较次序

样式声明既是同源,权重也相同时会进行次序比较。

html
<body>
    <h1>test</h1>
</body>
<style>
    h1 {
        font-size: 50px;
    }

    h1 {
        font-size: 20px;
    }
</style>

使用继承

样式继承是指元素的一些样式可继承与直接父元素。

html
<body>
    <div class="app">
        <p>我是 P1</p>
        <div class="home">
            <p>我是 P2</p>
        </div>
    </div>
</body>
<style>
    .app {
        color: #FAD;
        .home {
            color: #888;
        }
    }
</style>

可以在 MDN 中查看哪些属性可继承。

使用默认值

前面我们也说过,一个 HTML 元素要在浏览器中渲染出来,必须具备所有的 CSS 属性值,但是绝大部分我们是不会去设置的,用户代理样式表里面也不会去设置,也无法从继承拿到,因此最终都是用默认值。

面试题

下面的代码,最终渲染出来的效果,a 元素是什么颜色?p 元素又是什么颜色?

html
<body>
    <div>
        <a href="">test</a>
        <p>test</p>
    </div>
</body>
<style>
    div {
        color: red;
    }
</style>

实际上原因很简单,因为 a 元素在用户代理样式表中已经设置了 color 属性对应的值,因此会应用此声明值。而在 p 元素中无论是作者样式表还是用户代理样式表,都没有对此属性进行声明,然而由于 color 属性是可以继承的,因此最终 p 元素的 color 属性值通过继承来自于父元素。

基于 MIT 许可发布