Website archives have long been used to organize blog posts, comments, portfolio entries, and similar types of content. These pages are typically organized by date and split into sections by the month and year. This has naturally evolved to include other interface designs – one of which is a timeline of posts.
In this tutorial I want to demonstrate how to build a vertical responsive timeline using Twitter Bootstrap. It’s free to use and includes many helpful styles for getting the page setup properly. Also since we’re using Bootstrap it is very simple to create a responsive effect for the vertical timeline. This effect works great on a landing page or detailed archives page.
Live Demo – Download Source Code
Getting Started
The first step is to download a local copy of Bootstrap and the Glyphicons library. You can find copies hosted externally on Bootstrap CDN which also hosts the icon font files. I’ve separated these stylesheets into different files while also creating a new document called styles.css.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<!doctype html> <html lang="en-US"> <head> <meta charset="utf-8"> <meta http-equiv="Content-Type" content="text/html"> <title>Vertical Responsive Timeline UI - Template Monster Demo</title> <meta name="author" content="Jake Rocheleau"> <link rel="shortcut icon" href="http://static.tmimgcdn.com/img/favicon.ico"> <link rel="icon" href="http://static.tmimgcdn.com/img/favicon.ico"> <link rel="stylesheet" type="text/css" media="all" href="css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" media="all" href="css/bootstrap-glyphicons.css"> <link rel="stylesheet" type="text/css" media="all" href="css/styles.css"> <script type="text/javascript" src="js/jquery-1.11.0.min.js"></script> </head> |
Best Zurb Foundation Tutorials
Zurb Foundation Framework Tutorials
Responsive Email Design Tutorial + Free Templates
How to Create Dynamiv Password Generation and Rating with jQuery
Creating Perfect Website Navigation (Tips, Checklists, Tutorials)
Twenty WordPress Tutorials to Boom Up the Developments
You might also notice I’ve included small boxes for the date. This helps readers separate between the months and year of publication while scrolling through posts. Each bubble could represent events in history, status updates, or simply blog posts. The beauty of a timeline is that it can represent a number of things with an easy-to-use interface.
Page Structure
Twitter Bootstrap includes a set of default classes which can be used in any typical page. This design includes a .container div which expands or contracts based on the browser width. Beneath the small heading you’ll find an unordered list with the class .timeline. This is used in CSS to create a line down the center of the page.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<ul class="timeline"> <li><div class="tldate">Apr 2014</div></li> <li> <div class="tl-circ"></div> <div class="timeline-panel"> <div class="tl-heading"> <h4>Surprising Headline Right Here</h4> <p><small class="text-muted"><i class="glyphicon glyphicon-time"></i> 3 hours ago</small></p> </div> <div class="tl-body"> <p>Lorem Ipsum and such.</p> </div> </div> </li> <li class="timeline-inverted"> <div class="tl-circ"></div> <div class="timeline-panel"> <div class="tl-heading"> <h4>Breaking into Spring!</h4> <p><small class="text-muted"><i class="glyphicon glyphicon-time"></i> 4/07/2014</small></p> </div> <div class="tl-body"> <p>Hope the weather gets a bit nicer...</p> <p>Y'know, with more sunlight.</p> </div> </div> </li> |
.tl-circ is an empty div creating the blue circle icon. .timeline-panel contains the bubble itself which uses some detailed CSS pseudo-elements for the arrow. Also notice we are using the Glyphicons set to create the clock icon for each post status. Obviously you can rearrange these as needed, and it’s entirely possible to dynamically fill the timeline using a backend language such as PHP or Ruby.
There aren’t any particular rules for how you need to setup each timeline item. Some items may have the blue circle icon but it’s not necessary. Also you can add the class .noarrow onto the timeline panel to remove the arrow entirely. It’s a very flexible design with a lot of room for customization.
Styling the Page
Since Bootstrap offers a library of default styles we don’t need to create a lot from scratch. I’ve updated the page background to be dark rather than white, and the heading text color has also been updated. Also Bootstrap doesn’t set images to be responsive by default, so we accomplish this by adding the max-width: 100% property.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
body { background: #333; } img { border: 0; max-width: 100%; } .page-header h1 { font-size: 3.26em; text-align: center; color: #efefef; text-shadow: 1px 1px 0 #000; } /** timeline box structure **/ .timeline { list-style: none; padding: 20px 0 20px; position: relative; } .timeline:before { top: 0; bottom: 0; position: absolute; content: " "; width: 3px; background-color: #eee; left: 50%; margin-left: -1.5px; } .tldate { display: block; width: 200px; background: #414141; border: 3px solid #212121; color: #ededed; margin: 0 auto; padding: 3px 0; font-weight: bold; text-align: center; -webkit-box-shadow: 0 0 11px rgba(0,0,0,0.35); } .timeline li { margin-bottom: 25px; position: relative; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
/** timeline panels **/ .timeline li .timeline-panel { width: 46%; float: left; background: #fff; border: 1px solid #d4d4d4; padding: 20px; position: relative; -webkit-border-radius: 8px; -moz-border-radius: 8px; border-radius: 8px; -webkit-box-shadow: 0 1px 6px rgba(0, 0, 0, 0.15); -moz-box-shadow: 0 1px 6px rgba(0, 0, 0, 0.15); box-shadow: 0 1px 6px rgba(0, 0, 0, 0.15); } /** panel arrows **/ .timeline li .timeline-panel:before { position: absolute; top: 26px; right: -15px; display: inline-block; border-top: 15px solid transparent; border-left: 15px solid #ccc; border-right: 0 solid #ccc; border-bottom: 15px solid transparent; content: " "; } .timeline li .timeline-panel:after { position: absolute; top: 27px; right: -14px; display: inline-block; border-top: 14px solid transparent; border-left: 14px solid #fff; border-right: 0 solid #fff; border-bottom: 14px solid transparent; content: " "; } .timeline li .timeline-panel.noarrow:before, .timeline li .timeline-panel.noarrow:after { top:0; right:0; display: none; border: 0; } .timeline li.timeline-inverted .timeline-panel { float: right; } .timeline li.timeline-inverted .timeline-panel:before { border-left-width: 0; border-right-width: 15px; left: -15px; right: auto; } .timeline li.timeline-inverted .timeline-panel:after { border-left-width: 0; border-right-width: 14px; left: -14px; right: auto; } |
Each panel naturally locates onto the left side as content flows from left-to-right. But with the.timeline-inverted class it forces individual items to float over to the right. This also means adjusting the arrow to point the opposite way so everything aligns properly.
Responsive CSS
The last portion of my styles.css document is the responsive design. I’ve only set two unique breakpoints which define the key areas of this interface.
First at 991px I’m updating the timeline panel width from 46% down to 44%. As the page width drops smaller the timeline boxes move closer to the center, but stay at the same width. This means we find arrows overlapping the blue circle icon and it looks clunky. Adjusting the width solves this problem easily.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
/** media queries **/ @media (max-width: 991px) { .timeline li .timeline-panel { width: 44%; } } @media (max-width: 700px) { .page-header h1 { font-size: 1.8em; } ul.timeline:before { left: 40px; } .tldate { width: 140px; } ul.timeline li .timeline-panel { width: calc(100% - 90px); width: -moz-calc(100% - 90px); width: -webkit-calc(100% - 90px); } ul.timeline li .tl-circ { top: 22px; left: 22px; margin-left: 0; } ul.timeline > li > .tldate { margin: 0; } ul.timeline > li > .timeline-panel { float: right; } ul.timeline > li > .timeline-panel:before { border-left-width: 0; border-right-width: 15px; left: -15px; right: auto; } ul.timeline > li > .timeline-panel:after { border-left-width: 0; border-right-width: 14px; left: -14px; right: auto; } } |
This is generally easier to understand because the inverted panels look just like regular panels. Images are still visible, links are still clickable, and everything is still easy to read. I didn’t adjust font sizes other than the page header but you could increase regular text for better legibility.
As the window expands much wider Bootstrap has built-in responsive CSS to adjust the container width. The layout should work perfectly from smartphones all the way up through tablets, laptops, and desktop monitors.
Closing
Although this effect may not be useful on every website, it sure is unique and provides quite an interesting experience. As time goes on we might notice designers picking up on this trend for a cleaner performance when organizing galleries of content. Feel free to download a copy of my source code and play around with this design to get something you could use in future web projects.