标题中的 Cascading 亦能够理解为级联。css
进入正文,这是一个颇有意思的现象。能够直接跳到 总结一下 部分,看完再回过头来阅读本文。git
假设咱们有以下结构:github
<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
的样式。网站
问题来了。ui
若是在内联样式中,咱们也给加上 !important
会怎么样呢?
<p class="txt" style="color:red!important">123456789</p>
复制代码
.txt {
color: green!important;
}
复制代码
此时,内联的 !important
优先级更高,文本表现为红色。
问题又来了,那若是此时咱们没法修改内联样式,只能修改样式表,有办法能覆盖内掉内联的 !important
吗?
哦吼,还真有一种看似是奇技淫巧,实则不是的方法。让咱们康康:
<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 规则赋予不一样的权重:
一个选择器的优先级能够说是由四个部分相加 (份量),能够认为是 个十百千 四位数的四个位数:
总的来讲是规则是:
内联 > id 选择器 > 类/属性/伪类选择器 > 标签元素/伪元素
上面的规则没有问题的。可是,注意,这里仅仅考虑的是页面做者定义的样式的优先级。首先,它而且没有包含 !important
规则。
其次,对于决定一个 CSS 样式的最终表现而言,还有很是重要的另一个概念 -- 层叠。
层叠是 CSS 的一个基本特征,它是一个定义了如何合并来自多个源的属性值的算法。它在CSS处于核心地位,CSS的全称层叠样式表正是强调了这一点。
那么什么所谓的多个源又表示什么呢?下面是影响层叠的五个源:
浏览器会有一个基本的样式表来给任何网页设置默认样式。这些样式统称用户代理样式
网页的做者能够定义文档的样式,这是最多见的样式表。大多数状况下此类型样式表会定义多个,它们构成网站的视觉和体验,即页面主题,能够理解为页面做者样式
读者,做为浏览器的用户,可使用自定义样式表定制使用体验,能够理解为用户样式
动画(Animation),指使用 @keyframes @规则定义状态间的动画,动画序列中定义关键帧的样式来控制CSS动画序列
过渡 (Transition)
CSS动画,指使用@keyframes @规则定义状态间的动画。
这里有个重点:关键帧不参与层叠。
这意味着在任什么时候候 CSS 都是取单一的 @keyframes 的值而不会是某几个@keyframe的混合。同时仍应注意用 @keyframes(@规则)定义的值会覆盖所有普通值,但会被 !important 的值覆盖
这里我其实没弄很明白,这里的意思就是动画过程当中的每一帧,决定元素的样式表现只取决于单一的 @keyframes 的值,可是规范和 MDN 文档中都明确代表,动画 @keyframes 中的值仍会被 !important 规则覆盖,可是实际测试结果,在 Chromium 内核下,动画 @keyframes 中的值层叠顺序高于 !important 规则。
上面说的常见的优先级误区,仅仅是规定了网页的做者定义的样式的优先级。除此以外,CSS 优先级还须要考虑选择器的层叠(级联)顺序。
只有在层叠顺序相等时,使用哪一个值才取决于样式的优先级。
根据 CSS Cascading 4 最新标准:
定义的当前规范下申明的层叠顺序优先级以下(越往下的优先级越高,下面的规则按升序排列):
简单翻译一下:
按照上述算法,大概是这样:
过渡动画过程当中每一帧的样式 > 用户代理、用户、页面做者设置的!important样式 > 动画过程当中每一帧的样式优先级 > 页面做者、用户、用户代理普通样式
然而,通过多个浏览器的测试,实际上并非这样。(尴尬了)
实际代码测试的结果得出的结论实际上是与规范中的优先级不大一致的。
不一样内核浏览器实际表现不大一致,
animation 动画样式 > 页面做者定义的 !important 样式 > transition 过渡动画中的样式 > 普通样式
页面做者定义的 !important 样式 > animation 动画样式 > transition 过渡动画中的样式 > 普通样式
CodePen Demo -- the priority of CSS Animation
上文其实很绕,看得人很晕。简单总结一下:
决定一个元素的样式的最终表现,除了须要比较页面做者定义的样式的优先级以外,还须要比较样式的层叠顺序;
层叠是 CSS 的一个基本特征,定义了如何合并来自多个源的属性值的算法,5 个决定 CSS 样式的源分别是:用户代理样式、页面做者样式、用户样式、动画、过渡;
只有在层叠顺序相等时,元素的最终样式使用哪一个值才取决于样式的优先级;
最新规范中给出的层叠顺序优先级与实际测得的有出入,不一样内核浏览器实际表现不一致。
更多详细的关于层叠和样式优先级的概念,你能够看看下面:
上述 MDN 的两份文档都是有中文版的,可是发现其中中文版有部分与英文版规范不一致,应该是后面英文版有更新,可是没有同步到中文版,遇到这种状况仍是应该去读读规范,而且本身实际动手实验一下。
上面的第四点是我本身实测所得,多是我搞错了,或者是我理解错了,若是是个人错误但愿你们帮忙指出,共同进步学习。
更多精彩 CSS 技术文章汇总在个人 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。
好了,本文到此结束,但愿对你有帮助 :)
若是还有什么疑问或者建议,能够多多交流,原创文章,文笔有限,才疏学浅,文中如有不正之处,万望告知。