Chances are if you want to number things in order on a website, the ordered list (<ol>
) is your guy. It also is pretty reasonable that you want to style those numbers. Strangely enough, styling those list numbers isn’t a very easy thing to in CSS. Thankfully it’s also not impossible. Roger Johansson has a tutorial that shows how it can be done with the :before
pseudo element, which can have a counter
as a value to the content
property.
But let it be known, applying numbered counters is not limited to ordered lists. For instance, let’s say you wanted to number the question and answer pairs of a FAQ list.
You’d have markup like this:
<dl class="faq">
<dt>How much wood would a wood chuck chuck if a wood chuck could chuck wood?</dt>
<dd>1,000,000</dd>
<dt>What is the air-speed velocity of an unladen swallow?</dt>
<dd>What do you mean? An African or European swallow?</dd>
<dt>Why did the chicken cross the road?</dt>
<dd>To get to the other side</dd>
</dl>
Each new <dt>
element is a new question, hence where we should apply the numbering. It’s as simple as this:
.faq {
counter-reset: my-badass-counter;
}
.faq dt:before {
content: counter(my-badass-counter);
counter-increment: my-badass-counter;
}
Style the :before
element as you will. For instance:
Just wanted to make ya’ll aware of this ability. You start thinking of all kinds of things to number once it’s sunk in. For instance I recently blogged one of my favorite recipes and I numbered each step/photo with blocky roman numerals.list-style-type
can be. Namely:
disc (• • •)
circle (○ ○ ○)
square (▪ ▪ ▪)
decimal (1 2 3)
decimal-leading-zero (01, 02, 03)
lower-roman (i ii iii)
upper-roman (I II III)
lower-greek (α β γ)
lower-latin (a b c)
upper-latin (A B C)
armenian (Ա Բ Գ)
georgian (ა ბ გ)
lower-alpha (a b c)
upper-alpha (A B C)
All you need to do is specify which in the counter value itself:
content: counter(my-counter, lower-roman);
The Future
The stuff above is cool and in the Use-It-Today™ camp. But it almost feels hacky when you look at the leap forward CSS3 lists is taking. Once browser support for that comes along, we’ll be able to do things like target the marker of the list at will:
/*
Examples from THE FUTURE
No browser support at the time of this writing
*/
li::marker {
width: 30px;
text-align: right;
margin-right: 10px;
display: inline-block;
}
ol {
list-style: symbols("*" "\2020" "\2021" "\A7");
}
ul {
list-style-type: "★";
}
Great take on lists and definitions! I could see a lot of cases where this will come in handy.
I had no idea that this could be accomplished in pure CSS – awesome tutorial (as always) Chris!
Hi can you add (post) a HTML and CSS code for the first picture (image) ?
I like design that you can see on first picture.
Thanks.
Oh sorry there is a link. So nothing. Thanks.
Chris… according to Wolfram Alpha (their source is given) – a Woodchuck can chuck 361,9237001 cubic centimeters of wood – (if he could chuck wood that is) – NOT the “1,000,000” which you list. Just FYI, in case you feel like correcting your obviously inadvertent faux pas.
ps – glad you are back and moving on with your life: we missed you!
Obviously that’s 361.9237001 cc/day.
Sorry, the correct answer is in fact, “a chuckload”.
The correct answer is actually:
The wood that a woodchuck would chuck. Is the wood that a woodchuck could chuck. If a woodchuck could chuck wood.
I’ve used this quite a lot in the last couple of years or so, when appropriate because it’s great for appearance and very flexible.
But it’s well worth noting that having to set the list-style-type to none means that it is really only suitable for content that you just what to style like a list.
Anything that actually should be a list should not have its list-style removed if you can avoid it because it significantly reduces semantic understanding in most ATs.
I recently had a project that required a “countdown.” I used this technique to make the list count backwards (from 10 to 1):
$trade; => ™
Wow. This is very new for me :(o)
Nice ! Thanks
Whats compatibility like with this?
Very useful to know, however why are the ingredients for your meatloaf recipe not marked up as a list?
nice dude ! thanks a lot !
I learn something new everyday! Thanks for the tip!
I’m loving this idea, I stumbled upon it myself recently while trying to get the left padding equal on the list item content, trying to get “hello” to line up vertically:
6 hello
66 hello
666 hello
but using :before we can welcome in :inline-block and set a width!
http://jsfiddle.net/sQaeR/
Chris, I checked out
counter-reset
CSS property, and W3Schools says that it belongs to CSS2. How weird is that this property is so lost between designers.To be honest, this was my first time I met this property. Do you have a reference to the W3’s specification, in which this property is defined?
This is a really helpful post but it requires one correction:
a woodchuck would chuck as much wood as he could chuck if a woodchuck could chuck wood.
Great article Chris! I actually published a similar (relatively) article a couple of days ago – Use :pseudo-elements as list-style-image alternatives.
Good to know, Thanks Chris!
For people asking about the compatibility for this, it’s fine in all major browsers except IE7 (and before). IE7 doesn’t support the :before/:after pseudo elements.
But IE7 is under 5% worldwide!!!!
http://gs.statcounter.com/#browser_version-ww-monthly-201111-201111-bar
Great and very useful.
Thanks
Great article; looks like the future of CSS3 lists is going to be worth keeping an eye on.
Spotted a typo: “One browser support for that comes along” -> “Once browser support…”
Great tut, nice stuff as always
nice article ..
i found this type of article from few days..
I tried many methods to Get Countdown Automatically but nothing worked, any Ideas for it?
If anyone is looking for more inspiration for custom lists that use this technique, check out this post!
This technique is not highly recommend due to the WCAG 2.0 requirements in Web Accessibility. How does the deaf / blind user would know that list is actually #1 out of 3 when this technique doesn’t generate the actual text or value that has the number in it. I would highly discourage using this technique.