回顾 CSS 层叠与继承

119 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

今天开始“重学CSS”计划,其实是想通过「回顾 CSS 核心知识,阅读经典书籍和技术专栏,做一些有趣的练习」这样的路线进入“玩起CSS”的状态。大概对我来说,前端有趣的点之一是能实现设计,让优雅的视觉交互成真。每天学一点,在掘金输出成果。

今天阅读的是《深入解析CSS》的第一章“层叠、优先级和继承”,层叠和继承虽然简单,却是 CSS 的灵魂,作为 CSS 中的 C(cascade)层叠的作用不容小觑。

为什么需要层叠?

CSS 本质上是声明一系列规则,一条规则 = 选择器 + 声明块,一条声明 = 属性 + 值

code.png

于是有一个问题,当两条规则提供的声明冲突时哪一个会生效呢?我们需要一些规则来维护秩序,这些规则称为“层叠规则”。

层叠规则

层叠就是比较三个因素,决出优先级更高的声明。三个因素是

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

判断流程如图所示

流程图.jpg

层叠规则的应用:超链接伪类的书写顺序

a:link {
    color: #0269c8;
}
a:visited {
    color: #1f4bc2;
}
a:hover {
    color: #275b8c;
}
a:active {
    color: #091c2e
}

超链接存在 :link(有链接):visited(已访问):hover(悬停):active(点击) 四个状态。

四个状态有可能叠加存在,比如点击时既是 active 又是hover,如果href有值还满足link,但点击时需要 active 状态优先。按照交互逻辑,需要写出优先级 active > hover > visited > link 的效果。

四种选择器的优先级一样,所以通过源码顺序来调整。

经验法则:尽量使用低优先级写法。

优先级容易发展成一种“军备竞赛”。在大型项目中这一点尤为突出,通常最好让优先级尽可能低,这样当需要覆盖一些样式时,才能有选择空间。

克制地挑选选择器结构,为后续维护留有余地。这也是尽量避免使用 !important 和 ID 选择器的原因,尽量使用样式表选择器而非行内样式也有这方面的考量。

继承

通过层叠规则判断出优先声明后,一个元素属性的层叠值也计算出来了。

如果所有样式表中都没有声明一个元素的某个属性,接着可能会去继承某个祖先元素的值。

并不是所有属性都是能被继承的,这和属性的规范定义相关。

与继承有关的关键字是inherit,去强制继承父元素的值。神奇的是一些规范定义中不会被继承的属性,也可以用 inherit 实现强制继承。

默认值

那些无法被继承的属性将使用默认值,属性的默认值同样是由规范定义的。

和默认值相关的关键字是initial,用来恢复属性的默认值。有一个有趣的知识点,display 属性的默认值是 inline,并不会根据元素的类型变化。

Tips

1.在 DevTool Elements Styles 面板中查看层叠和继承情况 Screenshot 2022-12-01 at 23.11.35.png

2.简写中忽略的属性将会隐式使用默认值 例如写 font: 12px redfont-weight/font-style/line-height 等属性会被隐式设置回默认值

3.简写方向写法妙记 需要指定四个方向的值,就想想时钟“上右下左”,例如 margin/padding。需要指定两个方向的值,就想想笛卡尔网络要按照x/y的顺序来指定坐标,例如 box-shadow/text-shadow/background-position

总结

CSS 的本质是声明一系列规则,当多个规则中的声明冲突时,通过层叠来决出优胜声明,计算出元素属性的层叠值。

如果属性没有层叠值,可继承的属性会取父元素或祖先元素的值,不可继承的属性会使用默认值。

层叠的判断方法是:先比较样式来源,如果一致再比较选择器的优先级,最后比较源码顺序。 流程图.jpg