Why Can't I Beat an Id with Multiple Classes

Why can't I beat an ID with multiple classes?

Simply put: an ID will always beat any number of classes, pseudo-classes, attribute selectors or type selectors, but not necessarily another ID. That's all you need to remember.

Or to get into the technical nitty gritty: specificity isn't counted in some decimal numeric base that we all use. IDs are not worth "100 points", classes/attributes/pseudo-classes are not "10 points", types/pseudo-elements are not "1 point", etc. You don't add these numbers up and compare them, mathematically, based on their sum; that's not how it works. (You do add up the individual number of IDs, number of classes/attributes/pseudo-classes, etc, but you don't add all the individual numbers up to a single total.)

The specificity of these simple selectors is counted in a rather different way. The spec says it best:

9. Calculating a selector's specificity


A selector's specificity is calculated as follows:

  • count the number of ID selectors in the selector (= a)
  • count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)
  • count the number of type selectors and pseudo-elements in the selector (= c)
  • ignore the universal selector

Selectors inside the negation pseudo-class are counted like any other, but the negation itself does not count as a pseudo-class.

Concatenating the three numbers a-b-c (in a number system with a large base) gives the specificity.

Examples:

*               /* a=0 b=0 c=0 -> specificity =   0 */
LI /* a=0 b=0 c=1 -> specificity = 1 */
UL LI /* a=0 b=0 c=2 -> specificity = 2 */
UL OL+LI /* a=0 b=0 c=3 -> specificity = 3 */
H1 + *[REL=up] /* a=0 b=1 c=1 -> specificity = 11 */
UL OL LI.red /* a=0 b=1 c=3 -> specificity = 13 */
LI.red.level /* a=0 b=2 c=1 -> specificity = 21 */
#x34y /* a=1 b=0 c=0 -> specificity = 100 */
#s12:not(FOO) /* a=1 b=0 c=1 -> specificity = 101 */

Notice that it says "concatenating" (as in joining strings together), not "adding" (as in the arithmetic sense of 2 + 2 = 4).

Notice also that it says "a number system with a large base"; this is just to illustrate that you don't take these specificity scores as decimal numbers, where 13 × 10 = 130 is greater than 1 × 100 = 100 in layman's terms.

This is how you would calculate the specificity of your selectors:

/* 1 ID, 1 class     -> specificity = 1-1-0 */
#big .little

/* 1 ID, 2 classes -> specificity = 1-2-0 */
#big .little.little

/* 0 IDs, 13 classes -> specificity = 0-13-0 */
.little.little.little.little.little.little.little.little.little.little.little.little.little

Notice now how the specificity of the third selector is less than the first two, because there are no ID selectors in use?

When comparing the other two selectors, both of which have an ID selector each, you'll see that the second selector has one more class. In this case, the second selector wins due to the extra class selector, even though each has an ID selector, because the ID selectors by themselves share equal specificity.

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>

Why do you use Class for multiple elements but ID for one?

Multiple ids violates html standards.

Modern browsers may forgive common violations such as these in an attempt to win popularity. :)

I recommend sticking to the standards over browser implementation of the standards wherever you can. The authors of the standard publish a service that will validate your html against a given html version.

http://validator.w3.org/

Trust that, rather than your browser.

Two CSS Classes: Which one Wins?

The .table td selector has a higher specificity. CSS specificity rules are kind of weird... IDs weigh more than class names, which weigh more than tag names.

The specificity rules, in a nutshell:

  • For each tag name, add 1.
  • For each class name, add 10.
  • For each ID, add 100.

The higher values will always override the lower ones. In the case of a tie, the last rule loaded wins.

Why must I specify the parent id in my CSS selector in order to redefine a margin?

Because CSS uses a concept called specificity to determine what rules apply to what elements.

  • 1 ID + 1 tag is more specific than 1 ID
  • 2 IDs is more specific than 1 ID + 1 tag

When checking which rule gets priority, go down the list here and stop on the first that applies:

  1. An inline style beats a non-inline style.
  2. A style with more IDs in its specification beats a style with fewer.
  3. A style with more classes/attributes in its specification beats a style with fewer.
  4. A style with more tags in its specification beats a style with fewer.
  5. All else being equal, a rule that comes later in the specification beats one that comes earlier.

How do I make a class take precedence over an id?

What you have there is a CSS specificity problem.

.wider has a specificity of 0,0,1,0 while #normal has 0,1,0,0. You can't beat an ID with anything else than an ID (or inline definitions, but that is not the case here).

What I would recommend, if you cannot put the needed width declaration in the #normal selector, is to put it in #normal.wider or, if that either isn't possible, have an identified container, say #container, as high in the hierarchy as possible (maybe an ID on the body?) and replace .wider with #container .wider. This new selector will have a specificity of 0,1,1,0 which is a bit higher than 0,1,0,0.

Using !important will work too, but it should be used only as a last resort.

Example:

<div id="container" class="wrapper">
<div id="normal" class="wider">
</div>

For this HTML snippet some possible selectors in decreasing order of specificity would be:

CSS Selector         -> Specificity
---------------------------------------
#container #normal -> 0,2,0,0
#container .wider -> 0,1,1,0 // These two have the same specificity so
#normal.wider -> 0,1,1,0 // the last declared value will be used
#normal -> 0,1,0,0
.wrapper .wider -> 0,0,2,0
.wider -> 0,0,1,0

CSS works for id, but not for class because of bootstrap

Chaining multiple class selectors raises the importance of the rules.

What should help:

.form-control.search {
...
}

You can also add input to the mix:

input.form-control.search {
...
}

If that doesn't help, you can keep on chaining .search (which you shouldn't generally do but Bootstrap sometimes requires that):

input.form-control.search.search.search {
...
}

CSS uses something called "specifity" to determine the importance of your rules. In simpler terms: style= is worth 1000, ID is worth 100, attributes/classes/pseudoselectors are worth 10 and tag selectors are worth 1. (It's much more complex than this, but this is generally a good rule of thumb for CSS specifity.)

Reuse classes in an id based css

You can specify multiple selectors on a given set of properties, like this:

.LinkButton , #id1 { color: red; border: solid 1px blue; } /* Both get these */
#id1 { back-color: green; } /* Adding rules */

It can also override any of the properties if you need:

.LinkButton , #id1 { color: red; back-color: red; } /* Both get these */
#id1 { back-color: green; } /* Changing rules */

Or you give the element the class and ID:

<div id="id1" class="LinkButton ">


Related Topics



Leave a reply



Submit