(03)CSS 结构和层叠 | CSS

2,278 阅读5分钟
原创:itsOli  @前端一万小时

本文首发于公众号前端一万小时

本文版权归作者所有,未经授权,请勿转载!

本文节选自“语雀”私有付费专栏前端一万小时 | 从零基础到轻松就业

❗️❗️❗️
以下链接为本文最新勘误篇章——《CSS 结构和层叠》


1. 选择器的优先级是如何计算的?
2. 什么是 CSS 继承?哪些属性能继承,哪些不能?

🙋上方面试题“参考答案详解”,请点击此处查看获取方式!



前言: 在上一篇《(02)CSS 选择器详解 | CSS》中,我们文章一开始就谈到了“结构树”,也明白了之后的种种“选择器”都是建立在有这个“结构树”的基础之上。

这篇,我们将详细阐述“结构树”之于“继承”、“层叠”等的重要性。

① 继承:继承是指在结构树中,从一个元素向其后代元素传递属性值所采用的机制;

② 层叠:层叠是一个“过程”,是浏览器“考虑”的“过程”——浏览器在确定应当向一个元素应用哪些值时,浏览器不仅要考虑“继承”,还要考虑“声明的特殊性”,另外还需要考虑“声明本身的来源”。


1 特殊性/特定性

“特殊性/特定性”对于理解如何向文档应用声明很重要。

如果一个规则能“更准确”地选择一个元素,那么这个规则就更为“特定/特殊”!

可以通过计算的方法来得到这个“特定性”,值越大,特定性越强:

例如:

h1 {
  color: red;
  background: yellow;
} /* specificity=0001 */

p,div {
  font-family: sans-serif;
} /* specificity=0002 */

#txa {
  width: 300px;
  height: 200px;
  margin-left: -12px;
} /* specificity=0100 */

.done {
  text-decoration: line-through;
} /* specificity=0010 */

li[class] {
  color: red;
  background: yellow;
} /* specificity=0011 */

❗️注: 通配选择器对一个选择器的特定性没有贡献,其“特定性 = 0000”,虽全是 0,但这不代表他没有“特定性”。反而需要记住的是:0 特定性比无特定性要强。

❗️注:有时某个声明可能非常重要,超过了所有其他声明,则在这些声明结束分号前加上 !important 。
如:

h1 {
  color: red;
  background: yellow !important;
}

2 继承

继承是 CSS 中最基本的内容之一。

继承的值没有“特定性”,甚至连 0 特定性也没有。因此我们随时能使用一个更“特定”的选择器来覆盖其从父选择器继承的属性。

一般来讲,如果样式会影响你的文本外观,则所有这些样式都能“继承”。如:字体颜色 color 、所有与字体相关的属性:

font-family
font-size
font-weight
font-style

❗️而大多数 “框模型属性” 就不能继承(包括外边距、内边距、背景和边框),比如给 <body> 元素加了一个边框样式,不代表我们希望这个“身体”里所有的元素都有“边框”。


3 层叠

CSS:Cascading Style Sheets 层叠样式表。

CSS 基于的方法就是让所有样式“层叠”在一起,这是通过结合“继承”和“特殊性”做到的。

层叠是一个“过程”,是浏览器“考虑”的“过程”——浏览器在确定应当向一个元素应用哪些值时,浏览器不仅要考虑“继承”,还要考虑“声明的特殊性”,另外还需要考虑“声明本身的来源”。

站在“浏览器”的角度,它会进行以下几步来决定应用什么样式:
第一步: 收集所有样式表;

  • 包括:Web 页面作者写的样式表,读者自己增加的样式表,还有浏览器的默认样式。

第二步: 找到所有匹配的声明;

第三步: 对所有匹配的规则排序;

  • 标志 !important 的规则的权重要高于没有 !important 标志的规则。

  • 按“来源”——创作人员、读者、浏览器,对应用到给定元素的所有声明排序。
    一般来说:

    • 创作人员的样式要胜于读者的样式;
    • !important 标志的读者样式强于所有其他样式(包括有 !important 标志的创作人员样式);
    • 创作人员样式和读者样式都比浏览器默认样式要强。

第四步: 按上文讲的“特定性”计算值对所有声明排序;

第五步: 按出现顺序对应用到给定元素的所有声明排序。

  • 一个声明在样式表或文档中越后出现,它的权重就越大;

  • 如果一个样式表中有导入的样式表,一般认为出现在导入样式表中的声明在前,主样式表中的所有声明在后。


4 对上篇文章中遗留问题的解答

a:link {
  color: blue;
}

a:visited {
  color: red;
}

a:hover {
  color: orange;
}

a:active {
  color: black;
}

如上一篇文章所说:我们需要按以上顺序来声明链接样式。

通过这篇的学习,我们知道了原因:

  • 他们都有相同的权重、来源;

  • 所有这些选择器的“特定性”值都是一样的:0011;

  • 因此,顺序上与元素匹配的最后一个选择器才会胜出。

即:

  • 首先,正常情况下,a 的颜色是“蓝色”;

  • 然后,当我鼠标放上去之后,:hover 在顺序上在下边,所以变为“橙色”;

  • 接着,当我鼠标按下去时,表示我的鼠标正在这个元素上,那么 :link:hover:active 都生效,但按层叠规则,:active 在顺序上的最下边,故对以上产生覆盖,所以变成“黑色”;

  • 最后,当我点击过这个链接之后,鼠标移开后,:link:visited 生效,:visited:link 覆盖并永久生效。



后记: 本篇知识点不多,属于基础知识,需要烂熟于心。路还很长,希望收获在路上,快乐在路上。

祝好,qdywxs ♥ you!