深入理解CSS选择器优先级的计算
选择器的优先级关系到元素应用哪个样式。在CSS2.1的规范(http://www.w3.org/TR/2009/CR-CSS2-20090908/cascade.html#specificity)中是这样描述的:
- 如果声明来自于“style”属性,而不是带有选择器的规则,则记为 1,否则记为 0 (= a)(HTML元素的style属性也是样式规则,因为这些样式规则没有选择器,因此记为a=1,b=0,c=0,d=0)
- 计算选择器中 ID 属性的个数 (= b)
- 计算选择器中其他属性(类、属性选择器)和伪类的个数 (= c)
- 计算选择器中元素名称和伪元素的个数 (= d)
将四个数字按 a-b-c-d 这样连接起来(位于大数进制的数字系统中),构成选择器的优先级。
在最新的Selector Level 3规范中:
- 计算选择器中 ID 属性的个数 (= a)
- 计算选择器中其他属性(类、属性选择器)和伪类的个数 (= b)
- 计算选择器中元素名称和伪元素的个数 (= c)
- 忽略通用选择器*
问题:
1、选择器的整体优先级如何计算,是像网上说的a*1000+b*100+c*10+d吗?
- unsigned CSSSelector::specificity() const
- {
- // make sure the result doesn't overflow
- static const unsigned maxValueMask = 0xffffff; // 整个选择器的最大值,十进制表示:idMask + classMask + elementMak = 16777215
- static const unsigned idMask = 0xff0000; // ID选择器的最大值,十进制表示:(16*16+16)*16^4=16711680
- static const unsigned classMask = 0xff00; // class(伪类、类)选择器的最大值,十进制表示:(16*16+16)*16^2=65280
- static const unsigned elementMask = 0xff; // 元素选择器的最大值,十进制表示:16*16+16=255
- if (isForPage())
- return specificityForPage() & maxValueMask;
- unsigned total = ;
- unsigned temp = ;
- for (const CSSSelector* selector = this; selector; selector = selector->tagHistory()) {
- temp = total + selector->specificityForOneSelector();
- // Clamp each component to its max in the case of overflow.
- if ((temp & idMask) < (total & idMask)) // 判断是否为ID选择器
- total |= idMask; // 保证ID选择器的同类叠加不会超过ID选择器的总最大值,下同
- else if ((temp & classMask) < (total & classMask))
- total |= classMask;
- else if ((temp & elementMask) < (total & elementMask))
- total |= elementMask;
- else
- total = temp;
- }
- return total;
- }
- inline unsigned CSSSelector::specificityForOneSelector() const
- {
- // FIXME: Pseudo-elements and pseudo-classes do not have the same specificity. This function
- // isn't quite correct.
- switch (m_match) {
- case Id:
- return 0x10000; // ID选择器权重
- case PseudoClass:
- // FIXME: PsuedoAny should base the specificity on the sub-selectors.
- // See http://lists.w3.org/Archives/Public/www-style/2010Sep/0530.html
- if (pseudoClassType() == PseudoClassNot && selectorList())
- return selectorList()->first()->specificityForOneSelector();
- FALLTHROUGH;
- case Exact:
- case Class:
- case Set:
- case List:
- case Hyphen:
- case PseudoElement:
- case Contain:
- case Begin:
- case End:
- return 0x100; // class选择器权重
- case Tag:
- return (tagQName().localName() != starAtom) ? : ; // 元素选择器权重
- case Unknown:
- return ;
- }
- ASSERT_NOT_REACHED();
- return ;
- }
时间戳:2012-10-04 19:04:44 (20个月前)作者:commit-queue@webkit.org消息:
选择器特殊性类别溢出到高类别
https://bugs.webkit.org/show_bug.cgi?id=98295Patch by Tab Atkins <jackalmage@gmail.com> on 2012-10-04
Reviewed by Eric Seidel.这一次添加的补丁是为了对于CSS选择器的特殊性添加溢出策略。
以前我们并不会检测每个类别的特殊性溢出问题。原始的策略是:把每个类别存储为一个字节(2^8=256),然后整体存在一个无符号整型数中。这样的话就会导致256个同一类别的单选择器等于1个高类别的选择器。但是这违反了选择器的特殊性规则,导致样式规则排序问题。
Tests: /fast/selectors/specificity-overflow.html
- css/CSSSelector.cpp:
(WebCore::CSSSelector::specificity):
- int32_t nsCSSSelector::CalcWeightWithoutNegations() const
- {
- int32_t weight = ;
- #ifdef MOZ_XUL
- MOZ_ASSERT(!(IsPseudoElement() &&
- PseudoType() != nsCSSPseudoElements::ePseudo_XULTree &&
- mClassList),
- "If non-XUL-tree pseudo-elements can have class selectors "
- "after them, specificity calculation must be updated");
- #else
- MOZ_ASSERT(!(IsPseudoElement() && mClassList),
- "If pseudo-elements can have class selectors "
- "after them, specificity calculation must be updated");
- #endif
- MOZ_ASSERT(!(IsPseudoElement() && (mIDList || mAttrList)),
- "If pseudo-elements can have id or attribute selectors "
- "after them, specificity calculation must be updated");
- if (nullptr != mCasedTag) {
- weight += 0x000001;
- }
- nsAtomList* list = mIDList;
- while (nullptr != list) {
- weight += 0x010000;
- list = list->mNext;
- }
- list = mClassList;
- #ifdef MOZ_XUL
- // XUL tree pseudo-elements abuse mClassList to store some private
- // data; ignore that.
- if (PseudoType() == nsCSSPseudoElements::ePseudo_XULTree) {
- list = nullptr;
- }
- #endif
- while (nullptr != list) {
- weight += 0x000100;
- list = list->mNext;
- }
- // FIXME (bug 561154): This is incorrect for :-moz-any(), which isn't
- // really a pseudo-class. In order to handle :-moz-any() correctly,
- // we need to compute specificity after we match, based on which
- // option we matched with (and thus also need to try the
- // highest-specificity options first).
- nsPseudoClassList *plist = mPseudoClassList;
- while (nullptr != plist) {
- weight += 0x000100;
- plist = plist->mNext;
- }
- nsAttrSelector* attr = mAttrList;
- while (nullptr != attr) {
- weight += 0x000100;
- attr = attr->mNext;
- }
- return weight;
- }
- int32_t nsCSSSelector::CalcWeight() const
- {
- // Loop over this selector and all its negations.
- int32_t weight = ;
- for (const nsCSSSelector *n = this; n; n = n->mNegations) {
- weight += n->CalcWeightWithoutNegations();
- }
- return weight;
- }
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<style>
*{font-size:40px;}
#test {font-size:12px !important;}
p {font-size:24px;}
</style>
<body>
<div id="test"><p>test text</p></div>
</body>
在所有浏览器中文字都会应用p {font-size:24px;}。如果把这句去掉的话,就会应用*{font-size:40px;},*包括p。(继承的样式没有优先级)
结论:
1、优先级计算时跨级相加应注意溢出问题;
2、优先级计算不包括inline style和!important;
3、优先级计算只有同一类别才具有可比性(一般也不会有人定义超出255个的同一选择器)。
I am currently using the book CSS Mastery: Advanced Web Standards Solutions.
Chapter 1, page 16 says:
To calculate how specific a rule is, each type of selector is assigned a numeric value. The specificity of a rule is then calculated by adding up the value of each of its selectors. Unfortunately, specificity is not calculated in base 10 but a high, unspecified, base number. This is to ensure that a highly specific selector, such as an ID selector, is never overridden by lots of less specific selectors, such as type selectors.
参考文章:
深入理解CSS选择器优先级的计算的更多相关文章
- 看完就懂--CSS选择器优先级的计算
CSS选择器优先级的计算 什么是选择器的优先级 优先级的计算与比较(一) - 优先级具有可加性 - 选择器优先级不会超过自身最大数量级 - 同等优先级情况下,后写的覆盖前写的 - 并集选择器之间的优先 ...
- 深入理解CSS选择器优先级
题外话 今天把 <CSS REFACTORING>(中文名叫<CSS重构:样式表性能调优>)电子书粗略的浏览了一遍,这本书很薄,150页左右,首先是介绍了什么是重构并举了两个简 ...
- css 选择器优先级的计算过程
以下转自互联网 下面看看官方对选择器的定义:一个选择器的优先级由四个数字a,b,c,d确定.当比较两个选择器时,先比较a,a值大的优先级高,如果a相等则比较b,b值大的优先级高,以此类推.因此,无论b ...
- 关于Css选择器优先级
今天练习css的时候,重叠后的style发现不起作用,原来css选择器优先级大有文章. 声明: yi下内容选自 51cto.com --加以自己的理解 以备日后参照使用,毕竟自己理解的才是自己的. ...
- CSS选择器优先级(转)
原文:http://www.cnblogs.com/wangfupeng1988/p/4285251.html 另外,w3c有文章介绍了CSS选择器的特定性,见https://www.w3.org/T ...
- day44:CSS选择器优先级&JS基础
目录 1.CSS选择器优先级 2.补充:margin是可以设置百分比的 3.JS 3.1 js代码的引入方式 3.2 变量 3.3 数据类型 3.4 数组(类似于python中的列表) 3.5 自 ...
- CSS选择器优先级总结
CSS三大特性-- 继承. 优先级和层叠. 继承:即子类元素继承父类的样式; 优先级:是指不同类别样式的权重比较; 层叠:是说当数量相同时,通过层叠(后者覆盖前者)的样式. css选择符分类 首先来看 ...
- css选择器优先级全解析
这样一个问题: <!doctype html> <htmllang="en"> <head> <metacharset="UTF ...
- CSS选择器优先级 CSS权值
计算指定选择器的优先级:重新认识CSS的权重 标签的权值为 0,0,0,1 类的权值为 0,0,1,0 属性选择的权值为 0,0,1,1 ID的权值为 0,1,0,0 important的权值为最高 ...
随机推荐
- [LeetCode] 310. Minimum Height Trees 解题思路
For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...
- WPF: How to use DatePicker in XAML-DataGrid
https://msdn.microsoft.com/en-us/library/system.windows.controls.datagridtemplatecolumn(v=VS.100).as ...
- UITableViewStyleGrouped顶部留白问题
我这样创建, ? 1 2 self.tableView = [[UITableView alloc] initWithFrame: CGRectMake(0 ...
- MySQL定时备份之使用Linux下的crontab定时备份实例
这篇文章主要介绍了使用Linux下的crontab进行MySQL定时备份的例子,需要的朋友可以参考下 复制代码代码如下: ##################################### ...
- STL之Pairs
什么是Pair 关于类Pair的介绍,下面是引自<C++ Standard Library>的一段话: The class pair is provided to treat two va ...
- IntelliJ IDEA 中module的dependencies是其它module时的注意事项
Dependencies on other modules If a module (module A) depends on another module (module B), IntelliJ ...
- 【网络流#9】POJ 2135 Farm Tour 最小费用流 - 《挑战程序设计竞赛》例题
[题意]给出一张无向图,从1开始到n,求两条没有公共边的最短路,使得路程总和最小 每条边的权值设为费用,最大流量设为1,然后就是从源点到汇点流量为2的最小费用流. 因为是规定了流量,新建一个源点和一个 ...
- mysql数据库安装方法
前言 MySQL 有三种安装方式:RPM安装.二进制包安装.源码包安装.这3种种方式各有特色,主要特点参考下表.实际应用中,可以根据你所用的主机环境进行优化,选择 最佳的配置值,安装定制更灵活.访问M ...
- 第2章 来点C#的感觉
创建控制台项目 using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...
- ASP.NET-FineUI开发实践-4(二)
在网上找了找,实验了一下window弹出和关闭的动画效果分享一下. 接上次的代码 default.js window_tips.animCollapse= true;//打开动画效果 window_t ...