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...

相关推荐
顾安r4 小时前
11.8 脚本网页 星际逃生
c语言·前端·javascript·flask
Hello.Reader4 小时前
Data Sink定义、参数与可落地示例
java·前端·网络
im_AMBER5 小时前
React 17
前端·javascript·笔记·学习·react.js·前端框架
谷歌开发者6 小时前
Web 开发指向标 | Chrome 开发者工具学习资源 (六)
前端·chrome·学习
一晌小贪欢6 小时前
【Html模板】电商运营可视化大屏模板 Excel存储 + 一键导出(已上线-可预览)
前端·数据分析·html·excel·数据看板·电商大屏·大屏看板
发现你走远了6 小时前
连接模拟器网页进行h5的调试(使用Chrome远程调试(推荐)) 保姆级图文
前端·chrome
街尾杂货店&7 小时前
css - 实现三角形 div 容器,用css画一个三角形(提供示例源码)简单粗暴几行代码搞定!
前端·css
顺凡7 小时前
删一个却少俩:Antd Tag 多节点同时消失的原因
前端·javascript·面试
小白路过7 小时前
CSS transform矩阵变换全面解析
前端·css·矩阵
爬山算法7 小时前
Redis(110)Redis的发布订阅机制如何使用?
前端·redis·bootstrap