你不知道的CSS之层叠规则

本文同步发在个人博客

层叠规则

2023-12-15 23:36:14

众所周知,CSS 的计算过程分为四个步骤

  • 声明
  • 层叠
  • 继承
  • 默认

我们这里单说层叠

层叠

首先层叠是为了解决冲突而存在的,某一个元素在页面中可能会受到很多样式影响,那么当出现样式冲突的时候到底听谁的

css 复制代码
.box1 {
  color: blue;
}
.box2 {
  color: red;
}

比如这里的一个 div 有 box1 和 box2 两个 className ,那么到底是显示哪个颜色,这就是层叠要做的事

整个层叠规则会按照三个部分比较

  • 优先级
  • 特殊性
  • 源次序

优先级

主要有四个优先级,优先级从高到低 👇🏻

  • 开发者样式表中带有 !important 的样式
  • 默认样式表(浏览器)中带有 !important 的样式
  • 开发者样式表中的普通样式
  • 默认样式表中的普通样式

比较过程中优先级低的会被淘汰掉,留下高优先级的样式。

特定性 (specialization)

一般特殊性就是我们平时写 css 时所说的权重,核心就是用四位数字表达式来表示样式的特殊性,每个样式都会有自己的数字表达式

大概是这样的 👉🏻 (?, ?, ?, ?) 从左到右就是从高位到低位

第一位数字只能是 0 或 1,判定规则是只有当这个样式是被写在元素的 style 中,也就是内联样式时,它的数字表达式就是 (1, ?, ?, ?),不是的话就是 (0, ?, ?, ?),比如此处的 color: red 的首位数字就是 (1, ?, ?, ?)

html 复制代码
<div style="color: red">hello world</div>

第二位数字代表着该样式所在的选择器有几个 id 选择器

css 复制代码
#container .box {
  color: red;
}

#page #header #container .box {
  color: blue;
}

比如此处 第一个 color 所在的选择器只有一个 id,那么它对应的数字表达式就是 (?, 1, ?, ?),而第二个 color 是有三个,那么它的数字表达式就是 (?, 3, ?, ?)

第三位数字代表着该样式所在的选择器有几个类选择器、属性选择器、伪类选择器之和

css 复制代码
.menu .link[href]:active {
  color: red;
}

比如这里有两个类选择器 一个属性选择器 一个伪类选择器,那么它对应的表达式就是 (?, ?, 4, ?)

最后一位数字代表着该样式所在的选择器有几个元素选择器、伪元素选择器之和 同上

那么我们这里现在有这样的一个样式

css 复制代码
#container div#menu.link[href]:active {
  color: red;
}
  • 很明显这里不是内联样式,所以首位是 0
  • 有两个 id 选择器,所以第二位是 2
  • 一个类选择器,一个属性选择器,一个伪类选择器,所以第三位是 3
  • 一个元素选择器,所以最后一位是 4

那么这个样式的特殊性的数字表达式就是 (0, 2, 3, 1)

因为通常情况下我们不会去写内联样式,所以首位基本都是0,也大多会省略首位,写成三位的数字表达式,

比如在 VSCode 的css文件里,把鼠标放在样式上就会出现提示

在比较特定性时会从高位开始,高位相同时会继续向后比较,直到比较出大小

源次序

经过前面的优先级和特定性的比较后,大部分的样式冲突问题都会被解决,但是有些会比较巧合的情况下样式的特定性可能是相同的,那么就需要再源次序里再比较

源次序就是在源代码里的顺序,不是在class里的使用顺序

html 复制代码
<div class="box1 box2"">hello world</div>
<div class="box2 box1"">hello world</div>

像这样的两行代码是没有区别的,这里说的源次序是指在css文件里的书写顺序

css 复制代码
.box1 {
  ...
}
.box2 {
  ...
}

书写顺序靠后的源次序更高(覆盖的思想)

如果前面的特定性是相同的没有比较处理,那么到了源次序是一定会被解决的,因为总不可能两个样式是在同一行书写的,总会有先后顺序的,所以到了这一步样式冲突的问题一定会被解决,比较出到底哪一个样式会生效

相关推荐
前端摸鱼匠5 分钟前
Vue 3 的watch监听多个数据源:讲解如何同时监听多个响应式数据的变化
前端·javascript·vue.js·前端框架·ecmascript
文心快码BaiduComate8 分钟前
用Spec给AI Agent立规矩,AI编码告别手忙脚乱
前端·后端·前端框架
东北小狐狸-Hellxz8 分钟前
后端生成的URL中含base64参数值,经tomcat重定向后偶发前端无法解密报错
java·前端·tomcat
在等星星呐21 分钟前
人工智能从0基础到精通
前端·人工智能·python
前端不太难30 分钟前
Navigation State 与页面内存泄漏的隐性关系
前端·ui·react
C+++Python36 分钟前
如何选择合适的锁机制来提高 Java 程序的性能?
java·前端·python
IT_陈寒42 分钟前
JavaScript 性能优化:7 个 V8 引擎偏爱的编码模式让你提速 40%
前端·人工智能·后端
long31643 分钟前
类与对象 | 低级别设计 (LLD)
java·spring boot·学习·程序人生·spring·设计模式·学习方法
小oo呆1 小时前
【自然语言处理与大模型】LangChainV1.0入门指南:核心组件Messages
前端·javascript·easyui
果壳~1 小时前
【前端】【canvas】图片颜色填充工具实现详解
前端