CSS classes don't work the way you think they work

This is some text

Which color is this text going to be?

No cheating, give it a think ??

.

.

.

.

Blue. The answer is blue. ?

Look. I’m not lying. It’s really blue.

http://codepen.io/swizec/pen/BLvpER/

You can use any permutation of blue green red – the text is still blue. Try it! Edit the codepen. Play around :)

Did you find the pattern?

CSS classes apply in the order in which they are defined, not the order in which they are invoked. This is not intuitive.

Look: if you switch around the CSS rules, the text becomes red.

http://codepen.io/swizec/pen/EgGWNY/

Same HTML, same CSS classes, different order of definitions. Try it; change the code.

Maybe this is obvious to everyone but me, but I spent an embarrassing amount of time yesterday and today debugging some React components. It hits you when common components have default styling, and you want to override it in a specific instance.

const P = ({ className, children }) => (
    <p class="{`italic" blue="" ${classname}`}="">{children}</p>
); // default P

// ...

const Error = ({ errorText }) => (
    <p class="red">Red error!</p>
); // doesn't become red

The generic P component returns a <p> element with an italic and a blue class. You can expect text to be italic and blue by default.

Please don’t do that in real life. This is just an example.

It takes a className prop so you can extend classes used.

But when you use the Error component, which produces <p class="italic blue red">Red error!</p>, it’s not red. It’s blue because your CSS defines .red first and .blue second.

?

There is no workaround. This is expected behavior. The relevant part of W3C spec makes no mention of HTML attribute ordering.

How did I go 15 years without ever noticing? ?