A deep understanding of the calculation of CSS selector priority

Source: Internet
Author: User

The priority of the selector is related to the style applied by the element. The specification (http://www.w3.org/TR/2009/CR-CSS2-20090908/cascade.html#specificity) in CSS2.1 is described as follows:

Connect the four numbers in a-B-c-d (in a numeric system with a large number) to form the priority of the selector.

 

In the latest Selector Level 3 specification:

Connect the three numbers in a-B-c (in a numeric system with a large number) to form the priority of the selector. For details about style attribute calculation, see the css2.1 standard. Question: 1. How do I calculate the overall priority of a selector? Is it like a * 1000 + B * 100 + c * 10 + d on the Internet? A: No. This answer is obviously meaningful. Level 4 (a, B, c, d) is not a simple addition relationship. The same level (for example, a has a comparable relationship with. Analysis: The following is the code for priority calculation (http://trac.webkit.org/browser/trunk/Source/WebCore/css/CSSSelector.cpp) in webCore of webkit)
Unsigned CSSSelector: specificity () const {// make sure the result doesn't overflow static const unsigned maxValueMask = 0 xffffff; // the maximum value of the entire selector, in decimal format: idMask + classMask + elementMak = 16777215 static const unsigned idMask = 0xff0000; // the maximum value of the ID selector, in decimal format: (16*16 + 16) * 16 ^ 4 = 16711680 static const unsigned classMask = 0xff00; // the maximum value of the class (pseudo class, class) selector, in decimal format: (16*16 + 16) * 16 ^ 2 = 65280 static const unsigned elementMa Sk = 0xff; // the maximum value of the element selector, in decimal format: 16*16 + 16 = 255 if (isForPage () return specificityForPage () & maxValueMask; unsigned total = 0; unsigned temp = 0; for (const CSSSelector * selector = this; selector = selector-> tagHistory () {temp = total + selector-> specificityForOneSelector (); // Clamp each component to its max in the case of overflow. if (temp & idMask) <(total & idMask) // determines whether it is an ID selector t Otal | = idMask; // ensure that the similar superposition of the ID selector does not exceed the total maximum value of the ID selector. The same 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 qu Ite correct. switch (m_match) {case Id: return 0x10000; // ID selector weight case pseudo class: // FIXME: PsuedoAny shocould base the specificity on the sub-selectors. // See the http://lists.w3.org/Archives/Public/www-style/2010Sep/0530.html if (pseudo classtype () = pseudo classnot & selectorList () return selectorList ()-> first ()-> specificityForOneSelector (); FALLTHROUGH; case Exact: case Class: case Set: case L Ist: case Hyphen: case pseudo doelement: case Contain: case Begin: case End: return 0x100; // class selector weight case Tag: return (tagQName (). localName ()! = StarAtom )? 1: 0; // element selector weight case Unknown: return 0;} ASSERT_NOT_REACHED (); return 0 ;}
From the code above, we can see that in webkit, a class a selector (style rules of the "style" attribute) is not involved in the priority calculation process at all. For level B (ID selector), Level c (class selector), and level d (element selector), each level has its own Maximum value (up to 255)When the value is exceeded, the maximum value (maximum number) is applied ). The maximum value of Level B is 0xff0000 (16711680), and the weight is 0x1000 (65536). If the number exceeds 256, the maximum value is still used. Level c and Level d are similar. Therefore, there is no case where the number of lower-level workers exceeds a certain number, resulting in the coverage of higher-level workers.. In a selector group (em: # a. d div), the sum of all selectors does not exceed 16777215 (each type of selector ensures that the maximum value is not exceeded ). Demo: http://jsbin.com/duker/2. For! Important, webkit is another path (! Important style rules are greater than none! Important style rules, only available at the same time! When the important attribute is used, the overall priority of the selector is compared ). In general, in webkit ,! Important> inline style> ID> class> tag. Webkit is in chrome (the chrome version was released very quickly and switched to blink this year. It can be considered that chrome complies with the special (priority) Calculation Standard ):
Time stamp: 19:04:44 (20 months ago) Author: commit-queue@webkit.org message:

Selector special category overflows to high category
Https://bugs.webkit.org/show_bug.cgi? Id = 98295

Patch by Tab Atkins <jackalmage@gmail.com> on 2012-10-04
Reviewed by Eric Seidel.

The patch added this time adds an overflow policy for the special nature of the CSS selector.

In the past, we did not detect the special overflow problem of each category. The original policy is to store each category as a byte (2 ^ 8 = 256), and then the entire data is contained in an unsigned integer. In this case, 256 single selectors of the same category are equal to one high-category selector. However, this violates the special rules of selector and causes style rule sorting problems.

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 (row 472-row 537 )):
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"); #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 = 0;   for (const nsCSSSelector *n = this; n; n = n->mNegations) {     weight += n->CalcWeightWithoutNegations();   }   return weight; }
Like webkit, inline style elements are not included in the calculation. The maximum and minimum values of Level B (ID), Level c (class), and level d (tag) are also consistent with those of webkit. The difference is that in mozilla, the maximum value is not controlled for selectors of the same category, but the result is directly added. In this case, the number of single-level selectors is more than 255, and the result overflows. In addition, the Priority Calculation for the entire selector group is similar to the bitwise and operation of webkit to ensure that the result does not overflow. It is just a simple addition, which may cause overflow in mozilla. Because IE cannot read the code, the IE series can only use the demo test method to confirm the problem. In IE6 (q, s), the performance is the same as that in mozilla. In IE7 +, the performance is the same as that in webkit. Conclusion:

1. Overflow should be paid to the Cross-level addition during priority calculation;

2. Priority calculation does not include inline style and! Important;

3. Priority Calculation is comparable only for the same category (generally, no one defines the same selector with more than 255 values ).

End this article by referencing an answer from stackoverflow:

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.

Reference: CSS Cascade

Related Article

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.