CSS 层叠以及优先级
CSS层叠
层叠是CSS的一个基本特征,定义了如何合并来自多个源的属性值的算法。
参与CSS层叠计算的范围:只有属性名值对参与CSS层叠计算。包含CSS声明以外实体的@规则是不参与层叠计算的(例如:@font-face
、@key-frame
),而是是作为一个整体参与层叠计算的。大多数@规则的CSS声明是参与层叠计算的,比如 @media
、@documents
、 @supports
的CSS声明。
注意:@import
和 @charset
遵循特定的算法,不受层叠算法的影响。
CSS声明的来源:
- 用户代理样式。浏览器会有一个基本的样式表来给任何网页设置默认样式。为了减轻开发成本以及降低样式表运行所需的基本环境,网页开发者通常会使用一个CSS reset样式表,强制将常见的属性值转为确定状态。
- 网页的作者可以定义文档的样式,这是最常见的样式表。
- 读者,作为浏览器的用户,可以使用自定义样式表定制使用体验。
这些来源的CSS样式的作用范围是相同的,层叠算法定义了这些样式如何相互作用。
层叠顺序:
- 过滤来自不同源的全部规则,并保留要应用到指定元素上的那些规则。
- 依据重要性对这些规则进行排序。(层叠按升序排列的)
- 用户代理的 普通样式
- 用户的 普通样式
- 页面作者 的 普通样式
- CSS动画
- 页面作者的
!important
- 用户的
!important
- 用户代理的
!important
- CSS 过渡 (CSS transitions)
- 假如层叠顺序相等,则使用哪个值取决于优先级。层叠算法优于优先级算法,例如:当用户普通CSS样式和作者普通CSS样式选择到同一元素上,即使用户CSS的选择器优先级高于作者的CSS也不会应用上去。
**重置样式:**CSS属性all
能够让你快速地把(几乎)所有CSS属性设置到一个已知样式上。(当你的css对样式完成更改之后,也许会在某种情况下希望把他们还原到一个已知样式上,这可能发生在动画、主题修改之类的情形中。)
all 属性让你能够立刻把所有的属性都还原到它们初始(默认)的状态,或是继承自前一个层叠顺序等级的状态,又或是指定一个特定的来源(用户代理、页面作者或者用户),甚至还可以选择完全清除所有的属性。
/* Global values */
all: initial 改变该元素或其父元素的所有属性至初始值。
all: inherit 改变该元素或其父元素的所有属性的值至他们的父元素属性的值。
all: unset 如果该元素的属性的值是可继承的,则改变该元素或该元素的父元素的所有属性的值为他们父元素的属性值,反之则改变为初始值。
/* CSS Cascading and Inheritance Level 4 */
all: revert; 指定依赖于声明所属的样式表原点的行为:
CSS动画与层叠:
CSS动画指用 @keyframe
定义状态间的动画。关键帧不参与层叠,意味着在任何时候CSS都是取单一的@keyframes的值而不会是某几个@keyframe的混合。
当有多个满足条件的关键帧时,在最重要的文档里面最后定义的关键帧会被选中,而不会是将它们组合在一起。
同时仍应注意用@keyframes @规则定义的值会覆盖全部普通值,但会被!important的值覆盖。
优先级
浏览器通过优先级 来判断哪些属性值与一个元素最为相关,从而在该元素上应用这些属性值。当同一个元素有多个声明的时候,优先级才会有意义。因为每一个直接作用于元素的 CSS 规则总是会接管/覆盖(take over)该元素从祖先元素继承而来的规则。
选择器类型(优先级递增):
- 类型选择器和伪元素。(例如,
h1
、::before
) - 类选择器、属性选择器和伪类。(例如
.example
,[type="radio"]
,:hover
)) - id选择器(例如,
#example
) - 元素的内联样式。
style="font-weight:bold"
- 通配选择符
*
和关系选择符+
,>
,~
,'<span> </span>
'和否定伪类:not()
对优先级没有影响。(但是,在:not()
内部声明的选择器会影响优先级)。 - 而当优先级与多个 CSS 声明中任意一个声明的优先级相等的时候,CSS 中最后的那个声明将会被应用到元素上。
!important
当在一个样式声明中使用一个 !important
规则时,此声明将覆盖任何其他声明。技术上来说,这并不是改变优先级,而是改变了层叠顺序。
使用 !important
是一个坏习惯 ,应该尽量避免,因为这破坏了样式表中的固有的级联规则 。当两条相互冲突的带有 !important
规则的声明被应用到相同的元素上时,拥有更大优先级的声明将会被采用。
经验法则:
- 一定 要优先考虑使用样式规则的优先级来解决问题而不是
!important
- 只有 在需要覆盖全站或外部 CSS 的特定页面中使用
!important
- 永远不要 在你的插件中使用
!important
- 永远不要 在全站范围的 CSS 代码中使用
!important
什么时候可以使用 !important
- 覆盖内联样式。在全局的 CSS 文件中写一些
!important
的样式来覆盖掉那些直接写在元素上的行内样式。 - 覆盖优先级高的选择器。
怎样覆盖 !important
- 再写一条带
!important
的CSS规则,再给这个给选择器更高的优先级 - 使用相同的选择器,但是置于已有的样式之后
- 干脆改写原来的规则,以避免使用
!important
。