CSS专题之层叠

前言

石匠敲击石头的第 4 次

CSS 英文全称为 Cascading Style Sheets,中文翻译为 "层叠样式表",那究竟什么是层叠?我却说不出个所以然,所以打算写一篇文章来梳理一下,如果哪里写的有问题欢迎指出。

层叠是什么

层叠是指多个样式规则同时作用于同一个元素时,浏览器通过一套明确的优先级规则来决定最终生效的样式。

简单来说就是层叠就是浏览器应用样式的优先级规则

下图是层叠优先级规则判断的流程。

上图中流程简单来说会按照以下规则顺序来解决冲突。

  1. 样式表的来源
  2. 选择器优先级
  3. 在源码中的顺序

样式表的来源

样式表通常有以下的来源:

  • 用户代理样式表(User Agent Styles): 浏览器的默认样式,例如:<h1> 标签自带加粗和字体大小以及外边距的默认样式
  • 用户样式表(User Styles): 用户通过浏览器插件(如 Stylus 插件)、浏览器设置或开发者工具定义的样式,较少见
  • 作者样式表(Author Styles): 网页的开发者(即 "作者")编写的样式表,根据定义位置可以细分为如下样式表
    • 外部样式表:通过 <link> 标签引入的外部 CSS 文件
    • 内部样式:在 HTML 内部使用 <style> 标签定义的样式
    • 行内样式(内联样式):通过元素的 style 属性直接定义的样式

样式表的优先级

样式表的优先级由低到高如下:

  1. 用户代理样式表
  2. 用户样式表
  3. 作者样式表
    1. 外部样式表
    2. 内部样式表
    3. 行内样式表(内联样式表)
    4. 外部样式表的 !important
    5. 内部样式表的 !important
    6. 行内样式(内联样式)的 !important

⚠️ 注意: 不推荐在行内样式中使用 !important,因为优先级最高,无法被覆盖。

选择器优先级

选择器的优先级由低到高如下:

选择器类型 优先级标记
通用选择器(*)和组合选择器(>+~ (0,0,0)
标签选择器(p (0,0,1)
伪类选择器(:hover)、属性选择器([type="text"])、类选择器(.class (0,1,0)
ID 选择器(#id (1,0,0)

同时使用多种类型的选择器会让它们的优先级标记进行个数计算,例如 (1,2,2) 表示选择器由 1 个 ID 选择器、2 个类选择器、2 个标签选择器组成。

源码顺序

当两个声明的来源和选择器的优先级都相同,这时浏览器会根据声明在源码中的顺序,哪个声明最晚出现,则使用哪个声明。

例如:给链接添加样式的时候需要按照正确的顺序来书写选择器。

❌ 错误的顺序

css 复制代码
a:hover {
  text-decoration: underline;
}

a:link {
  color: blue;
  text-decoration: none;
}

a:visited {
  color: purple;
}

a:active {
  color: red;
}

上述代码中,链接的四种状态都来自于相同的来源(作者样式表,并且在同一个文件中),并且选择器的优先级都为 (0,1,1),所以浏览器根据在源码中的顺序来判断使用哪个声明。

所以导致了 a:hover 选择器中的 text-decoration: underline; 声明被后面的 a:link 选择器中的 text-decoration: none; 所覆盖。

✔️正确的顺序

css 复制代码
a:link {
  color: blue;
  text-decoration: none;
}

a:visited {
  color: purple;
}

a:hover {
  text-decoration: underline;
}

a:active {
  color: red;
}

可以使用顺序记忆口诀:"LoVe/HAte"("爱/恨"),其中 L 表示 link,V 表示 visited,H 表示 hoverA 表示 active

最佳实践

  1. 不使用 ID 选择器来添加样式: 因为 ID 选择器的优先级过高,需要使用其它的 ID 选择器或者使用 !important 才能覆盖,并且也不利于样式的复用,因为 ID 属性是唯一的
  2. 不使用 !important 比 ID 选择器更难覆盖,如果需要覆盖就需要使用 !important,如果很多声明都添加了 !important,就又会按照层叠优先级规则判断的流程的顺序进行比较

⚠️ 注意: 在特殊情况中(例如需要使用 JavaScript 通过 ID 选择器快速定位某个元素,或者需要使用 !important 才能覆盖第三方组件库的样式),可以不必死板遵守上述的两条建议

总结

  • 层叠就是浏览器应用样式的优先级规则 ,大致的规则流程顺序如下
    1. 样式表的来源
    2. 选择器优先级
    3. 在源码中的顺序
  • 最佳实践
    1. 不使用 ID 选择器来添加样式
    2. 不使用 !important

参考文章

博客地址:github.com/wjw020206/b...

相关推荐
IT_陈寒1 天前
Redis性能翻倍的5个冷门技巧,90%开发者都不知道第3个!
前端·人工智能·后端
jingling5551 天前
vue | 在 Vue 3 项目中集成高德地图(AMap)
前端·javascript·vue.js
油丶酸萝卜别吃1 天前
Vue3 中如何在 setup 语法糖下,通过 Layer 弹窗组件弹出自定义 Vue 组件?
前端·vue.js·arcgis
J***Q2921 天前
Vue数据可视化
前端·vue.js·信息可视化
ttod_qzstudio1 天前
深入理解 Vue 3 的 h 函数:构建动态 UI 的利器
前端·vue.js
_大龄1 天前
前端解析excel
前端·excel
一叶茶1 天前
移动端平板打开的三种模式。
前端·javascript
前端大卫1 天前
一文搞懂 Webpack 分包:async、initial 与 all 的区别【附源码】
前端
Want5951 天前
HTML音乐圣诞树
前端·html
老前端的功夫1 天前
前端浏览器缓存深度解析:从网络请求到极致性能优化
前端·javascript·网络·缓存·性能优化