How To Stylize Ordered Lists <ol> With Pure CSS?

Ordered lists <ol> allow you to show incrementing numbers (or other counters) next to your list items. For example, let’s list down seven books of A Song of Ice and Fire using <ol>:

  1. A Game of Thrones
  2. A Clash of Kings
  3. A Storm of Swords
  4. A Feast for Crows
  5. A Dance with Dragons
  6. The Winds of Winter
  7. A Dream of Spring

The code for above list will look like this:

<ol>
	<li>A Game of Thrones</li>
	<li>A Clash of Kings</li>
	<li>A Storm of Swords</li>
	<li>A Feast for Crows</li>
	<li>A Dance with Dragons</li>
	<li>The Winds of Winter</li>
	<li>A Dream of Spring</li>
</ol>

Let’s try to add some style to list. Let’s display each number on the left in a bigger font size and within a circle like shown below:

A lot of folks achieve such styles using image backgrounds, but there is nothing like it if you can create it using pure CSS. Here is my attempt:

ol {
    /* disable default counter */
    list-style: none;
    
    /* create a new counter, call it my-counter (or whatever you like) */
    counter-reset: my-counter;
    margin: 40px 20px 20px 0px;
}
ol li{
    /* positioning li relative will allow us to absolutely position children of li relative to li 
     * (the origin of x and y axis of li's absolutely positioned children will become top left corner of li,
     * instead of top left corner of the window) 
     */
    position: relative;
    padding-left: 50px;
    margin-bottom: 56px;
}
ol li:before{
    /* content property with :before pseudo selector will prepend a child element in li. 
     * Value of content will be set as text within the child element.
     * Let's use this element to create circle on the left side of a list item.
     */
    content: '';
    width:0px;
    height:0px;
    border:24px solid #ccc;
    border-radius: 40px;
    position: absolute;
    /* using left and top to adjust absolute position of circle relative to li
     */
    left:-12px;
    top:-12px;
    z-index:-1;
}
ol li:after {
    /* content property with :after pseudo selector will append a child to li
     * Let's use content of :after psuedo selector to display our counter number within the circle.
     * Value of content here signifies that we are using my-counter as content of newly appended child,
     * and this counter is a decimal number. 
     */
    content: counter(my-counter, decimal);
    /* if you don't use counter-increment, value of my-counter will always stay 0.
     */
    counter-increment: my-counter;
    position: absolute;
    /* using left and top to adjust absolute position of number relative to li
     */
    left:3px;
    top:-7px;
    font-weight: bold;
    font-size: 32px;
    color: #999;
}

Umar Ashfaq

Umar Ashfaq is a full-stack web developer. His core strengths are Java (Spring, Hibernate stack) and JavaScript (both client-side and server-side). Follow him on twitter @umarashfaq87

More Posts

Follow Me:
TwitterFacebookLinkedIn

Related posts:

  1. How To Create A Speech Balloon With Pure CSS?
  2. A Better Technique To Create A Speech Balloon With Pure CSS

2 Comments

  • 1
    Lisa
    August 2, 2013 - 10:58 pm | Permalink

    Thanks for this tutorial! Not sure what to do with the double digits when using absolute positioning to center 1-9 in the circle. Any ideas?

    • 2
      Umar Ashfaq
      August 20, 2013 - 2:19 pm | Permalink

      Sorry for late response, I had been busy in some work. Here is a quick fiddle I created to handle multiple digits: http://jsfiddle.net/Xm7xw/

      The key change lies in adding text-align: center in ol li:after. But you’ll not notice this change because width of this element is auto. So we need to add a fixed width, for example width: 50px. Finally I pulled the element towards left using left: 13px. Hope it helps.

  • Leave a Reply

    Your email address will not be published. Required fields are marked *

    *

    Wrap your code in [sourcecode language="java"][/sourcecode] tag (you can replace "java" with language you are using).