Here it is. Enjoy.
Article Options
Archives by Category
- Design (1)
- Freebies (1)
- OS X Workflow (1)
- Personal (2)
- Productivity (1)
- Thoughts (1)
- Web Development (3)
Archives by Year
Pure CSS Timeline
- Published in: Web Development
- with 117 comments
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.
What are we building?
Let’s take a look at a screenshot of the timeline that we’re building in this tutorial.

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:

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 & 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 & 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
- Structured Timeline — Eric Meyer’s table approach to timelines.
- CSS Based Timeline — A very nice CSS based solution.
Subscribe to the Notebook RSS Feed
117 people left comments
Rheba Graner on January 26, 2012 at 11:26 pm wrote:
Hi! I read your article and couldn’t leave without commenting. Thanks for your time in creating this post!
Jimmmy on January 5, 2012 at 11:02 am wrote:
Interesting article. I created one of my own, made of pure CSS, that is a vertical timeline. It allows for unlimited number of entries and is fluid depending on browser size (works ok on mobile). http://jamespautz.com/web/2011/12/pure-css-timeline/
REGGIE on November 19, 2011 at 6:39 am wrote:
This is a cool article. Thanks for being so generous with your valuable knowledge
cheap caribbean vacations on August 14, 2011 at 7:33 pm wrote:
You ought to actually think about working on creating this weblog into a serious authority on this market. You certainly have the knowledge on the subjects everyone seems to be interested in on this site anyhow and you might even earn a buck off of some banners. Just a thought, good luck in whatever you do!
Craig McPheat on July 5, 2011 at 6:25 pm wrote:
Nice timeline! Cheers :)
Fabian on April 6, 2011 at 4:13 pm wrote:
Hello,
Great job!
I was doing myself but there is a need which I think is not possible to do:
I have an event that begins in 1960, ends in 1980 and reopens in 2000 until today.
Do you think there is a way to draw it within the same ??
I think no but not sure…
Thanks
Ed on May 7, 2010 at 10:52 pm wrote:
What’s cool is that I came back to this after all this time. I’m actually thinking of using it for quotes.Thanks for posting.
polskie biuro ksiegowe on April 23, 2010 at 8:18 am wrote:
Well well well… really nice, but unfortunately there is no possibility to scroll left/right some events :(
Filip on October 12, 2009 at 2:16 pm wrote:
interesting!
Thanks for the nice article.
Kathleen on August 19, 2009 at 3:42 pm wrote:
I just realized, those nice rounded ends are missing from the source code…. I’ve got rectangles around my items…. !!!
Kathleen on August 19, 2009 at 2:58 pm wrote:
This is really beautiful and very interesting. I don’t know CSS, but I have configured bits made by others. I just set up this CSS timeline on my desktop to try out, and what I would love to see, to really enhance it, is to somehow combine it with CSS expanding tree-menu code. So that, if you click on my entry, “Trudeau says “New World Order” to U.S. Congress (22 February 1977) “, it would EXPAND a single tab-window below the item title, and I could type a precise but detailed description of that event into that window.
Super-ideal would be if (A) I could click on any item and expand it to that detailed window,, individually. (B) I could click on a single control somewhere on the page that would cause all sub-windows in the entire timeline to expand so that I could PRINT it out.
Really gorgeous, nice thing! Bravo!
Brombomb on August 14, 2009 at 4:40 pm wrote:
Great was planning on doing this myself, and you saved me a lot of headache. Just thought I’d add one of my mods. I had an event that was split (due to jobs), but I wanted to keep it on the same line. To accomplish this I created a div inside the li.events. Then I applied the same left, width properties, and the only other change was making the div display as inline-block. Now I can have an event stretch from 2004 through 2005 then pick up again in 2007 and go to 2008.
Smashing Themes on August 13, 2009 at 3:23 am wrote:
That is one of the most unique things you can build with CSS. Very neat trick indeed.
Baris Oztekin on August 11, 2009 at 9:35 am wrote:
Just One Word: Perfect!!
Ben on July 17, 2009 at 11:33 am wrote:
Ah ha – I see it now. Thanks a lot
Matt Bango on July 17, 2009 at 9:48 am wrote:
@Ben – Sorry about that, demo should be working again. :)
@Steve Avery and @Tito Puente – Yep, I thought about that but wanted to stay away from images so that if the width of the timeline were to change I wouldn’t have to tweak the image every time. But on the other hand, if CSS is disabled as you both said, we have a list of dates that have no real meaning. I’ll put some thought into a good solution for that.
Thanks for the comments everyone!
Ben on July 17, 2009 at 9:38 am wrote:
Hi – the screenshots and ideas look good but the actual demo doesn’t load. It’d be cool if you could get that online again :)
Thanks in advance
Listen2Me on July 14, 2009 at 7:00 pm wrote:
I like it but I’d like to see the timeline with some of the elements floating inline next to each other. At the moment it seems a little limited in terms of it’s application.
Steve Avery on July 14, 2009 at 4:51 am wrote:
Nice work Matt. However I would suggest that the timeline of dates at the bottom could/should be a background image. That way if CSS is off you won’t see the unordered list of dates that have no relevant meaning under the above unordered list that list your Timeline with the dates anyway.
Ha. I’ve just relised that the 1st comment via Tito Puente also agree with my comment.
Ewout on July 14, 2009 at 3:55 am wrote:
Great use of lists and clean code. Nice results!
Webstandard-Team (Heiko) on July 14, 2009 at 3:47 am wrote:
Nice solution, but a definition-list ( dl ) would be a little bit more semantic. But the CSS would be more difficult ;o)
Tito Puente on July 12, 2009 at 6:28 pm wrote:
I think that ul.interval has not semantic meaning. So it is useless to have it on the HTML code. I thing it would a better solution to put the years as an backgropund of the ul.events.
Nikita Sumeiko on July 11, 2009 at 2:46 am wrote:
Well done, Matt!
Your tutorial is great for people who really need this time line, made with css.
Maybe someday I’m going to use it too.
Thank you.
dAN on July 10, 2009 at 5:27 am wrote:
I whipped this up with firebug, using CSS absolute positioning and z-index to place the date markers behind the bars, which I think makes it a little more readable:
http://drop.io/uyvgsti/asset/timeline-grab-jpg
cheers!
sasdaman on July 9, 2009 at 8:03 pm wrote:
Great use of ordered lists! A good alternative to using tables & images.
Brandon Cox on July 9, 2009 at 3:32 pm wrote:
Wow, very clever and cool. Love it! Nice presentation.
mattbango on July 9, 2009 at 3:31 pm wrote:
@macros If possible, dynamically creating the style sheet may be a good option. My first thought is that I would rather use inline styles than dynamically generating a style sheet.
Another thought is to dynamically generate the CSS in the
tag with a server side language and apply @tierack’s class naming convention of “start-2006 duration-3years”. Even though this is similar to inline styles, just not as messy.I would probably stay away from relying on Javascript to parse the classes, though it’s a good thought. The only issue I have with doing it that way is that a user might have Javascript disabled, but still have CSS turned on, in that case the display would not be correct as the presentation is relying on Javascript. I would rather use a server side solution rather than mixing in Javascript to rely on presentation.
These are all interesting ideas that I’ll put some more thought into.
Chris Reynolds on July 9, 2009 at 3:15 pm wrote:
Very nice tutorial. Great for something like an online resume or company profile.
Thanks!
Xavier on July 9, 2009 at 5:06 am wrote:
It’s a fantastic tip to build a CSS Timeline! thanks for share it!!
Veera on July 8, 2009 at 10:57 pm wrote:
Nice. The time line looks neat and clean.
I had tried to do a similar thing, but I went for HTML Tables instead of CSS. I thought, tables would be semantically correct structure for representing the timelines. And, tables were easy to add styles to the time line.
I’ve bundled that timeline creation logic as a web tool which can be accessed from: http://veerasundar.com/timelinr Please have a look at that and do let me know what do you think about the tool.
For a sample timeline, you can see this post: Timelinr – A web 2.0 application for creating timelines online
Btw, I like your blog theme! very clean!
marcos on July 8, 2009 at 10:54 pm wrote:
@mattbango getting back to tierack’s solution, maybe a better idea is to dynamically generate the css file, in order to retain the expressiveness of the class names.
however, a better solution might parse the content of the em tag using some js trickery because it would give you the ability to create discrete yearly/monthly/etc elements (i.e. 2003-2006, 2008). The js solution would still degrade in the same way, but would probably scale over time a bit better and prevent you from having to develop some obtuse backend timeline structure.
mattbango on July 8, 2009 at 3:02 pm wrote:
@tierack Yes, you could take that approach and it looks great. The only reason I didn’t do it that way is because I envisioned this timeline being used dynamically, so width and position needs to be calculated on the fly.
If you are dealing with static values that don’t change, such as the example I used in the article, your approach would work great and actually would be better if you are not doing any dynamic calculations.
Thanks for the feedback!
tierack on July 8, 2009 at 2:52 pm wrote:
Instead of inline styles, couldn’t you use class names? If you’re dealing with discrete data, it wouldn’t be so rough.
li class=”start-2006 duration-3years”…
li class=”start-2004 duration-5years”…
And then set the left and width styles in the class definitions for start-* and duration-* respectively.
Or am I missing something?
Mettez de la timeline dans vos webdesigns | Bitpxl on January 13, 2012 at 4:19 am wrote:
[...] Tutoriel et source timline css par Mattbango [...]
E-sitesweb » 45 Powerful CSS/JavaScript-Techniques on December 28, 2011 at 7:01 am wrote:
[...] 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.” [...]
40 Essential CSS Templates, Resources and Downloads « batusy on November 11, 2011 at 1:25 pm wrote:
[...] Pure CSS Timeline [...]
Blogging Well » Blog Archive » 30 Pure CSS Alternatives to Javascript on November 2, 2011 at 10:07 pm wrote:
[...] Pure CSS Timeline [...]
40 Important CSS Templates, Source Codes And Downloads | DesDevWeb on October 18, 2011 at 8:27 pm wrote:
[...] Pure CSS Timeline [...]
Web Designer Blog » Blog Archive » The Power Of CSS: Pure CSS Effects With Demos-No Javascript - All About Graphics and web designing on October 11, 2011 at 5:56 am wrote:
[...] 35.Pure CSS Timeline A simple and clean looking timeline with some very straight forward markup. [...]
展柜设计精美的图表和图形 - 泽宇空宁 on August 19, 2011 at 1:18 pm wrote:
[...] 纯CSS大事记 [...]
13+ 模拟 JavaScript 交互效果的纯 CSS 技术 | zend实验室-java/php学习教程、web前端设计、网站建设、网页设计、网络SEO推广 on July 10, 2011 at 7:34 pm wrote:
[...] 纯 CSS 时间线 [...]
Showcase of Beautifully Designed Charts & Graphs - WORDPRESS4free | WORDPRESS4free on July 10, 2011 at 12:41 pm wrote:
[...] Pure CSS Timeline [...]
Share your thoughts