How Element Selector Is More Specific Than Id Selector

How element selector is more specific than id selector?

To understand CSS specificity, read The Specificity Wars. There’s a handy reference sheet, too:

Sample Image

So, a selector like #foo would have 1,0,0 specificity, while an element selector like p would have 0,0,1 specificity. Out of these two, the ID selector would “win” as 100 is greater than 1.

A more specific (heh) version which also includes pseudo-elements and pseudo-classes can be found here: http://www.standardista.com/css3/css-specificity/

Sample Image

Is an attribute selector for the ID attribute less specific than an ID selector?

An attribute selector will always be less specific than an ID selector; its specificity value does not change based on the attribute name. Selectors only maps specific attribute names to class selectors and ID selectors; an attribute selector is a generic concept and does not contain any such mappings.

The only way for a complex selector to have ID specificity is if it contains one or more ID selectors. Implementation limits aside, it is theoretically not possible to override even a single ID selector with any number of attribute selectors or any other type of simple selector.

Here is how your two selectors compare:

/* 1 attribute, 2 types -> specificity = 0-1-2 */
html div[id^="blue"] {
background-color: blue
}

/* 1 ID -> specificity = 1-0-0 */
#blue4 {
background-color: red
}

Even the addition of html doesn't help because it's just a type selector. Change it to :root and you get a pseudo-class which is equally specific to an attribute selector, and thus still less specific than an ID.

How does a strong selector override an id selector? Isn't an id selector considered more specific?

You are correct with specificity, but selectors only work with the direct content of the element. So the text color is different for the strong elements because it is nested deeper and the p selector isn't able to change the color for those elements. So if you did want to change the strong elements for #abc you would do it like this

strong { color: red; }

#abc strong { color: blue; }

and if you wanted strong tags text to be the same as the p text then you would do this

#abc, #abc strong { color: red; }

strong { color: red; }#abc strong {  color: blue; }#def, #def strong { color: red; }
<p id="abc">  <strong>C</strong>ascading  <strong>S</strong>tyle  <strong>S</strong>heets</p><p id="def">  <strong>ABC</strong>DEF</p>

Why is this 11 class selector less specific than the ID?

Because the CSS specificity point system is exactly as you have specified:

  • Style attribute: 1,0,0,0
  • ID: 0,1,0,0
  • Class, pseudo-class, attribute selector: 0,0,1,0
  • Element: 0,0,0,1

Specificity

The commas are there to remind us that this isn't really a "base 10" system, in that you could technically have a specificity value of like 0,1,13,4 - and that "13" doesn't spill over like a base 10 system would.

Your ID selector is 0,1,0,0, and your combined class selector is 0,0,11,0.

At no point will any combination of class selectors ever override a single ID selectors, as is seen in the following:

#box {  width: 100px;  height: 100px;  background-color: #ff0; /* yellow */}
.one.two.three.four.five.six.seven.eight.nine.ten.eleven { background-color: #f00; /* red */}
<div id="box" class="one two three four five six seven eight nine ten eleven"></div>

CSS specificity: [parent ID] [descendant combinator (space)] [my class] more specific than [my ID]?

[My ID] is more specific than [parent ID]

No, a lone ID is a lone ID. What's important in your example is which element it is being applied to.

[parent ID] [descendant combinator (space)] [my class] more specific than [my ID]

Yes, it's valid, and it is more specific. Using the W3C's abc model:

#child { // 1, 0, 0 = 100 Specificity }

#parent .foo { // 1, 1, 0 = 110 Specificity }

#parent #child { // 2, 0, 0 = 200 Specificity }

#parent #child.foo { // 2, 1, 0 = 210 Specificity }

So, #parent .foo will trump #child, but #parent #child trumps #parent .foo

#parent { /* 100 */  color: blue;}#parent .foo { /* 110 */  color: green;}#child { /* 100 */  color: red;}#parent #child { /* 200 */  color: aqua;}
<div id="parent">  <div id="child" class="foo bar">what color am I?</div></div>

Why ID has stronger meaning than Class in CSS styling even if declared before the Class

This is to do with the complicated world of "Specificity"...

ID's are more specific than classes and take precedence over them. This is because ID's have to be UNIQUE on every page...so they are by nature very specific. Classes can appear multiple times.

Learning how this works is fundamental to coding CSS. Some people say you should try to avoid using ID's altogether as they are so specific they tend to cut down reuse.

A rule of thumb might be to use ID's to identify large sections of your page, or important items and classes to attach styles to the other things.

These days with html5 we have <section>, <header> and <footer> whereas we used to use div's for those (with ID's normally) so these days the ID is used less than ever since we can target those things directly.

However consider ID-ing sections: <section id="mainContent"> for example is a fairly standard thing to do.

There are no RULES about how to specifically (excuse the pun) use ID's and classes. Just conventions that have built up over time.

see: https://developer.mozilla.org/en/docs/Web/CSS/Specificity ... here is a section:

The concept

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.

How is it calculated?

Specificity is a weight that is applied to a given CSS declaration,
determined by the number of each selector type in the matching
selector. When specificity is equal to any of the multiple
declarations, the last declaration found in the CSS is applied to the
element. Specificity only applies when the same element is targeted by
multiple declarations. As per CSS rules, directly targeted element
will always take precedence over rules which an element inherits from
its ancestor.

How is the * CSS rule more specific than a class or ID style rule?

The * is a universal selector and overriding the settings on #profileMessageBoxHeader. It's the same as manually setting BODY, H1, P, TABLE, TR, TD, TH, PRE, UL, LI, ETC. For more information on it and how it can circumvent inheritance, Eric Meyer has a good article.

Apply the following and it should work:

#profileMessageBoxHeader p
{
color: #FFF;
}

Sample: http://jsfiddle.net/x7AnM/

Specificity order of CSS tag selectors with equal specificity

Specificity matters when two or more selectors are matching the same element – not the case here.

e.g.:
in the example below the more specific selector div#id.class won't win against h1 because they are referring to two distinct elements, so the color of h1 is determined by the first rule

h1{    color: blue;}
div#id.class { color: red;}
<html><head></head><body>    <div id="id" class="class">        <h1>This is the title</h1>    </div></body></html>

Understanding specificity: achieving desired selector outcomes without using !important

A class has a specificity of 10. An element has a specificity of 1.

Therefore, in the first instance:

  • the .main li a selector has a specificity of 12.
  • the .active a selector has a specificity of 11

Because they both target the same element, and the former has a higher specificity, the latter loses the battle to style the element.

In the second instance:

  • the .primary p selector has a specificity of 11.
  • the .copyright selector has a specificity of 10.

Again, because they both target the same element, and the former has a higher specificity, the latter loses the battle to style the element.

The !important annotation trumps all specificity. Hence, with that applied, .active a and .copyright re-take the elements.

If you want to remove !important, which would be the right thing to do as it's not necessary here, you can instead boost the specificity of the selectors.

An ID has a specificity of 100. So that can quickly move a selector up in priority.

Here are some examples:

.main li a      { color: #7ab2c1; }  /* previous winner; specificity 12 */.main .active a { color: #ff0000; }  /* added class selector; specificity now 21 */.primary p      { font-size: 12px; } /* previous winner; specificity 11 */#copyright      { font-size: 8px;} /* switched to ID selector; specificity now 100 */
<nav class="main">  <ul class="group">    <li class="active"><a href="#">Home</a></li>    <li><a href="#">About</a></li>    <li><a href="#">Contact</a></li>  </ul></nav><footer class="primary">  <p><a href="#">Sign up</a> for our newsletter, it's a racket!</p>  <p id="copyright">Copyright © Sven's Snowshoe Emporium.                    All Rights Reserved.</p></footer>


Related Topics



Leave a reply



Submit