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

相关推荐
冴羽15 分钟前
SvelteKit 最新中文文档教程(17)—— 仅服务端模块和快照
前端·javascript·svelte
uhakadotcom17 分钟前
Langflow:打造AI应用的强大工具
前端·面试·github
前端小张同学26 分钟前
AI编程-cursor无限使用, 还有谁不会🎁🎁🎁??
前端·cursor
yanxy51230 分钟前
【TS学习】(15)分布式条件特性
前端·学习·typescript
uhakadotcom1 小时前
Caddy Web服务器初体验:简洁高效的现代选择
前端·面试·github
前端菜鸟来报道1 小时前
前端react 实现分段进度条
前端·javascript·react.js·进度条
花楸树1 小时前
前端搭建 MCP Client(Web版)+ Server + Agent 实践
前端·人工智能
wuaro1 小时前
RBAC权限控制具体实现
前端·javascript·vue
专业抄代码选手1 小时前
【JS】instanceof 和 typeof 的使用
前端·javascript·面试