In-depth understanding of the calculation of CSS selector precedence

Source: Internet
Author: User
Tags comparable

the priority of the selector relates to which style the element applies. This is described in the CSS2.1 specification (http://www.w3.org/TR/2009/CR-CSS2-20090908/cascade.html#specificity):

    1. If the declaration comes from a "style" property instead of a rule with a selector, it is recorded as 1, otherwise it is 0 (= a) (the HTML element's style property is also a style rule because these style rules do not have selectors and are therefore recorded as A=1,b=0,c=0,d=0)
    2. Count the number of ID attributes in the selector (= b)
    3. Count the number of other properties (classes, property selectors) and pseudo-classes in the selector (= c)
    4. Count The number of element names and pseudo-elements in the selector (= d)

Connect the four numbers as a-b-c-d (in a large digital system) to prioritize the selectors.

In the latest selector Level 3 specification:

    1. Count the number of ID attributes in the selector (= a)
    2. Count the number of other properties (classes, property selectors) and pseudo-classes in the selector (= b)
    3. Count The number of element names and pseudo-elements in the selector (= c)
    4. Ignore Universal selectors *
connect the three numbers as a-b-c (in a large digital system) to prioritize the selectors. The Style property calculates the reference css2.1 specification.  Questions:1, the overall priority of the selector how to calculate, is like online said A*1000+b*100+c*10+d? answer: No. This answer is obviously words too literally. Level Four (A, B, C, D) is not a simple additive relationship. The same level (for example: A to a) has a comparable relationship.  Analysis:The following is the code for priority calculations in WebKit WebCore (http://trac.webkit.org/browser/trunk/Source/WebCore/css/CSSSelector.cpp )
unsigned cssselector::specificity ()Const{    //Make sure the result doesn ' t overflow    Static Constunsigned maxvaluemask =0xFFFFFF;//The maximum value of the entire selector, in decimal notation: IDMask + classmask + elementmak = 16777215     Static Constunsigned IDMask =0xff0000;//The maximum value of the ID selector, in decimal notation: (16*16+16) *16^4=16711680     Static Constunsigned classmask =0xff00the maximum value of the//class (pseudo class, Class) selector, in decimal notation: (16*16+16) *16^2=65280Static Constunsigned elementmask =0xFF;//The maximum value of the element selector, in decimal notation: 16*16+16=255if(Isforpage ())returnSpecificityforpage () &Maxvaluemask; Unsigned total=0; Unsigned temp=0;  for(Constcssselector* selector = This; Selector selector = selector->taghistory ()) {Temp= Total + selector->Specificityforoneselector (); //Clamp each component to their max in the case of overflow.        if(Temp & IDMask) < (Total &IDMask)) Determines whether the ID selector is total|=IDMask;//Ensure that the same overlay of the ID selector does not exceed the total maximum value of the ID selector, asElse if(Temp & Classmask) < (Total &classmask)) Total|=Classmask; Else if(Temp & Elementmask) < (Total &elementmask)) Total|=Elementmask; Else Total=temp; }    returnTotal ;} 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) { CaseId:return 0x10000;//ID selector weights CasePseudoclass://Fixme:psuedoany should base the specificity on the sub-selectors. // Seehttp://lists.w3.org/Archives/Public/www-style/2010Sep/0530.html        if(Pseudoclasstype () = = Pseudoclassnot &&selectorlist ())returnSelectorlist ()->first ()Specificityforoneselector ();    Fallthrough;  CaseExact: CaseClass: CaseSet: CaseList: Casehyphen: Casepseudoelement: Casecontain: CaseBegin: CaseEnd:return 0x100;//class selector weights CaseTag:return(Tagqname (). LocalName ()! = Staratom)?1:0;//element selector weights CaseUnknown:return 0;    } assert_not_reached (); return 0;}
As can be seen from the above code, in WebKit, for a-level selector (style rule for the "style" attribute), the process of not participating in the priority operation at all. For Class B (ID selector), Class C (class selector), Class D (element selector), each level has its own maximum (maximum number of 255), and its maximum value (maximum) is applied when it is exceeded. The B-Class maximum value is 0xff0000 (16711680), with a weight of 0x1000 (65536), and the maximum value is still used when the number exceeds 256. C-Class, D-class similar. Therefore, there is no situation where the lower level exceeds a certain number, resulting in a high one-step-up coverage . In a selector group (em: #a. D div), all selectors will not have more than 16777215 plus and no more than one (each class of selectors guarantees that the maximum value is not exceeded). DEMO:HTTP://JSBIN.COM/DUKER/2. For! Important,webkit is another path to go (with! Important style rules are greater than no! Important style rules are only available at the same time! The important property is compared to the overall priority of the selector). Overall, in the WebKit,!important>inline Style>id>class>tag. WebKit is in http://trac.webkit.org/changeset/130444/trunk/Source/WebCore/css/. CSSSelector.cpp this one, plus the handling of the priority overflow (the chrome release is very fast, this year we switched to blink, and you can assume that chrome adheres to the specific (priority) calculation criteria):
Timestamp
: 2012-10-04 19:04:44 (20 months ago) Author: [Email protected] message:

Selector specific category overflow to high category
? https://bugs.webkit.org/show_bug.cgi?id=98295

Patch by Tab Atkins <? [email protected]> on 2012-10-04
Reviewed by Eric Seidel.

This time the patch was added to add an overflow policy for the specifics of the CSS selector.

Previously, we did not detect the specific overflow problem for each category. The original strategy is to store each category as one byte (2^8=256), and then there is a whole number of unsigned integers. This will result in 256 single selectors of the same category equal to 1 high class selectors. However, this violates the special rules of selectors, resulting in the sorting of style rules.

Tests:/fast/selectors/specificity-overflow.html

  • Css/cssselector.cpp:

(webcore::cssselector::specificity):

The code for priority calculation in Mozilla (address http://hg.mozilla.org/mozilla-central/file/7297dedf2416/layout/style/StyleRule.cpp (472 lines-537 lines)):
int32_t nscssselector::calcweightwithoutnegations ()Const{int32_t weight=0; #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"); #elseMoz_assert (! (Ispseudoelement () &&mclasslist),"If pseudo-elements can have class selectors"              "After them, specificity calculation must be updated"); #endifMoz_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 was 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; }   returnweight;} int32_t nscssselector::calcweight ()Const {   //Loop over this selector and all its negations.int32_t weight =0;  for(ConstNscssselector *n = This; N n = n->mnegations) {Weight+ = N->calcweightwithoutnegations (); }   returnweight;}
Like WebKit, the inline style element does not count toward calculations. The maximum and minimum values for B-level (ID), C-Class, Class-D (tag) are also consistent with WebKit. The difference is that in Mozilla there is no maximum control for the same category of selectors, but the results are added directly. This results in a higher number of same-level selectors than 255, which is a result overflow problem.       And the priority calculation for the whole selector group because there is no webkit-like bitwise AND operation to ensure that the results do not overflow, but simply add, in the Mozilla can overflow problems. Because IE can't read the code, the IE series can only take the demo test method to confirm the problem. In all IE series (q, s), the performance is consistent with Mozilla. Includes the latest IE11. Note: CSS selectors also have an inheritance:

<! DOCTYPE html>
<meta charset= "Utf-8" >
<title>js bin</title>
<style>
*{font-size:40px;}
#test {font-size:12px!important;}
p {font-size:24px;}
</style>
<body>
<div id= "Test" ><p>test text</p></div>
</body>

The text in all browsers will be applied to P {font-size:24px;}. If you remove this sentence, you will apply *{font-size:40px;},* including p. (Inherited styles have no precedence)

Conclusion:

1, priority calculation when the cross-level add should pay attention to overflow problem;

2, priority calculation does not include inline style and!important;

3. Priority calculations are comparable only in the same category (typically no one defines a single selector that exceeds 255).

Close this article by quoting an answer on StackOverflow:

I am currently using the book CSS mastery:advanced WEB standards Solutions.

Chapter 1, page says:

To calculate how specific a are, each of the type of selector is assigned a numeric value. The specificity of a rule is then calculated by adding up the value of all of its selectors. Unfortunately, specificity is isn't calculated in base and a high, unspecified, base number. This was to ensure a highly specific selector, such as an ID selector, was never overridden by lots of less specific SE Lectors, such as type selectors.

Reference article:http://trac.webkit.org/browser/trunk/Source/WebCore/css/CSSSelector.cpphttp://hg.mozilla.org/mozilla-central/ file/17c65d32c7b8/layout/style/stylerule.cpp#l521 Browser works: A new web browser behind the scenes kb005:css Cascade

In-depth understanding of the calculation of CSS selector precedence

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.