文章目录
- 层叠
- 一、基本概念
- 二、哪些CSS实体会参与层叠计算
- 三、CSS声明的来源
- 3.1 用户代理样式
- 3.2 作者样式表
- 3.3 读者自定义样式表
- 四、层叠算法
- 4.1 重要性 -- !important
- 4.2 特殊性 -- 选择器权重
- 4.3 源顺序 -- 后来居上
- 五、特殊的 @规则与层叠计算
- 5.1 完全不参与层叠计算的 @规则
- 5.1.1 @charset规则
- 5.1.2 @import规则
- 5.2 整体参与筛选但内部声明不参与层叠的 @规则
- 5.2.1 @font-face
- 5.2.2 @keyframes
- 5.3 内部声明参与层叠计算的 @规则
- 5.3.1 @media规则
- 5.3.2 @supports规则
- 六、重置样式 -- all属性
层叠
一、基本概念
层叠是CSS的一个基本特征,是一个定义了如何合并来自多个源的属性值的算法
层叠计算就是为了挑选 CSS 声明来给 CSS 属性设置正确的值
二、哪些CSS实体会参与层叠计算
- 只有 CSS 声明,就是
属性名值对
- 直接的CSS声明
- 包含在大多数 @规则的 CSS 声明(第五点有详细讲解)
.box{color:pink; /* 这是一条属性名值对,即一个CSS声明 */
}
三、CSS声明的来源
CSS 层叠算法期望通过挑选 CSS 声明来给 CSS 属性设置正确的值。CSS 声明可以有不同的来源
来源类型
- 用户代理样式
- 作者样式表
- 读者自定义样式表
源的关系
- 它们共同构成了网页最终呈现给用户的样式效果
- 尽管 CSS 样式会来自这些不同的源,但它们的作用范围是重叠的
- CSS层叠算法则负责协调这些不同来源的样式声明,为每个 CSS 属性设置正确的值
源的默认优先级
一般情况下,不同来源样式的优先级顺序从高到低为:
- 读者自定义样式表(带
!important
) - 作者样式表(带
!important
) - 读者自定义样式表(普通)
- 作者样式表(普通)
- 用户代理样式
3.1 用户代理样式
浏览器会有一个基本的样式表来给任何网页设置默认样式,即用户代理样式
在没有任何额外样式定义的情况下,一个简单的 HTML 页面中的段落会以浏览器默认的字体和颜色显示
。
浏览器差异: 不同浏览器的用户代理样式存在差异
CSS reset表:
为了统一不同浏览器的默认样式,减轻开发成本,网页开发者通常会使用 CSS reset 样式表,例如:
* { margin:0;padding:0; }
这样可以避免不同浏览器对元素默认的内外边距设置不同而导致布局出现差异
3.2 作者样式表
网页的作者可以定义文档的样式,这是最常见的样式表。大多数情况下此类型样式表会定义多个,它们构成网站的视觉和体验,即主题
3.3 读者自定义样式表
读者自定义样式表则是读者根据个人需求对网页样式进行的个性化调整
例如:
- 在 Firefox 浏览器中,可以在
about:config
中找到userContent.css
文件修改font-size
属性以调整网页文本大小
四、层叠算法
层叠算法的判断主要基于三个关键因素:重要性、特殊性和源顺序
4.1 重要性 – !important
重要性是层叠算法中一个较为特殊的判断因素;
属于层叠算法中用于打破常规优先级的一种机制。
!important声明
!important
声明会使对应的样式具有最高优先级,它超越了特殊性和源顺序的常规判断,直接改变了样式的应用规则
.box{color:blue !important;color:red;
}
/* 对于上述代码,!important会覆盖后续声明,超越了源顺序的判断 */
注意
- 由于!important标记的声明具有最高的优先级,它会破坏层叠的正常逻辑,使代码的可维护性变差
- 所以我们需要谨慎使用
正常声明
- 没有
!important
标记的声明,按照特殊性和源顺序来决定优先级
4.2 特殊性 – 选择器权重
特殊性是根据选择器的类型来计算的,不同类型的选择器具有不同的权重
特殊性的计算方式 (选择器优先级算法
) 通常可以用四个数字来表示 (a,b,c,d
)
选择器权重
- 如果存在内联样式,那么
A = 1
, 否则A = 0
; B
的值等于ID选择器
出现的次数;C
的值等于类选择器
和属性选择器
和伪类
出现的总次数;D
的值等于标签选择器
和伪元素
出现的总次数 。
比较规则
- 从左往右依次进行比较 ,较大者胜出,如果相等,则继续往右移动一位进行比较
- 如果4位全部相等,则按照源顺序来决定优先级
4.3 源顺序 – 后来居上
当重要性和特殊性都相同时,后面定义的样式会覆盖前面定义的样式
.box{color:black;color:pink;
}/* 2,3行的声明重要性与特殊性相同,则根据源顺序选择3行声明 */
五、特殊的 @规则与层叠计算
什么是 @规则
- At 规则是一个CSS 语句,用来指示 CSS 如何运行
一般结构:@identifier (RULE);
- 如我们常见的 @media,@keyframes…
@规则参与层叠计算吗
- 在 CSS 中,
部分 @规则参与层叠计算,部分不参与
- 而对于参与的@规则,又分为
两种情况
:- 整体参与筛选但内部声明不参与
- 内部声明参与
5.1 完全不参与层叠计算的 @规则
这是因为这类@规则有特点的规则,它们的存在和处理方式与层叠机制无关
5.1.1 @charset规则
该规则用于告知浏览器该CSS文件的字符编码
它必须放在任何规则之前的CSS文件最顶部;根据CSS规范,只能出现一次
如果一个CSS文件中有多个@charset规则呢?,如下:
@charset "UTF - 8";
/* 此处省略一些CSS代码 */
@charset "ISO - 8859 - 1";
/* 此处省略一些CSS代码 */
对于上述情况,可能出现两种结果
- 只有第一个有效:浏览器通常只会识别第一个
@charset
规则,而忽略后面的规则 - 可能导致编码错误:比如,样式表中的字符实际是按照
ISO - 8859 - 1
编码保存的,但第一个@charset
规则指定了UTF - 8
编码,那么浏览器会以UTF - 8
编码来解析这些字符,就可能导致字符显示不正确
5.1.2 @import规则
该规则用于引入外部的CSS文件,通常放在CSS文件的开头部分
@import url("styles.css");
@import url("styles1.css");
- 它的作用是将另一个 CSS 文件的内容引入到当前文件中
- 多个
@import
规则只是按顺序引入不同的文件,不会相互层叠,因此不参与层叠计算
5.2 整体参与筛选但内部声明不参与层叠的 @规则
这类@规则定义了一些特殊的对象,如
字体、动画关键帧等
,它们作为一个整体被筛选和应用,而内部的声明不会像普通的 CSS 声明那样相互层叠
5.2.1 @font-face
改规则用于自定义字体
/* 定义 */
@font-face { font-family: 'MyFont';src: url('myfont.woff2') format('woff2');
}
/* 使用 */
.box {font-family: 'MyFont';
}
- 浏览器会根据
@font - face
规则的整体定义来加载和使用字体 - 不同的
@font - face
规则不会合并它们的描述符,只会选择符合条件的规则来应用,所以其内部声明不参与层叠计算
整体参与层叠算法的情况
.box {font-family: 'MyFont1';font-family: 'MyFont2';
}
5.2.2 @keyframes
改规则用于定义CSS动画的关键帧
/* 定义 */
@keyframes move {from {left:0;}to {left:10px;}
}
/* 使用 */
.box{animation:move 2s linear infinite;
}
@keyframes
规则定义了一个完整的动画序列,浏览器会选择一个特定规则来应用动画,不会将多个@keyframes
规则的关键帧混合在一起,所以关键帧的声明不参与层叠计算。
5.3 内部声明参与层叠计算的 @规则
这类@规则通常是条件性的,用于根据不同的条件(如
媒体查询、特性检测等
)来应用样式,其内部的 CSS 声明会像普通的声明一样参与层叠计算
5.3.1 @media规则
改规则根据媒体特性(如屏幕宽度、设备类型等)来应用不同的样式
@media (min - width: 768px) { body { font - size: 18px; } } @media (max - width: 767px) { body { font - size: 16px; } }
- 当满足不同的媒体查询条件时,这些规则内部的声明会像普通的 CSS 声明一样进行层叠计算,最终确定应用的样式
5.3.2 @supports规则
该规则用于检测浏览器是否支持某个 CSS 特性
@supports (display: grid) { .container { display: grid; } } @supports not (display: grid) { .container { display: flex; } }
六、重置样式 – all属性
all
属性是一个简写属性,它可以一次性重置元素的所有 CSS 属性
为什么需要all属性
- 当你的 css 对样式完成更改之后,也许会在某种情况下希望把他们还原到一个已知样式上,这可能发生在动画、主题修改之类的情形中
all属性的取值
- initial — 将元素的所有属性重置为浏览器默认的初始值(用户代理样式表)
.box{all:initial;
}
- inherit — 让元素的所有属性继承其父元素的属性值
.parent{color:blue;
}
.parent .child{all:inherit;
}
-
unset — 对于可继承的属性,使用继承的值;对于不可继承的属性,使用初始值
-
revert — 如果有自定义样式表,则恢复到自定义样式表;如果没有用户自定义样式,那么就恢复到浏览器的默认样式
-
revert-player — 将元素的所有属性恢复到当前层叠层中该属性的上一个值
- 层叠层是一个更高级的特性,建立在层叠与优先级的基本概念之上
参考文档:
https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_cascade/Cascade