A better way to style ordered lists.
Ordered lists are probably one of the neatest HTML tags.
In a lot of ways, they’re the best and the worst of ‘old-school’ HTML; here’s a completely semantic tag that has beautiful inner nesting, a clear meaning encapsulated within the name of the tag (also, it took me an embarrassing three years to realize ol stood for ordered list).
But when it comes to dealing with the ‘ordered’ part of the ordered list, there’s not much leeway, and the presentation of the ordering itself isn’t easily modifiable by either HTML5 or CSS3. HTML5 conventions let us only access three attributes:
- start, which is the starting number/character/numeral/etc. of the first
li - reversed, which is hopefully obvious
- type, which can either be “1”, “A”, “a”, or “i” — basically, what type of ordering you want it to be.
Okay, pop quiz — how do you make the color of the numbers in an ordered list red?
If you’ve got Firebug or Chrome, go ahead and inspect the ordered list below:
- One Fish
- Two Fish
- Red Fish
- Blue Fish
Notice how the numbers are ‘outside the scope’ of the li element? That’s terrible, right? So, how do we make the numbers red?
Bad ideas
You’ve seen the bad ideas before:
- Hardcoding in the numbers. This is a) gross, as it loses the structure of a proper ordered list and b) painful, as without CSS3 or JS you have to manually type in each number/character and that just makes you feel like some sort of web design pauper.
- CSS3. Maybe you’ve seen a tutorial or two about ordered lists. The general answers involve pretty much the closest thing CSS3 has to sorcery: disabling the list altogether, taking advantage of
:beforeandcounter-incrementto simulate the ordered list on the CSS3 side while still being able to style it. While this does solve the problem at hand, it does so by pretty much disregarding the entire point of CSS (no content, remember?) and generally tackling a two-ton problem with a ten-ton gallon of magical bricks. It might make you feel clever, but it’s unnecessary.
A pretty easy good idea
So, the numbers are definitely outside the scope of an li element but inside the scope of the ol element. Let’s take advantage of that, and try this:
<style type='text/css'>
ol {
color: red;
}
ol li {
color: black;
}
</style>
Except that this doesn’t work. From a DOM perspective, the numerals are still an aspect of the li tag; styling the tag means styling the numerals, and thus anything we apply to li will be applied to the increments as well. Thankfully, we can achieve a quick workaround that achieves our ideal effect without being quite as hackish as :before:
<style type='text/css'>
ol {
color: red;
}
ol li span {
color: black;
}
</style>
<ol>
<li> <span> One fish </span> </li>
<li> <span> Two fish </span> </li>
<li> <span> Red fish </span> </li>
<li> <span> Blue fish </span> </li>
</ol>
Conclusion
Tada. That’s it. It’s not perfect, but it’s much kinder than the CSS3 approach. While the CSS3 approach destroys the semantic meaning of ol and ravages the acceptable use-cases for :before by commiting the cardinal sin of mingling content and presentation, this approach (and it works with span, div, p, or whatever element you care to use) is kinder to all parties involved; most importantly you, since you don’t need to carry around a dozen lines of bleeding-edge CSS in your back pocket.
If you thought this was helpful, you should follow me on Twitter where I dispense with more of these gems .