Pure CSS Timeline

I wanted to build a CSS  timeline for the “About” section of my site while using some clean and simple markup. I wanted to avoid using images as much as possible, so I spent a few minutes prototyping some options and came up with a solution using unordered lists. The result is a simple and clean looking timeline with some very straight forward markup. In this article I’ll share my approach to creating a timeline out of CSS and HTML which results in a nice looking, simple timeline.

Introduction

First and foremost, is the solution I’m about to share with you the best solution? Probably not. I may revisit this at a later time when I have more than fifteen minutes to spend thinking about it, but for now it works and is accessible. If you don’t care to read the entire article, you can take a look at the demo or grab the source below and be on your merry way.

Demo

What are we building?

Let’s take a look at a screenshot of the timeline that we’re building in this tutorial.

Timeline

We have a nice looking timeline styled completely with CSS, but what happens if the visitor doesn’t have CSS enabled? Since we used unordered lists, we still have a nicely accessible list of events. What makes this even more useful is that I put the dates in parenthesis after the label for the timeline block. I would suggest doing this as it will help with accessibility, you can always hide the dates if you don’t want them with CSS later using the display: none; property. Take a look at the screenshot below:

Timeline without CSS

What would make this better is if the labels for the x-axis of the timeline would work better with the timeline block labels. Maybe someone out there has some suggestions for better markup to use?

The Markup

I chose to use a unordered list implementation. It’s very straight forward, however what I would like to explain are the inline styles being used on the list elements. I normally do not advocate using inline styles, in fact you should avoid using them if at all possible. However, for this solution, I couldn’t see any other way around it. Basically what you would do is have a PHP loop or some other server side loop echoing these list elements out. In the process you would calculate the correct width and position of each timeline block and set the width and left values as inline styles.


<div class="timeline">
    <ul class="events">
        <li style="width: 42.48%; left: 57.2%;">Design &amp; Typography <em>(2007 - 2009)</em></li>
        <li style="width: 56.68%; left: 43%;">Photography <em>(2006 - 2009)</em></li>
        <li style="width: 71.3%; left: 28.4%;">Object Oriented Programming <em>(2005 - 2009)</em></li>
        <li style="width: 85.5%; left: 14.2%;">Web Development <em>(2004 - 2009)</em></li>
        <li style="width: 42.75%; left: 0;">3D Modeling and Rendering <em>(2003 - 2006)</em></li>
        <li style="width: 99.5%; left: 0;">Drawing &amp; Illustration <em>(2003 - 2009)</em></li>
    </ul> <!-- end .events -->

    <ul class="intervals">
        <li class="first">2003</li>
        <li>2004</li>
        <li>2005</li>
        <li>2006</li>
        <li>2007</li>
        <li>2008</li>
        <li class="last">2009</li>
    </ul> <!-- end .intervals -->
</div> <!-- end .timeline -->

The CSS

The CSS is as simple as the markup. You will notice that I’m using the border-radius property (as well as the mozilla and webkit specific versions as border-radius isn’t implemented in any browsers yet, use border-radius to plan for the future). You should note that this is a CSS3 property and is not supported by all browsers. In fact, all versions of Internet Explorer don’t support this property at all (surprise, surprise). Other than that, take a look at what’s going on and if you have questions feel free to post a comment.


ul.events {
    list-style-type: none;
    margin: 0;
    padding: 0 0 20px 0;
}

ul.events li {
    -webkit-border-radius: 11px;
    -moz-border-radius: 11px;
    border-radius: 11px;
    background: #eee;
    border: 1px solid #ddd;
    color: #707070;
    font-size: 1.2em;
    font-weight: bold;
    margin-bottom: 6px;
    padding: 3px 0;
    position: relative;
    text-align: center;
}

ul.events li em {
    color: #aaa;
    font-weight: normal;
    font-size: 0.9em;
}

ul.intervals {
    list-style-type: none;
    padding: 0;
    display: block;
}

/* The width depends on the number of intervals. For example 100 / 7 = 14.29% -- then subtract a little bit for room for the borders */
ul.intervals li {
    background: #fff url(/images/1x1_eee.gif) repeat-x left 10%;
    border-right: 1px solid #ccc;
    color: #999;
    float: left;
    font-size: 1.2em;
    margin: 0;
    padding: 15px 0;
    text-align: center;
    width: 14.17%;
}

ul.intervals li.first {
    border-left: 1px solid #ccc;
}

Summary

As you can see, we’ve put together an aesthetically pleasing timeline using only CSS and unordered lists. Like I said before, this may not be the perfect solution markup wise and CSS wise, but it gets the job done and is still quite accessible for all users. This may be a topic to be revisited in the future to improve the markup if need be.

Take the timeline a step further. You could add some Javascript interactions, tooltips, animations, etc. How does this work for mobile browsers? Does it still look nice, is it still accessible? Experiment, play with it, have fun!

Further Reading

  1. Structured Timeline — Eric Meyer’s table approach to timelines.
  2. CSS Based Timeline — A very nice CSS based solution.