Precedence of multiple classes defining color property being set by declaration order rather than specification order
Asked Answered
R

2

23

Given two classes of equal specificity defining the color property I thought the last class listed in the element class attribute would take precedence.

From http://htmlhelp.com/reference/css/structure.html:

Order of Specification To make it easy, when two rules have the same weight, the last rule specified wins.

In the following vacuum code example the order in which the class rule set is defined determines precedence. Here the last, or most recent, class rule set definition takes precedence.

<style>
    .makeBlue {color: blue;}
    .makeGreen {color:green;}
</style>
<div>
    <p class="makeGreen makeBlue">makeGreen makeBlue</p>
    <p class="makeBlue makeGreen">makeBlue makeGreen</p>
</div>

The output text is green.

If I swap the order of class declaration, and declare .makeGreen first

<style>
    .makeGreen {color:green;}
    .makeBlue {color: blue;}        
</style>
<div>
    <p class="makeGreen makeBlue">makeGreen makeBlue</p>
    <p class="makeBlue makeGreen">makeBlue makeGreen</p>
</div>

The output text is blue.

I've never noticed this before. edit I thought edit the last class listed in the element class attribute takes precedence.

edit To clarify --> I sometimes think of an element as a pet, let's say a dog. I see adding a class to the element's class attribute as issuing the dog a command. If I tell it to sit, and later tell it lie down, I expect the dog to lie down. I do not expect the dog to remain sitting simply because I taught it how to sit after (more recently than) I taught it how to lie down.

So... two questions.

  1. Is this how it is supposed to be? answered
  2. If so... why? I am unable to see the advantage of having to dig through class declarations in order to determine which was declared before the other.

Much thanks!

Rupture answered 18/7, 2013 at 15:28 Comment(5)
Thank you, that post answers the first question, as do the answers from j08691 & mathguy54. I'm still uncertain as to why that is the case (question #2). If I'm missing a common reference somewhere please let me know. I'd like to better understand the underlying reason as to why style declaration order trumps order of appearance in an element's class attribute. edited original questionRupture
"I see adding a class to the element's class attribute as issuing the dog a command." That's not a good way to see it. Attributes are very different from commands. Attributes are something inherent to an element, whereas commands on the other hand are things that an element does, often in sequence (or one after another).Interne
In answer to your second question it's simply because "specificity" is a CSS concept. The document language (in this case, HTML) has no bearing on it whatsoever.Interne
Thank you! The attribute/command distinction kicked out some cobwebs.Rupture
I thought the analogy of a dog was excellent, and even though that's not how it works, I bet a lot of people (like myself) would intuitively would arrive at that conclusion. If this was how it works, IMO it would stop a whole lot of !important directives from happening :)Pion
A
23

The order of the classes as you specify them on the elements is irrelevant. It's the order that you define them in your style declarations that matters. The quote you posted means in the style declarations, not the order the classes are listed on the elements.

Anthropoid answered 18/7, 2013 at 15:32 Comment(1)
Accepted for being first posted answer and clarifying the quote I referenced. Thanks again.Rupture
O
0

This seems to limit options. If I want to use two classes on two different paragraphs but have the precedence be different, I'd need to define a third class that is the same as the first defined class but with a slightly different name.

e.g

.xxxxx {margin-top: 1em; margin-left: 0; text-align: left; ... [some other attribute definitions]}<br/>

.yyyyy {margin-top: 3em; margin-left: 1em; text-align: justify; ... [some different attribute definitions]}

<p class="yyyyy xxxxx">...</p> 

will always use a top margin of 3em with a left margin of 1em and a text alignment of justify plus the other attributes in xxxxx and yyyyy. However, there might be a situation in which I want to override the margin-top, margin-left, and text-align settings while keeping all of the other attributes in xxxxx and yyyyy. If precedence was determined by order in the class attribute then I would have that option by doing this:

<p class="xxxxx yyyyy">...</p>

Since it is not, I have to create another definition below the two in question, as so:

.zzzzz {margin-top: 1em; margin-left 0; text-align: left; ... [some other attribute definitions]}

and use

<p class="yyyyy zzzzz">...</p>

This seems like a non-optimal solution to the problem whereas class attribute order precedence allows more flexibility without mucking up the CSS.

BTW, the Nook Glowlight does it the way it should be done by allowing me to set precedence by the order in the class attribute. And thus my css is a bit more compact.

If there is anything that I've learned in my decades of programming, it's that precedence is best placed as close as possible to where all the work gets done. Placing precedence in a linked static stylesheet reduces flexibility.

Overset answered 26/9, 2014 at 4:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.