当前位置: 首页 > 编程日记 > 正文

深入解析CSS样式层叠权重值

本文为转载内容,源地址:http://www.ofcss.com/2011/05/26/css-cascade-specificity.html

读到《重新认识CSS的权重》这篇,在文章最后给出了便于记忆的顺序:

important > 内联 > ID > 类 > 标签 | 伪类 | 属性选择 > 伪对象 > 通配符 > 继承”。

那么这个顺序是怎么得出来的呢?实际上在CSS2规范关于具体性(specificity)的定义中,描述是非常明确的,但是很多中文版本的 CSS 图书中采用了 10 进制的简单相加计算方式(包括第一版《CSS 权威指南》,第二版中已经纠正)。因此把规范中对CSS层叠优先级的相关定义意译一下,希望给初入门或对权重计算尚有疑惑的朋友提供一些参考。

根据 CSS 规范,具体性越明确的样式规则,权重值越高。计算权重值的依据,并不是许多文章所描述的那样“class是10,标签是1,ID是100”之类——虽然这样在大多数情况下能够得到正确的结果。

选择器权重值的计算

  • A:如果规则是写在标签的style属性中(内联样式),则A=1,否则,A=0. 对于内联样式,由于没有选择器,所以 B、C、D 的值都为 0,即 A=1, B=0, C=0, D=0(简写为 1,0,0,0,下同)。
  • B:计算该选择器中ID的数量。(例如,#header 这样的选择器,计算为 0, 1, 0, 0)。
  • C:计算该选择器中伪类及其它属性的数量(包括类选择器、属性选择器等,不包括伪元素)。 (例如, .logo[id='site-logo'] 这样的选择器,计算为 0, 0, 2, 0)。
  • D:计算该选择器中伪元素及标签的数量。(例如,p:first-letter 这样的选择器,计算为0, 0, 0, 2)。

CSS2 规范中给出的一些例子:

 1 * {} /* a=0 b=0 c=0 d=0 -> specificity = 0,0,0,0 */
 2 li {} /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */
 3 li:first-line {} /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
 4 ul li {} /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
 5 ul ol+li {} /* a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */
 6 h1 + *[rel=up]{} /* a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 */
 7 ul ol li.red {} /* a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 */
 8 li.red.level {} /* a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */
 9 #x34y {} /* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */
10 style="" /* a=1 b=0 c=0 d=0 -> specificity = 1,0,0,0 */

根据这样的定义,所以很多文章简单地把规则归纳为:内联样式的权重值是1000,ID选择器的权重值是100,class选择器的权重值是10,标签选择器的权重值是1. 整条规则中的所有选择器权重值相加得到整个样式规则的权重值,数字越大权重值越高。

大多数情况下,按照这样的理解得出的结论没有问题,但是遇到下面这样的情况就出现问题了:

/* 样式一 */
body header div nav ul li div p a span em {color: red}/* 样式二 */
count {color: blue}

按照错误的计算方法,样式一的权重值是11,样式二的权重值是10,如果这两条规则用于同一个元素,则该元素应该是红色。实际结果却是蓝色。

权重值的比较

按照四组计算的正确方法,上面例子中的样式一权重值应该是 0, 0, 0, 11,样式二的权重值是 0, 0, 1, 0。

根据规范,计算权重值时,A, B, C, D 四组值,从左到右,分组比较,如果 A 相同,比较 B, 如果 B 相同,比较 C, 如果 C 相同,比较 D, 如果 D 相同,后定义的优先。

样式二和样式一的 A、B 相同,而样式二的 C 大于样式一,所以,不管 D 的值如何,样式二权重值都大于样式一。这就是正确的答案。

特殊的 !important

在按照 ABCD 四组计算比较之外,在定义样式的时候,还可以对某一个属性应用 !important. 对于一直从事编程而没做过重构的人,需要特别注意的是这里的 "!" 与其在编程语言中的意义刚好相反,不是代表“不重要”而是代表“很重要”。

CSS2 规范中规定:!important 用于单独指定某条样式中的单个属性。对于被指定的属性,有!important 指定的权重值大于所有未用 !important 指定的规则。

例如:

/* 样式一 */
#header nav ul li.current {color: red; font-weight: bold;}/* 样式二 */
li:hover {color: blue !important; font-weight: normal;}

就整条规则而言,样式一的权重值为 0, 1, 1, 3,而样式二的权重值仅为 0, 0, 0, 2。所以应用于相同元素时,应该样式一生效。但是对于 color 这个属性,由于在样式二中用 !important 做了指定,因此color 将应用样式二的规则。而 font-weight 则按照规定用样式一的规则。

如果多条规则中都对同一个属性指定了 !important 呢?这时候 !important 的作用相互抵销,依然按照ABCD四组计算比较。

因此 !important 的作用只有在具有唯一性时才能提现,但是我们永远无法预料自己什么时候又需要覆盖一个已经指定了 !important 的属性,所以最好的办法就是:不要使用 !important.

关于 inherit

除了直接指定到元素上的样式规则以外,每个属性值还有一个可能为 inherit(继承) 的值。表示元素的该样式属性继承自父级元素,与父级元素的定义一致。比如:

<style>.list .item { color: red }</style>
<ul class="list"><li class="item"><span>某些文字</span></li>
</ul>

上例中,样式规则并未针对 span 标签指定 color 属性, 但是 span 中的文字会显示为红色, 这就是因为 span 的 color 属性默认值为 inherit.

对于 inherit 的属性,只要记住一点: 继承而来的属性值,权重永远低于明确指定到元素的定义。只有当一个元素的某个属性没有被直接指定时,才会继承父级元素的值。例如:

<style>span { color: blue }.list .item { color: red }</style>
<ul class="list"><li class="item"><span>某些文字</span></li>
</ul>

同样的例子, 第一条规则的权重是 0,0,0,1, 第二条规则的权重是 0,0,2,0. 虽然第二条规则的权重更高,但是它是针对 li 元素的直接指定,并不是针对 span 元素定义的,所以计算 span 的 color 属性权重值时,实际上就是 inherit 的红色与直接指定的蓝色的对比。按照规则,只要有直接指定的值(蓝色),就不会再取继承的值(红色),所以 span 中的文字显示为蓝色。

这条规则最典型的场景就是链接文字的颜色。由于一般浏览器自带的样式表都有针对 a 标签的颜色及下划线的直接指定,所以网页样式表中对 a 标签的父级元素指定 color 属性及 text-decoration 属性,通常不会起作用。但是我们可以通过下面的 reset 来改变这一点:

<style>
a { color: inherit; text-decoration: inherit }
.item { color:red }
</style>
<p class="item"><a href="#">链接文字</a></p>

在上例中,由于我们的样式表对 a 标签直接指定了 color 和 text-decoration 属性值, 覆盖了浏览器的默认样式,所以在没有特别指定 a 标签的颜色和下划线定义的前提下, 会从父级元素 p 继承,因此链接会显示为红色(有补充)。

特别补充:inherit 在 CSS1 规范中并未定义,所以 IE6, IE7 以及 IE8 的 QuirksMode 不支持。

总结

  1. 一条样式规则的整体权重值包含四个独立的部分:[A, B, C, D];
  2. A 表示内联样式,只有 1 或者 0 两个值;
  3. B 表示规则中 ID 的数量;
  4. C 表示规则中除了 ID、标签和伪元素以外的其它选择器数量;
  5. D 表示规则中标签和伪元素的数量;
  6. 比较时从高位到低位(从 A 到 D)分别比较,高位相同才需要比较低位;
  7. 有 !important 标记的属性权重值无视没用 !important 指定的一切情况;
  8. 多次指定 !important 时,相互抵销。
  9. inherit 而来的属性定义,优先级低于任何直接指定的属性值。

转载于:https://www.cnblogs.com/freefish12/p/4763841.html

相关文章:

VUE做一个公共的提示组件,显示两秒自动隐藏,显示的值父组件传递给子组件

需求&#xff1a;VUE做一个公共的提示组件&#xff0c;显示两秒自动隐藏&#xff0c;显示的值由父组件动态传给子组件。 效果图&#xff1a; 实现步骤&#xff1a; 1.创建一个子组件 Toptips.vue (它就是公共提示组件)&#xff0c; optips.vue代码如下&#xff1a; <temp…

Linux课堂随笔---第四天

用户账户简介 在Linux系统中有三大类用户&#xff0c;分别是root用户&#xff0c;系统用户和普通用户。 在Linux系统中&#xff0c;root用户UID为0&#xff0c;root用户的权限是最高的&#xff0c;普通用户无法执行的操作&#xff0c;root用户都能完成。所以也被称为超级用户。…

初级开发人员的缺点_作为一名初级开发人员,我如何努力克服自己的挣扎

初级开发人员的缺点by Syeda Aimen Batool通过Syeda Aimen Batool 作为一名初级开发人员&#xff0c;我如何努力克服自己的挣扎 (How I’m working to overcome my struggles as a junior developer) I believe the other name for coding is the “struggle”. And if you ar…

lintcode-136-分割回文串

136-分割回文串 给定一个字符串s&#xff0c;将s分割成一些子串&#xff0c;使每个子串都是回文串。 返回s所有可能的回文串分割方案。 样例 给出 s "aab"&#xff0c;返回 [ ["aa", "b"], ["a", "a", "b"] ] 标…

微信小程序把繁琐的判断用Js简单的解决

场景&#xff1a; 订单列表&#xff0c;有很多种订单状态&#xff0c;根据不同的订单状态要显示不同的css。 适用场景&#xff1a;需要根据数组下标判断不同的显示。 示例代码&#xff1a; this.data.order [{"_type":"1","custName":"…

数论(Lucas定理) HDOJ 4349 Xiao Ming's Hope

题目传送门 题意&#xff1a;求C (n,0),C (n,1),C (n,2)...C (n,n)中奇数的个数 分析&#xff1a;Lucas 定理&#xff1a;A、B是非负整数&#xff0c;p是质数。AB写成p进制&#xff1a;Aa[n]a[n-1]...a[0]&#xff0c;Bb[n]b[n-1]...b[0]。则组合数C(A,B)与C(a[n],b[n])*C(a[n-…

docker容器虚拟化技术_Docker,虚拟机和容器的全面介绍

docker容器虚拟化技术by shota jolbordi通过Shota Jolbordi Docker has been a buzzword for tech people for the last several years, and the more times goes by, the more often you hear about it. We’re seeing it more in job requirements, and more companies are …

IOS中的响应者链

响应者链就是当子视图不响应,父视图有响应事件,父视图响应 #import "RootViewController.h" #import "ResponderView.h" interface RootViewController ()endimplementation RootViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additi…

MySQL闪退问题的解决

刚刚学习了数据库&#xff0c;并且安装了MySQL&#xff0c;正当高兴之余&#xff0c;发现我的MySQL出现了闪退的显现。上网搜了好久的解决方案。最后解决了这个问题&#xff0c;也舒心了。 问题从这里开始&#xff1a; 接着我打开MySQL&#xff0c;寻思能不能用&#xff0c;结果…

HTML封装AJAX请求,在请求里面写登录的逻辑 ajax 网络请求 post

调用方法&#xff1a; 先引用config.js&#xff0c;然后调用封装网络请求。 里面三个参数 1.url&#xff0c; 2.请求需要提交的数据, 3.请求类型 // 获取二维码、背景图片接口 getScheduleInfo() {var url /v1/basketball/getQRCode.do;var params {phone: 13977284414}co…

oye pandora_我尝试了Pandora出色的功能优先级排序方法。 这是我学到的。

oye pandoraby Josh Temple通过乔什坦普尔 我尝试了Pandora出色的功能优先级排序方法。 这是我学到的。 (I tried Pandora’s brilliant method for feature prioritization. Here’s what I learned.) 潘多拉(Pandora)的方法和3美元的便签纸如何使利益相关者的管理变得轻而易…

2016-2017-2软件工程课程总结

2016-2017-2软件工程课程总结 本学期的软件工程课程终于在大家的共同努力下圆满落幕了&#xff0c;我们的暑假也正式开启&#xff0c;终于有时间写写这门课的总结了。 在2016年下半学期末的时候课程组就决定使用邹欣老师的书《构建之法》&#xff0c;由课程组长王瑞老师带领入构…

asp.net mvc jqgrid 同一个页面查询不同的表,jqgrid显示不同表的表头和数据并且分页...

基于我上一篇文章<a href"http://www.cnblogs.com/alasai/p/4765756.html">asp.net mvc excel导入</a>中不同的部门上传不同的excel文件类型&#xff0c;当在同一个页面查询时怎么办呢。 解决方案&#xff1a;根据传过来的表名和时间参数一次性把数据全部…

降维后的高维特征的参数_高维超参数调整简介

降维后的高维特征的参数by Thalles Silva由Thalles Silva 高维超参数调整简介 (An introduction to high-dimensional hyper-parameter tuning) 优化ML模型的最佳做法 (Best practices for optimizing ML models) If you ever struggled with tuning Machine Learning (ML) mo…

细细品味大数据--初识hadoop

初识hadoop 前言 之前在学校的时候一直就想学习大数据方面的技术&#xff0c;包括hadoop和机器学习啊什么的&#xff0c;但是归根结底就是因为自己太懒了&#xff0c;导致没有坚持多长时间&#xff0c;加上一直为offer做准备&#xff0c;所以当时重心放在C上面了&#xff08;虽…

js中Array数组中的常用方法汇总

Array的push与unshift方法性能比较分析从原理就可以知道&#xff0c;unshift的效率是较低的。原因是&#xff0c;它每添加一个元素&#xff0c;都要把现有元素往下移一个位置。unshift比push要慢差不多100倍&#xff01;Array有一个叫做reverse的方法&#xff0c;能够把一个数组…

vue写一个通用的toast弹窗 toast 弹窗 提示

效果图 代码 <!DOCTYPE html> <html lang"en"><head><title>弹窗</title><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0, user-scalableno, minimum-s…

我对Node.js Core的首次贡献中学到了什么

by Yael Hermon通过Yael Hermon 我对Node.js Core的首次贡献中学到了什么 (What I Learned from My First Contribution To Node.js Core) A couple of weeks ago my very first PR for Node.js core was merged! A few days later, I decided to tweet about it and share ho…

SHA204A加密芯片配置

1、参考配置文章&#xff1a;http://blog.csdn.net/a5882230/article/details/522148452、可以选slot configuration 1作为密钥区&#xff0c;该区的配置应为&#xff1a;0x81 81&#xff0c;对应的data 0的数据就密钥数据。3、slot configuration的配置有7个参数&#xff0c;其…

[剑指offer] 二叉搜索树的后序遍历序列

二叉搜索树的后序遍历序列 P157 题目&#xff1a;输入一个数组&#xff0c;判断这个数组是不是一个二叉搜索树的后序遍历的结果。 solution&#xff1a;我们知道后序遍历序列的最后一个item是根节点&#xff0c;如果确实是二叉搜索树的后序遍历结果&#xff0c;那么在[0,N-2]中…

HbuilderX中的git的使用 git HbuilderXgit HbuilderX 使用git

【前戏】&#xff1a;得在HubilderX中找到 "工具"->"插件安装" -> "Git插件" 。 【提交代码】&#xff1a;&#xff08;1&#xff09;选中该项目的文件&#xff0c;右键&#xff0c;Git提交 &#xff08;2&#xff09;填写提交信息、查看…

Swift与Objective-C:与恐龙有关的趋势

by Colin Smith通过科林史密斯 Swift与Objective-C&#xff1a;与恐龙有关的趋势 (Swift vs. Objective-C: The trending up-and-comer vs. the dinosaur) Swift的简短历史 (A short history of Swift) I remember how pivotal it was when Swift was introduced at Apple’s …

我的JavaScript学习笔记

1. 那些老旧的实例可能会在 <script> 标签中使用 type"text/javascript"。现在已经不必这样做了。JavaScript 是所有现代浏览器以及 HTML5 中的默认脚本语言。 2. <head> 或 <body> 中的 JavaScript 您可以在 HTML 文档中放入不限数量的脚本。 …

获取枚举值上的Description特性说明

/// <summary> /// 获取枚举值上的Description特性说明 /// </summary> /// <typeparam name"T">枚举类型</typeparam> /// <param name"obj">枚举值</param> /// <returns></returns> public static str…

微信小程序实时获取用户经纬度

注意&#xff0c;使用这个功能之前手机得先打开位置信息。 现在app.json配置 {"pages": ["pages/map/map","pages/index/index","pages/register/register","pages/logs/logs"],"window": {"backgroundTex…

pwa js_如何在互联网信息亭中实现PWA和Barba.js

pwa jsby Nino Mihovilić由NinoMihovilić 如何在互联网信息亭中实现PWA和Barba.js (How to Implement a PWA and Barba.js into internet kiosks) The project we’ll describe here is an interactive internet kiosk that’s used as an extension for the LikeUs mobile …

Vant 组件库(VUE)的使用 Vant滚动选择器 选择器 传值

在 vue- cli 项目中安装 官方文档链接 npm ( 后面内容需要在控制台终端输入) # 通过 npm 安装 npm i vant -S 自动按需引入组件&#xff1a;babel-plugin-import 是一款 babel 插件&#xff0c;它会在编译过程中将 import 的写法自动转换为按需引入的方式 # 安装插件 npm…

MySQL的安装过程

&#xfeff;&#xfeff;近期对MySQL做了一些研究。曾经主要接触的是SQL SERVER。所以&#xff0c;今天对该安装过程做了一些总结以及使用过程中的一些心得。并分享给大家。记得前面。分享过一篇关于数据库的几种连接方式。而本系列文章。将以对数据库的详细操作为主。 MySQL是…

一个球从100米高度自由落下,每次落地后反弹回原高度的一半; * 再落下,求在第几次之后反弹高度小于0.1米, * 并计算在这一次落地时共经过多少米?...

package com.db2;/*** 一个球从100米高度自由落下&#xff0c;每次落地后反弹回原高度的一半&#xff1b; * 再落下&#xff0c;求在第几次之后反弹高度小于0.1米&#xff0c;* 并计算在这一次落地时共经过多少米&#xff1f;* * author denny**/ public class Demo1 {static …

在遗传算法中出现等式约束_排序算法中的稳定性-等式的处理

在遗传算法中出现等式约束by Onel Harrison通过Onel Harrison 排序算法中的稳定性-等式的处理 (Stability in Sorting Algorithms — A Treatment of Equality) Algorithms are at the heart of computer science. Algorithms used for sorting are some of the most fundamen…