18

The markup below aligns SAMPLE TEXT to the left.

To me, it seems like it should be aligned to the right. The class that aligns to the right is declared after the one that aligns left. And the class that aligns to the right is even referenced last. So why does the class that aligns to the left win?

CSS

.table {
    width: 100%;
}
.table td {
    text-align: left;
}
.cell {
    text-align: right;
}

HTML

<table class="table">
    <tr>
        <td class="cell">
             SAMPLE TEXT
        </td>
    </tr>
</table>​

Please see my jsFiddle Example.

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466

4 Answers4

27

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.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Dagg Nabbit
  • 75,346
  • 19
  • 113
  • 141
  • Specificity values are not counted in decimal numbers. The specificity of `.table td` is *not* 11 (eleven) in base 10, but in some imaginary high base, meaning a rule with 12 type selectors isn't going to take precedence over that. So, it's weird like that. – BoltClock Mar 02 '12 at 03:30
  • 1
    Thanks. Could you clarify that last bit? If class names weigh more than tag names, doesn't that mean `.cell` outweighs `.table td`? – Jonathan Wood Mar 02 '12 at 03:32
  • 1
    @Jonathan Wood: No, in this case you have `.cell`, which is a class selector, and `.table td,` which is a class selector *plus* a type selector, so it wins. – BoltClock Mar 02 '12 at 03:33
  • 2
    @BoltClock What base are the values in if not 10? I don't think I understand what you mean. The way I read [this](http://www.w3.org/TR/selectors/#specificity), the value would be 11. Can you maybe explain this in a separate answer if you have time? – Dagg Nabbit Mar 02 '12 at 03:34
  • both are equal in a sense that both have classes (both have 1-0), but one has an element, which adds 1. so `.table td` = 1-1 (some sort of eleven) while `.cell` has 1-0 (some sort of 10). 1-1 is higher, thus `.table td` wins – Joseph Mar 02 '12 at 03:34
  • 4
    @GGG what Bolt means is that if you add up tag to 10 or more, the value will not carry over to the other digit. it goes on like 1-10, 1-11, 1-12 (class-tag) – Joseph Mar 02 '12 at 03:36
  • Wait, why is this paragraph (http://jsfiddle.net/xXaP5/) green then if IDs are 100 points and classes are 10 points? – dangerChihuahua007 Mar 02 '12 at 03:38
  • @GGG: Well, forget about the bases thing, that's mentioned by the Selectors spec but isn't a great explanation. A better way to think of this is to just count each kind of selector separately. Or see Joseph's comment. – BoltClock Mar 02 '12 at 03:38
  • @David Faux: Your class is being applied to the `

    ` element, while your ID is on the `

    `, so specificity becomes irrelevant here.
    – BoltClock Mar 02 '12 at 03:40
  • Oh, so it's got to be on the same element, otherwise selectors pertinent to the inner element wins. Thanks, got it. – dangerChihuahua007 Mar 02 '12 at 03:41
  • http://jsfiddle.net/xXaP5/1/ here's proof when styles are applied on the same element using classes and ID - ID takes precedence. – Joseph Mar 02 '12 at 03:41
  • @DavidFaux, I think you should [read the spec on inheritance](http://www.w3.org/TR/CSS2/cascade.html#inheritance). – zzzzBov Mar 02 '12 at 03:41
  • @BoltClock gotcha, so it's more like 200.30.5 or something... yeah that is weird. – Dagg Nabbit Mar 02 '12 at 03:42
  • Funnily, a day after this question was posted, somebody else asked why 13 classes don't beat an ID + 2 classes, giving me a short-lived opportunity to explain it in greater detail: http://stackoverflow.com/questions/9540339/why-cant-i-beat-an-id-with-multiple-classes – BoltClock Mar 03 '12 at 19:26
  • @BoltClock hahah, feel free to fix this one up. I started editing that stuff in and couldn't find a way to explain it that wasn't confusing or really wordy (arbitrary base numbers, etc.). – Dagg Nabbit Mar 03 '12 at 19:28
6

I highly recommend reading the actual CSS specification on specificty.

There are four levels:

  1. inline-styles, !important (a)
  2. IDs (b)
  3. classes, pseudo-classes, attribute selectors (c)
  4. element, pseudo-elements (d)

For every selector, add one to it's respective letter category:

#foo.bar baz -> a=0, b=1, c=1, d=1
#fizz#buzz   -> a=0, b=2, c=0, d=0

a trumps b trumps c trumps d.

If there's a tie the second one wins:

#foo #bar baz
#fizz #buzz baz  <-- same specificity, this one wins
zzzzBov
  • 174,988
  • 54
  • 320
  • 367
  • Inline styles are no longer part of calculating selector specificity as of level 3, as they are not selectors. – BoltClock Mar 02 '12 at 03:41
  • I hadn't known that, but after [scanning the level 3 spec](http://www.w3.org/TR/selectors/#specificity), you're right. I'm going to leave them in though because they *do* override the stylesheet values, and are important to remember in debugging specificity issues. Besides, the level 3 spec references the level 2 spec in how `[style]` values work. – zzzzBov Mar 02 '12 at 03:44
  • 1
    Indeed. That's more of a cascading issue, though, but [I should try not to confuse anyone any further](http://stackoverflow.com/a/9492857/106224). – BoltClock Mar 02 '12 at 03:51
3

styles of text-align by .table td will win over the text-align applied by cell

.table td specificity is (1-1) :

(10 x 1 class selector) + (1 x 1 element selector)

.cell specificity is (1-0) :

(10 x 1 class selector)

for .cell to win, it has to have a specificity higher than the others. It can also be equal to others but it has to be declared after the others of the same level.

read more about inheritance and specificity

Joseph
  • 117,725
  • 30
  • 181
  • 234
1

If you do

.table {
    width: 100%;
}
.table td {
    text-align: left;
    color: Yellow;
    background-color: Red;
}
td.cell {
    text-align: right;
}

it will right align http://jsfiddle.net/VTrEE/4/

Dan675
  • 1,697
  • 15
  • 15
  • Both the last two rules have same value but the last rule scanned gets the precedence thus the text aligns itself right. If you keep the '.table td' rule at the end, that will apply. – Parul Feb 23 '19 at 23:22