Welcome to a tutorial and example of how to create a simple vertical timeline using pure CSS. Yes, there is a ton of timeline plugins on the Internet, but nothing beats having the knowledge to build one yourself and the power to style as you please. So here it is, let us walk through a lightweight pure CSS timeline in this guide – Read on!
ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.
TABLE OF CONTENTS
DOWNLOAD & NOTES
Firstly, here is the download link to the example code as promised.
QUICK NOTES
If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.
EXAMPLE CODE DOWNLOAD
Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
VERTICAL TIMELINE
All right, let us now get started with the responsive vertical timeline.
VERTICAL TIMELINE DEMO
THE HTML
<h1>Vertical Timeline Demo</h1>
<div class="vtl">
<div class="event">
<p class="date">11 Mar 2237 12:34</p>
<p class="txt">Evil Cates invaded planet Doge.</p>
</div>
<div class="event">
<p class="date">12 Mar 2237 14:23</p>
<p class="txt">Cates ate Doge food.</p>
</div>
<div class="event">
<p class="date">13 Mar 2237 20:12</p>
<p class="txt">Cates took over the Doge beds.</p>
</div>
<div class="event">
<p class="date">14 Mar 2237 08:11</p>
<p class="txt">Hoomans to the rescue.</p>
</div>
<div class="event">
<p class="date">15 Mar 2237 14:27</p>
<p class="txt">Evil cates gone. Victory for good boys and girls.</p>
</div>
</div>
There is nothing “special” with the HTML, just need to create the container and events accordingly.
- Start by creating a
<div class="vtl">
container to put all the events in. - Sandwich the events
<div class="event">
inside the container. - Finally, insert the
<p class="date">
timestamp and the<p class="txt">
event itself.
That’s all.
THE CSS
/* (A) TIMELINE CONTAINER */
.vtl {
/* (A1) RELATIVE POSITION REQUIRED TO PROPERLY POSITION THE TIMELINE */
position: relative;
/* (A2) RESERVE MORE SPACE TO THE LEFT FOR THE TIMELINE */
padding: 10px 10px 10px 50px;
/* (A3) OPTIONAL WIDTH RESTRICTION */
max-width: 400px;
}
.vtl, .vtl * { box-sizing: border-box; }
/* (B) DRAW VERTICAL LINE USING ::BEFORE */
.vtl::before {
/* (B1) VERTICAL LINE */
content: "";
width: 5px;
background-color: #de421a;
/* (B2) POSITION TO THE LEFT */
position: absolute;
top: 0; bottom: 0; left: 15px;
}
/* (C) COSMETICS FOR EVENTS */
div.event {
padding: 20px 30px;
background-color: #ffebeb;
position: relative;
border-radius: 6px;
margin-bottom: 10px;
}
/* (D) COSMETICS FOR EVENT DATE & TEXT */
p.date {
font-size: 1.1em;
font-weight: 700;
color: #ff6a00;
}
p.txt {
margin: 10px 0 0 0;
color: #222;
}
/* (E) EVENT "SPEECH BUBBLE CALLOUT" */
div.event::before {
/* (E1) "MAGIC TRIANGLE" */
content: "";
border: 10px solid transparent;
border-right-color: #ffebeb;
border-left: 0;
/* (E2) POSITION TO THE LEFT */
position: absolute;
top: 20%; left: -10px;
}
/* (F) CIRCLE ON TIMELINE */
div.event::after {
/* (F1) "MAGIC CIRCLE" */
content: "";
background: #fff;
border: 4px solid #DE421A;
width: 16px; height: 16px;
border-radius: 50%;
/* (F2) POSITION TO THE LEFT */
position: absolute;
top: 20%; left: -44px;
}
Yep, this looks massive at first, but keep calm and study it slowly.
- (A) First, we need to “set up” the
.vtl
container. The idea here is to use.vtl::before
to draw the timeline, and thus the extra left padding. - (B) Should be pretty self-explanatory. Draw the vertical timeline and position it on the left side of
.vtl
. - (C & D) Just some cosmetics for the events, date, and text itself.
- (E) Use
.event::before
to draw the “speech callout” for the events. Basically, a “magic triangle” CSS trick using borders. I will leave a link below if you are interested to know this works. - (F) Use
.event::after
to draw an “event circle” on the timeline.
ALTERNATE VERTICAL TIMELINE
Now that you know how to create a vertical timeline, here is an alternate version with the vertical line in the center instead.
ALTERNATE TIMELINE DEMO
THE HTML
<div class="alt-vtl">
<div class="alt-event">
<p class="date">11 Mar 2237 12:34</p>
<p class="txt">Evil Cates invaded planet Doge.</p>
</div>
<div class="alt-event right">
<p class="date">12 Mar 2237 14:23</p>
<p class="txt">Cates ate Doge food.</p>
</div>
<div class="alt-event">
<p class="date">13 Mar 2237 20:12</p>
<p class="txt">Cates took over the Doge beds.</p>
</div>
<div class="alt-event right">
<p class="date">14 Mar 2237 08:11</p>
<p class="txt">Hoomans to the rescue.</p>
</div>
<div class="alt-event">
<p class="date">15 Mar 2237 14:27</p>
<p class="txt">Evil cates gone. Victory for good boys and girls.</p>
</div>
</div>
Yep, the HTML in this alternate version is pretty much the same as previously – The difference is in the CSS.
THE CSS
/* (A) TIMELINE CONTAINER */
.alt-vtl {
/* (A1) RELATIVE POSITION REQUIRED TO PROPERLY POSITION THE TIMELINE */
position: relative;
/* (A2) WIDTH RESTRICTION & CENTER ON PAGE */
max-width: 600px;
margin: 0 auto;
}
/* (B) DRAW TIMELINE USING ::BEFORE */
.alt-vtl::before {
/* (B1) VERTICAL LINE */
content: "";
width: 5px;
background-color: #1da1ff;
/* (B2) POSITION IN THE MIDDLE */
position: absolute;
top: 0; bottom: 0; left: 50%;
}
/* (C) EVENTS */
div.alt-event {
/* (C1) COSMETICS */
background-color: #dbf0ff;
border-radius: 6px;
/* (C2) DIMENSIONS */
padding: 20px 30px;
width: 45%;
margin-bottom: 10px;
/* (C3) POSITION - DEFAULT LEFT SIDE */
position: relative;
left: 0;
}
/* (C4) CHANGE EVENT POSITION TO RIGHT SIDE */
div.right { left: 55%; }
/* (D) COSMETICS FOR EVENT DATE & TEXT */
p.date {
font-size: 1.1em;
font-weight: 700;
color: #ff6a00;
}
p.txt {
margin: 10px 0 0 0;
color: #222;
}
/* (E) EVENT "SPEECH BUBBLE CALLOUT" */
/* (E1) SHARED */
div.alt-event::before, div.alt-event.right::before {
content: "";
border: 10px solid transparent;
position: absolute;
}
/* (E2) FOR EVENTS ON THE LEFT */
div.alt-event::before {
/* (E2-1) "MAGIC TRIANGLE" */
border-left-color: #dbf0ff;
border-right: 0;
/* (E2-2) POSITION TRIANGLE ON THE RIGHT */
left: 100%; top: 20%;
}
/* (E3) FOR EVENTS ON THE RIGHT */
div.alt-event.right::before {
/* (E3-1) "MAGIC TRIANGLE" */
border-right-color: #dbf0ff;
border-left: 0;
/* (E3-2) POSITION TRIANGLE ON THE LEFT */
left: auto; right: 100%; top: 20%;
}
/* (F) EVENT CIRCLE ON TIMELINE */
/* (F1) SHARED */
div.alt-event::after, div.alt-event.right::after {
/* (F1-1) "MAGIC CIRCLE" */
content: "";
background: #fff;
border: 4px solid #1da1ff;
width: 16px; height: 16px;
border-radius: 50%;
/* (F1-2) POSITION */
position: absolute;
}
/* (F2) POSITION TO THE LEFT */
div.alt-event::after { top: 20%; left: 108%; }
/* (F3) POSITION TO THE RIGHT */
div.alt-event.right::after { top: 20%; left: auto; right: 105%; }
Yikes. This looks like brain damage material, but it is just a slightly modified version of the earlier one:
- (A) Just some “setup” for the timeline container.
- (B) Same old strategy to use
.alt-vtl::before
to draw the vertical timeline. But we useleft: 50%
to position it in the middle of the container instead. - (C & D) Just some cosmetics for the events again, but take note of
div.alt-event { left: 0; }
anddiv.right { right: 55%; }
. Yes, we apply the.right
CSS class to alternate the events. - (E & F) Same old speech callout and “circle on the timeline”, just different positioning.
USEFUL BITS & LINKS
That’s all for the main tutorial, and here is a small section on some extras and links that may be useful to you.
LINKS & REFERENCES
- How To Create Triangles In HTML CSS – Code Boxx
- How to Create CSS Circles – Code Boxx
- Examples On CodePen – Vertical Timeline | Alternating Timeline
THE END
Thank you for reading, and we have come to the end of this guide. I hope that it has helped you with your project, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!
Thanks a lot for this, I added this small piece which worked for me. It just hides the speech bubble triangles and circles on the vertical line, then extends each speech bubble to be full length. It ends up working nicely for smaller screens, it just stacks the speech bubbles along the center line. Figured I’d share (don’t mind the format).
@media screen and (max-width: 600px) {
div.ewrap {width: 100%;}
div.right {left: 0%;}
div.ewrap::before {display: none;}
div.ewrap::after {display: none;}
}
Man you are a genuis