build wordpress website in 5 days build motocms website in 5 days

Build a Vertical Timeline Archives Page Using Bootstrap

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>

My stylesheet is based off the BS timeline snippet which uses default Bootstrap codes. However I've redesigned the layout to handle better responsive techniques, also updating the color scheme to a darker UI.

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>

From here it's pretty simple to understand how each bubble is created. The list items represent objects on the timeline, and we can revert to the opposite side by appending the .timeline-inverted class. Everything inside the list item will be practically identical.

.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;
}

The timeline container is meant to be centered at all times. Since the layout is responsive we only see it centered when larger than a few hundred pixels. When dropped to smaller resolutions the timeline will fix onto one side and the boxes will adjust in width.

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

Looking over the individual timeline panels you can see how each arrow design is created. Using the :before and :after pseudo-elements it is possible to generate arrows using CSS without any images. It also means the .noarrow class is easy to create by just reversing the properties and removing the arrow entirely.

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

Once the page viewport drops to 700px or below, then the timeline fixes itself onto the left side. Instead of being centered down the page, .timeline adjusts for smaller screens by keeping all the timeline panels off to the right side.

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.