css属性值计算

先来看两个问题

问题1: 关于 a 标签的 color为什么没有继承父元素的 color。

html 复制代码
<!-- 代码1: 为什么 a 标签中 文字的颜色没有继承父元素的 color:red, 显示红色呢 -->
<style>
  .container {
    color: red;
  }
</style>

<!-- 代码2: 为什么这么写了就可以了 a元素中的文字就会变成 红色 -->
<style>
  .container a {
    color: red;
  }
</style>

<!-- 代码3:加上 important,权重最高了,a 标签文字依然不会变成红色 -->
<style>
  .container a {
    color: orange;
  }
  .container {
    color: red !important;
  }
</style>


<!-- html 部分 -->
<div class="container">
  <a href="">百度</a>
</div>

问题2:为什么我们设置的 * { margin: 0} 样式可以覆盖浏览器自带的样式

* 的权重是 0, body 的权重是 1,为什么用户设置的可以覆盖浏览器默认样式

要回答上面两个问题,就要先知道 css 属性值的计算过程

每一个 HTML 元素都有很多个 css 属性,可以在浏览器的 computed 中查看

浏览器要显示一个元素,这个元素的所有的 css 属性都必须有值,浏览器才能知道渲染这个元素,该怎么显示,显示在哪里。

一个 css 属性从没有值 到有值的过程 就是 CSS属性值计算过程

每一个 css 属性从没有值到有值都要经过下面这个过程

我们在页面上看到的元素样式由最终的计算结果决定

在代码里面设置的样式 并不一定是最终显示的结果

代码里面设置的样式会影响最终显示的结果

比如 在代码里面设置的 width: 100%, 实际可能得到的是 width: 890px

确定声明值

规则:先看样式表中没有冲突的样式声明,直接作为 css 的最终属性值, 有冲突的样式先忽略不处理。

html 复制代码
<h2 class="box">属性值计算</h2>

用户样式
.box {
    color: red;
    font-size: 100px;
}
h2 {
    font-size: 30px;
}

div h2.box {
    font-size: 50px;
    font-size: 60px;
}


浏览器默认样式
h2 {
    display: block;
    font-size: 1.5em;
    font-weight: 700;
}

如上面代码所示, 有个 h2 元素

在用户设置的样式中,有通过 类名设置的样式、有通过标签名设置的样式、还有综合各种选择器设置的样式

h2 元素有自己默认的浏览器样式

可以看出 font-size 属性是有冲突的,先忽略不处理

没有冲突的作为最终的属性值,

这一步之后, h2 元素的样式如下

css 复制代码
<style>
    h2 {
        color:red
        background-color: 不确定
        text-align: 不确定
        font-size: 不确定
        font-weight:700
        display:block
    }
</style>

层叠冲突

规则: 对样式表有冲突的声明使用层叠规则,确定CSS属性值

层叠冲突其实要经过三个步骤

第一步:比较重要性, 简单理解就是用户设置的样式覆盖浏览器默认样式

这也就解释了一开始的 为什么 * 会覆盖 body 的 margin 样式

这一步之后, 浏览器默认的 font-size: 1.5em 就被淘汰了

第二步: 比较特殊性, 就是比较 css 权重

根据权重规则,第三个的权重最高,其他两个被淘汰了,留下下面的样式

css 复制代码
div h2.box {
    font-size: 50px;
    font-size: 60px;
}

第三步:比较源次序,就是比较代码属性的顺序,后面的覆盖前面的,也就是 层叠

最终确定的 h1 元素的 font-size 属性的值 是 60px

使用继承

规则: 对仍然没有值的属性,若可以继承,则继承父元素的值

注意:是对没有值的属性,同时该属性支持继承,才会继承

假设 h2 的父元素的样式如下

css 复制代码
div {
    color:green
    background-color:gray
    text-align:center
    font-size:20px
    font-weight:normal
    display:block
}

目前就剩下 background-color 和 text-align 没有值

因为 background-color 不能继承,text-align 可以继承

所以最终这一步之后可以确定 text-align 属性的值 是 center

使用默认值

规则: 对仍然没有值的属性,使用默认值

经过上面的三个步骤之后,剩下的所有没有值的属性就使用默认属性值

至此,一个 元素的所有css 属性值都确定了。

总结

现在来解释开头的问题

a 标签的 color 属性为什么没有继承

是因为浏览器给 a 标签的 color 属性设置了值, 在第一步确定声明值的时候,就已经确定了 color 的值,所以不会进行第三步的继承。

为什么 width 设置的是 100%, 最终计算结果是 890px

这是因为在计算过程中,凡是相对单位都会被计算为绝对单位 px, 因为浏览器要渲染一个元素,需要确定这个元素的位置、大小等等各种样式信息,所以必须是一个绝对的值,这一块涉及到浏览器的渲染原理,在另一篇中介绍。

完~

相关推荐
魔云连洲2 分钟前
Vue的响应式底层原理:Proxy vs defineProperty
前端·javascript·vue.js
专注VB编程开发20年6 分钟前
CSS定义网格的列模板grid-template-columns什么意思,为什么要用这么复杂的单词
前端·css
IT_陈寒12 分钟前
Redis性能提升50%的7个关键优化策略,90%开发者都不知道第5点!
前端·人工智能·后端
Hilaku19 分钟前
深入URL和URLSearchParams:别再用正则表达式去折磨URL了
前端·javascript·代码规范
pubuzhixing24 分钟前
Canvas 的性能卓越,用它解决一个棘手问题
前端
weixin_4569042724 分钟前
Vue.jsmain.js/request.js/user.js/store/index.js Vuex状态管理项目核心模块深度解析
前端·javascript·vue.js
伍哥的传说28 分钟前
Vue 3.6 Alien Signals:让响应式性能飞跃式提升
前端·javascript·vue.js·vue性能优化·alien-signals·细粒度更新·vue 3.6新特性
永日4567032 分钟前
学习日记-HTML-day51-9.9
前端·学习·html
狗头大军之江苏分军1 小时前
iPhone 17 vs iPhone 17 Pro:到底差在哪?买前别被忽悠了
前端
小林coding1 小时前
再也不怕面试了!程序员 AI 面试练习神器终于上线了
前端·后端·面试