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:

	<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>

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: '';
    border:24px solid #ccc;
    border-radius: 40px;
    position: absolute;
    /* using left and top to adjust absolute position of circle relative to li
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
    font-weight: bold;
    font-size: 32px;
    color: #999;

Published by

Umar Ashfaq

Umar Ashfaq is a full-stack web developer. His core strength is building neat UIs with JavaScript on web but he also enjoys server side Java, NodeJS and Objective C. Follow him on twitter @umarashfaq87

2 thoughts on “How To Stylize Ordered Lists <ol> With Pure CSS?”

  1. 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?

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

      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 *