前端杂谈: CSS 权重 (Specificity)

简介:

css 权重想必大家都听说过, 一些简单的规则大部分人也都知道:

  • 较长的 css selector 权重会大于较短的 css selector
  • id selector 权重高于 class selector.

但是具体规范是什么? 浏览器是按照什么标准来判定不同选择器的权重的呢?

让我们来看一下官方文档是怎么说的~

第一个关键词: Specificity

Specificity is the means by which browsers decide which CSS property values are the most relevant to an element and, therefore, will be applied. Specificity is based on the matching rules which are composed of different sorts of CSS selectors

官方文档中用 Specificity: 特异性 来表示一个 css selector 和其元素的相关性. 相关性越强, 即表示表示其权重最高.

那么问题来了, Specificity 是如何被比较的呢?

Specificity is a weight that is applied to a given CSS declaration, determined by the number of each selector type in the matching selector.

Specificity 是由 selector 中 不同 selector type 的数目决定的.

第二个关键词: Selector Type

根据 W3 标准中的规定, css selector 分为 4 种 type: a, b, c, d. 他们的数目计算规则为:

  • a: 如果 css 属性声明是写在 style=“” 中的, 则数目为 1, 否则为 0
  • b: id 选择器的数目
  • c: class 选择器, 属性选择器(如 type=“text”), 伪类选择器(如: ::hover) 的数目
  • d: 标签名(如: p, div), 伪类 (如: :before)的数目

在比较不同 css selector 的权重时, 按照 a => b => c => d 的顺序进行比较.

由第一个 selector type a 的计算规则可知: 写在 html 代码 style 属性中的 css 相较写在 css 选择器中的 css 属性具有最高的优先级.

而 id selector (b) 相较 class selector (c) 有更高的优先级. 这也和我们平时的经验相吻合.

还有一些 css 选择器你没提, 它们该怎么计算权重?

除了上面 Specificity 计算规则中的 css 选择器类型, 还有一些选择器如: *, +, >,:not() 等. 这些选择器该如何计算其权重呢?

答案是这些选择器并不会被计算到 css 的权重当中 :)

有一个需要特别注意一下的选择器: :not(), 虽然它本身是不计权重的, 但是写在它里面的 css selector 是需要计算权重的.

如果 a,b,c,d 算完都一样, 怎么办?

默认行为是: 当 specificity 一样时, 最后声明的 css selector 会生效.

如果我重复同样的 css selectory type, 权重会增加吗?

让我们来做个实验, 我们声明一个 html 节点:

<div>
  <div id="testId" class="testClass"><span>test div</span></div>
</div>

在 css 中我们添加两个选择器:

.testClass.testClass {
  background-color: red;
}
.testClass {
  background-color: black;
}

如果重复的 css selector 会被忽略的话, 按照前面的规则, 最后声明的 css selector 会生效, 所以 这个 div 节点背景色应该是黑色. 让我们看看结果:

FSvsHI.png

结果我们得到的是一个红色的 div, 也就是说 .testClass.testClass 高于 .testClass. 所以结论是: 重复的 css selector, 其权重会被重复计算.

关于 !important:

按照 MDN的说法, !important 是不在 css 选择器的权重计算范围内的, 而它之所以能让 css 选择器生效是因为浏览器在遇见 !important 时会进行特殊的判断. 当多个 !important 需要进行比较时, 才会计算其权重再进行比较.

通常来说, 不提倡使用 !important. 如果你认为一定要使用, 不妨先自检一下:

  • 总是先考虑使用权重更高的 css 选择器, 而不是使用 !important
  • 只有当你的目的是覆盖来自第三方的 css(如: Bootstrap, normalize.css)时, 才在页面范围使用 !important
  • 永远不要 在你写一个第三方插件时使用 !important
  • 永远不要在全站范围使用 !important

一些误导的信息

我在搜索关于 css 权重的资料时, 看到了下面这张图, 看似十分有道理, 但其实是错误的!css_weight1

让我们来做一个简单的测试:

按照图片中的计算公式: 如果一个 css 选择器包含11 个 class selector type, 另一个选择器是1 个 id selector type. 那么 class 选择器的权重会高于 id 选择器的权重. 让我们来试一试:

.testClass.testClass.testClass.testClass.testClass.testClass
  .testClass.testClass.testClass.testClass.testClass {
  background-color: red;
}
#testId {
  background-color: black;
}

让我们看看结果:

FSvfgg.png

结果显示还是 id 选择器权重更高.

虽然我们在实际编码过程中很少会出现 10 多个 class 的情况, 但万一出现了, 知道权重真正的计算比较规则, 我们才能正确的处理~

想了解更多 前端 和 数据可视化 ?

这里是我的 D3.js数据可视化 的 github 地址, 欢迎 star & fork :tada:

D3-blog

如果觉得本文不错的话, 不妨点击下面的链接关注一下 : )

github 主页

知乎专栏

掘金

想直接联系我 ?

邮箱: ssthouse@163.com

目录
相关文章
|
1月前
|
前端开发 JavaScript 算法
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
transition过渡属性 早期在Web中要实现动画效果,都是依赖于JavaScript或Flash来完成。 但在CSS3中新增加了一个新的模块transition,它可以通过一些简单的CSS事件来触发元素的外观变化, 让效果显得更加细腻。简单点说,就是通过鼠标经过、获得焦点,被点击或对元素任何改变中触发, 并平滑地以动画效果改变CSS的属性值。 在CSS中创建简单的过渡效果可以从以下几个步骤来实现: 在默认样式中声明元素的初始状态样式; 声明过渡元素最终状态样式,比如悬浮状态; 在默认样式中通过添加
154 0
|
1月前
|
前端开发 JavaScript 算法
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
transform变形 css3在原来的基础上新增了变形和动画相关属性,通过这些属性可以实现以前需要大段JavaScript才能实现的 功能。 CSS3的变形功能可以对HTML组件执行位移、旋转、缩放、倾斜4种几何变换,这样的变换可以控制HTML组件 呈现出丰富的外观。 借助于位移、旋转、缩放、倾斜这4种几何变换,CSS3提供了transition动画。 transition动画比较简单,只要指定HTML组件的哪些CSS属性需要使用动画效果来执行变化,并指定动画时间,就可保证动画播放。 比transitio
117 0
|
1月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
Flex 布局 布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。 2009年,W3C 提出了一种新的方案----Flex 布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。 一、Flex 布局是什么? Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。
213 0
|
1月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
盒模型 盒模型: 所谓盒模型,就是浏览器为页面中的每个HTML元素生成的矩形盒子。 这些盒子们都要按照可见板式模型在页面上排布。 可见的板式模型主要由三个属性控制:position 属性、display 属性和 float属性。 position属性控制页面上元素间的位置关系。 display属性控制元素是堆叠、并排或者不在页面上显示。 float属性提供控制的方法,以便于把元素组成成多栏布局。 盒模型讲解: 在默认的情况下,每个盒子的边框是不可见的,背景也是透明的。 所以我们 不能直接的看到页面中的盒
135 1
|
1月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
伪类:伪类这个叫法源自于它们跟类相似,但实际上并没有类会附加到标记中的标签上。 伪类分为两种(以及新增的伪类选择器): UI伪类:会在HTML元素处于某种状态时(例如:鼠标指针位于连接上),为该元素应用CSS样式。 :hover 结构化伪类:会在标记中存在某种结构上的关系时 例如: 某元素是一组元素中的第一个或最后一个,为该元素应用CSS样式。 :not和:target(CSS3新增的两个特殊的伪类选择器)
130 1
|
1月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
上下文选择器(迭代选择器):基于祖先或同胞元素选择一个元素 ID和类选择器:基于id#和class的属性值进行选择元素。 属性选择器:基于属性的有无和特征进行选择。 ①上下文选择器: 上下文选择器的语法格式:标签1 标签2{属性:值;} //注意:组合选择器和上下文选择器的区别,组合选择器以逗号隔开, 上下文选择器以空格隔开 ②特殊的上下文选择器 子选择器> : 语法格式:标签1>标签2 解释说明:标签1和标签2
174 0
|
1月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
Animation属性 css3为Animation动画提供的几个属性如下: 属性名 属性值 animation-name 指定动画名称,该属性指定一个已有的关键帧定义。 animation-duration 指定动画持续时间。 animation-timing-funtion 指定动画变化速度。 animation-delay 指定动画延迟多长时间才开始执行。 animation-iteration-count 指定动画的循环执行次数。 animation:这是一个复合属性。
142 0
|
1月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
position定位(核心) 我们讲盒模型的时候,提到了3个属性可以用来控制页面排版。 三大属性:position属性,display属性,float属性。 position 属性控制页面上元素间的位置关系。 display 属性控制页面元素是否显示或者是堆叠还是并排显示。 float 属性提供控制方法。 通过float这种控制方法,可以实现多栏布局,导航菜单等等。 position属性是干嘛用的?怎么用?有哪些属性值? position属性控制页面上元素间的位置关系,也就是排版。 怎么用?要知道怎么用
266 1
|
1月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
继承 我们的CSS中很多的属性也是可以继承的,其中相当一部分是跟文字的相关的,比如说颜色、字体、字号。 当然还有一部分是不能继承的。 例如边框、内外边距。 层叠 层叠是CSS的核心机制。 层叠的工作机制: 当元素的同一个样式属性有多种样式值的时候,CSS就是靠层叠机制来决定最终应用哪种样式。 层叠规则: 层叠规则一:找到应用给每个元素和属性的声明。 说明:浏览器在加载每个页面时,都会据此查找到每条CSS规则, 并标识出所有受到影响的HTML元素。
65 0
|
7月前
|
前端开发

热门文章

最新文章

  • 1
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
    142
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
    154
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
    117
  • 4
    (CSS)使用Flex布局,帮助你快速了解各种基本的Flex布局属性以及帮你让元素快速达到布局中的指定位置!
    91
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
    213
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
    266
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
    134
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
    65
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
    130
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
    174