深入理解 CSS(Cascading Style Sheets)中的层叠(Cascading)

标题中的 Cascading 亦可以理解为级联。

进入正文,这是一个很有意思的现象。可以直接跳到 总结一下 部分,看完再回过头来阅读本文。

引子

假设我们有如下结构:

<p class="txt" style="color:red">123456789</p>

上面的 p 标签只有一个内联 CSS,很明显,在没有其他样式的干预下,文本 .txt 的颜色肯定就是红色的。

如果此时,我们希望改变 .txt p 标签元素的内容文字的颜色,但是不能去修改内联 CSS,只能通过样式文件去实现,像是这样:

.txt {
    color: green;
}

嗯。稍微对 CSS 有点了解的同学都会知道,上面的 CSS 文件设置的样式不会生效,因为内联样式比上述 CSS 中的样式优先级要更高。

上述这种说法不是很严谨,下文会细说。

OK,有同学就会说了,这简单,在 CSS 样式文件中添加 !important 后缀即可 。像是这样:

.txt {
    color: green!important;
}

如此操作之后,文本的颜色确实变成了绿色,因为在 CSS 文件中带 !important 后缀的规则优先级大于内联样式中同个但不带 !important 的样式。

内联样式的 !important 与样式表中的 !important

问题来了。

如果在内联样式中,我们也给加上 !important 会怎么样呢?

<p class="txt" style="color:red!important">123456789</p> 
.txt {
    color: green!important;
}

此时,内联的 !important 优先级更高,文本表现为红色。

问题又来了,那如果此时我们无法修改内联样式,只能修改样式表,有办法能覆盖内掉内联的 !important 吗?

animtion 的威力(Chromium 内核)

哦吼,还真有一种看似是奇技淫巧,实则不是的方法。让我们康康:

<p class="txt" style="color:red!important">123456789</p>

我们给 .txt p 元素新增一个动画,改变它的颜色。

.txt {
    animation: colorGreen 2s infinite;
}

@keyframes colorGreen {
    0%,
    100% {
        color: green;
    }
}

这里新增了一个无限循环的动画,且动画初始状态及结束状态都赋予 color: green。甚至,我们都没有在规则后缀添加 !important

神奇的事情发生了,文本的颜色变成了绿色,成功的覆盖了内联的 <p class="txt" style="color:red!important"> 的红色样式。

CodePen Demo -- the priority of CSS Animation

常见 CSS 优先级误区

严格来说也不算是误区(错误),但是这种说法不够严谨。

通常我们聊到 CSS 规则的优先级,第一时间都会想到这个表,也就是给不同的 CSS 规则赋予不同的权重:

一个选择器的优先级可以说是由四个部分相加 (分量),可以认为是 个十百千 四位数的四个位数:

  • 千位: 如果声明在 style 的属性(内联样式)则该位得一分。这样的声明没有选择器,所以它得分总是1000
  • 百位: 选择器中包含ID选择器则该位得一分
  • 十位: 选择器中包含类选择器、属性选择器或者伪类则该位得一分
  • 个位:选择器中包含元素、伪元素选择器则该位得一分

总的来说是规则是:

内联 > id 选择器 > 类/属性/伪类选择器 > 标签元素/伪元素

上面的规则没有问题的。但是,注意,这里仅仅考虑的是页面作者定义的样式的优先级。首先,它并且没有包含 !important 规则。

其次,对于决定一个 CSS 样式的最终表现而言,还有非常重要的另外一个概念 -- 层叠。

Cascading -- 层叠

层叠是 CSS 的一个基本特征,它是一个定义了如何合并来自多个源的属性值的算法。它在CSS处于核心地位,CSS的全称层叠样式表正是强调了这一点。

那么什么所谓的多个源又表示什么呢?下面是影响层叠的五个源:

  • 浏览器会有一个基本的样式表来给任何网页设置默认样式。这些样式统称用户代理样式
  • 网页的作者可以定义文档的样式,这是最常见的样式表。大多数情况下此类型样式表会定义多个,它们构成网站的视觉和体验,即页面主题,可以理解为页面作者样式
  • 读者,作为浏览器的用户,可以使用自定义样式表定制使用体验,可以理解为用户样式
  • 动画(Animation),指使用 @Keyframes @规则定义状态间的动画,动画序列中定义关键帧的样式来控制CSS动画序列
  • 过渡 (Transition)

CSS动画与层叠(重点)

CSS动画,指使用@Keyframes @规则定义状态间的动画。

这里有个重点:关键帧不参与层叠。

这意味着在任何时候 CSS 都是取单一的 @Keyframes 的值而不会是某几个@Keyframe的混合。同时仍应注意用 @Keyframes(@规则)定义的值会覆盖全部普通值,但会被 !important 的值覆盖

这里我其实没弄很明白,这里的意思就是动画过程中的每一帧,决定元素的样式表现只取决于单一的 @Keyframes 的值,但是规范和 MDN 文档中都明确表明,动画 @Keyframes 中的值仍会被 !important 规则覆盖,但是实际测试结果,在 Chromium 内核下,动画 @Keyframes 中的值层叠顺序高于 !important 规则。

CSS 选择器的层叠(级联)顺序

上面说的常见的优先级误区,仅仅是规定了网页的作者定义的样式的优先级。除此之外,CSS 优先级还需要考虑选择器的层叠(级联)顺序。

只有在层叠顺序相等时,使用哪个值才取决于样式的优先级。

根据 CSS Cascading 4 最新标准:

CSS Cascading 4(Current Work)

定义的当前规范下申明的层叠顺序优先级如下(越往下的优先级越高,下面的规则按升序排列):

  • Normal user agent declarations
  • Normal user declarations
  • Normal author declarations
  • Animation declarations
  • Important author declarations
  • Important user declarations
  • Important user agent declarations
  • Transition declarations

简单翻译一下:

按照上述算法,大概是这样:

过渡动画过程中每一帧的样式 > 用户代理、用户、页面作者设置的!important样式 > 动画过程中每一帧的样式优先级 > 页面作者、用户、用户代理普通样式

然而,经过多个浏览器的测试,实际上并不是这样。(尴尬了)

实际测试的结果

实际代码测试的结果得出的结论其实是与规范中的优先级不大一致的。

不同内核浏览器实际表现不大一致,

Chrome 78 / Safari 13.0.4 / Edge 44.18362 (与规范表现不一致,Chromium内核)

animation 动画样式 > 页面作者定义的 !important 样式 > transition 过渡动画中的样式 > 普通样式

Firefox 71.0 (与规范表现一致)

页面作者定义的 !important 样式 > animation 动画样式 > transition 过渡动画中的样式 > 普通样式

CodePen Demo -- the priority of CSS Animation

总结一下

上文其实很绕,看得人很晕。简单总结一下:

  1. 决定一个元素的样式的最终表现,除了需要比较页面作者定义的样式的优先级之外,还需要比较样式的层叠顺序;
  2. 层叠是 CSS 的一个基本特征,定义了如何合并来自多个源的属性值的算法,5 个决定 CSS 样式的源分别是:用户代理样式、页面作者样式、用户样式、动画、过渡;
  3. 只有在层叠顺序相等时,元素的最终样式使用哪个值才取决于样式的优先级;
  4. 最新规范中给出的层叠顺序优先级与实际测得的有出入,不同内核浏览器实际表现不一致。

更多详细的关于层叠和样式优先级的概念,你可以看看下面:

上述 MDN 的两份文档都是有中文版的,但是发现其中中文版有部分与英文版规范不一致,应该是后面英文版有更新,但是没有同步到中文版,遇到这种情况还是应该去读读规范,并且自己实际动手实验一下。

最后

上面的第四点是我自己实测所得,可能是我搞错了,或者是我理解错了,如果是我的错误希望大家帮忙指出,共同进步学习。

更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。

好了,本文到此结束,希望对你有帮助 :)

如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

原文地址:https://www.cnblogs.com/coco1s/p/12200445.html

时间: 2024-11-11 12:46:29

深入理解 CSS(Cascading Style Sheets)中的层叠(Cascading)的相关文章

CSS 指层叠样式表 (Cascading Style Sheets)

CSS 指层叠样式表 (Cascading Style Sheets)CSS (Cascading Style Sheets) 用于渲染HTML元素标签的样式样式定义如何显示 HTML 元素样式通常存储在样式表中把样式添加到 HTML 4.0 中,是为了解决内容与表现分离的问题外部样式表可以极大提高工作效率外部样式表通常存储在 CSS 文件中多个样式定义可层叠为一:如果你要在HTML元素中设置CSS样式,你需要在元素中设置"id" 和 "class"选择器id 选择

传说中的CSS~让我来告诉你吧~Cascading Style Sheets

css 的每个类其实都是定义盒子的~ 每个类都是定义div里面的所有情况的~ 包括文字的啊图片啊列表啊啥啥啥啊 之类之类 就像立法的一样,你是哪个国家的就要遵守哪个国家的法律 国家下面还有省.市.区.公司 这种 然后男性有法律,女性有法律,孩子有法律,老人有法律 猫狗以及种种动物也有法律. css,其实就是rule . 你要写css,想快起来的写css,就是给自己一个先后标准. 是先说男的还是女的?先定老人还是孩子?先说猫怎么动还是狗怎么动? 可以拿来主义,也可以搞一个模板出来.

CSS media query应用中的层叠特性使用最佳实践

media query是css3规范中引入的,它提供了一种responsive design的基础机制:浏览器在不同size的设备中将以不同样式展现网页,这就给一个网页能够适应不同device一种可能.在实际使用中,我常常碰到以下问题:为什么media query的rule不起作用?很有可能和你的media query所处的位置有关,也很有可能和media query中的selector权重不 如外面的targeting到相同元素的css权重有关,比如: @media screen and (m

Qt Style Sheets帮助文档 Overview

Qt Style Sheets are a powerful mechanism that allows you to customize the appearance of widgets, in addition to what is already possible by subclassing QStyle. The concepts, terminology, and syntax of Qt Style Sheets are heavily inspired by HTML Casc

深入理解CSS中的层叠上下文和层叠顺序(转)

by zhangxinxu from http://www.zhangxinxu.com 本文地址:http://www.zhangxinxu.com/wordpress/?p=5115 零.世间的道理都是想通的 在这个世界上,凡事都有个先后顺序,凡物都有个论资排辈.比方说食堂排队打饭,对吧,讲求先到先得,总不可能一拥而上.再比如说话语权,老婆的话永远是对的,领导的话永远是对的. 在CSS届,也是如此.只是,一般情况下,大家歌舞升平,看不出什么差异,即所谓的众生平等.但是,当发生冲突发生纠葛的时

深入理解CSS中的margin

1.css margin可以改变容器的尺寸 元素尺寸 可视尺寸--标准盒子模型中盒子的宽度是不包括margin值的,clientWidth 占据尺寸--包括margin的宽度 outWidth不在标准之中,jquery中有相对应的方法 margin与可视尺寸 1.1使用那个与没有设定width/height的普通block水平元素 2.2只适用于水平方向尺寸 <body style="background-color:#1a2b3c"> <div style=&quo

深入理解CSS中的层叠上下文和层叠顺序

零.世间的道理都是想通的 在这个世界上,凡事都有个先后顺序,凡物都有个论资排辈.比方说食堂排队打饭,对吧,讲求先到先得,总不可能一拥而上.再比如说话语权,老婆的话永远是对的,领导的话永远是对的. 在CSS届,也是如此.只是,一般情况下,大家歌舞升平,看不出什么差异,即所谓的众生平等.但是,当发生冲突发生纠葛的时候,显然,是不可能做到完全等同的,先后顺序,身份差异就显现出来了.例如,杰克和罗斯,只能一人浮在木板上,此时,出现了冲突,结果大家都知道的.那对于CSS世界中的元素而言,所谓的“冲突”指什

CSS(Cascading Style Shee)

1.CSS是Cascading Style Sheet这个几个英文单词的缩写,翻译成中文是“层叠样式表”的意思 CSS能让网页制作者有效的定制.改善网页的效果. CSS是对HTML的补充,网页设计师曾经为无法很好的控制网页的显示效果而倍感苦恼,CSS的出现解决了这个问题. Css实现了网页内容和页面效果的彻底分离. 参考资料: 完整版W3CSchool线下教程  链接: http://pan.baidu.com/s/1jGSIqxg  密码: iuch TakeColor 8.0 CN Gree

深入理解css中的margin属性

转载自  http://www.cnblogs.com/zhuzhenwei918/p/6124263.html 深入理解css中的margin属性 之前我一直认为margin属性是一个非常简单的属性,但是最近做项目时遇到了一些问题,才发现margin属性还是有一些"坑"的,下面我会介绍margin的基本知识以及那些"坑".这篇博文主要分为以下几个部分: margin--基础知识 margin--在同级元素(非父子关系)之间应用 margin--在父元素和子元素之间