This tutorial will guide you through creating a responsive vertical timeline using HTML, CSS, and a touch of JavaScript. We’ll build a visually appealing and adaptable timeline that works seamlessly across different screen sizes. This is perfect for showcasing project timelines, company history, or any sequential data.
Step 1: Setting up the Project
Adding Header Assets
First, let’s include the necessary assets in the header of your HTML document. This includes linking to external fonts to style our timeline.
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Proza+Libre:ital,wght@0,400;0,500;0,600;0,700;0,800;1,400;1,500;1,600;1,700;1,800&family=Roboto+Mono:wght@700&family=Rosario:ital,wght@1,300..700&display=swap" rel="stylesheet">
Step 2: Creating the HTML Structure
Now, let’s craft the basic HTML structure for our timeline. We’ll use semantic HTML5 elements for better organization and accessibility.
<section class='timeline'>
<article>
<div class='timeline__content'>
<h1>Some heading</h1>
<time datetime='2005'>2005</time>
<hr/>
<p>Jelly cotton candy apple pie toffee soufflé tiramisu pastry cupcake lollipop. Jelly beans wafer ice cream pastry topping topping gingerbread gummies. Brownie cotton candy sweet halvah oat cake.</p>
</div>
<img src='https://images.unsplash.com/photo-1753788132128-a6198b5d2f80?w=400' alt='camera on a map on a desk'/>
</article>
<article>
<div class='timeline__content'>
<h1>Some other heading</h1>
<time datetime='2006'>2006</time>
<hr/>
<p>Jelly-o chocolate cake sweet fruitcake soufflé. Dessert halvah gummi bears lollipop powder brownie candy bear claw. Jelly-o marshmallow candy candy jujubes croissant fruitcake. Lollipop pudding brownie icing halvah dessert dessert.</p>
</div>
<img src='https://images.unsplash.com/photo-1755371033904-21dd8a9d002b?w=400' alt='mountain landscape'/>
</article>
</section>
Step 3: Styling with CSS
This is where we’ll add the visual appeal. The CSS will handle the layout, colors, and responsiveness of our timeline.
@charset "UTF-8";
html, body, section, article {
display: grid;
}
/* display: grid on html & body + min-height: 100% on html
* avoids the 100vh height mobile problem
* https://allthingssmitty.com/2020/05/11/css-fix-for-100vh-in-mobile-webkit/
* AND has better support than 100dvh height */
html {
min-height: 100%;
}
/* avoid pure white text on pure black background
* https://graphicdesign.stackexchange.com/questions/25356/why-not-use-pure-black-000-and-pure-white-fff
* https://uxplanet.org/alternatives-to-using-pure-black-000000-for-text-and-backgrounds-54ef0e733cdb
* https://uxmovement.com/content/why-you-should-never-use-pure-black-for-text-or-backgrounds/ */
body {
background: #121212;
color: #ededed;
}
.timeline {
/* middle align along both axes */
place-self: center;
/* limit width */
max-width: 50em;
}
.timeline article {
/* commonly used length value ¯\_(ツ)_/¯ */
--size: .625em;
/* timeline bar and markers */
--highlight: lime;
/* default marker */
--marker:
radial-gradient(circle closest-side,
var(--highlight) calc(100% - 1px), transparent)
0 0/ 100% var(--size);
/* spacing between the two columns (text content and image) */
grid-gap: 2em;
/* equally sized columns */
grid-template-columns: 1fr 1fr;
/* tiny correction, avoid subpixel rounding issues */
margin-top: -1px;
background: var(--marker), linear-gradient(var(--highlight) 0 0) 50%/2px;
background-repeat: no-repeat;
/* different marker for the first item */
/* for the odd items */
/* spacing in between items */
/* direct article children, text content box + img */
}
.timeline article:first-child {
--marker:
linear-gradient(var(--highlight) 0 0)
50% 0/ var(--size) calc(.5*var(--size)) ;
}
.timeline article:nth-child(odd) img {
/* on the 1st row, 1st column */
grid-area: 1/1;
/* right-aligned */
justify-self: end;
}
.timeline article:not(:last-child) {
padding-bottom: 1em;
}
.timeline article > * {
border-radius: var(--size);
}
.timeline__content {
padding: 1em;
background: rgba(255, 255, 255, 0.07);
}
.timeline h1 {
margin: 0 0 var(--size);
color: #88d55e;
font: italic 1.375em/1 rosario, sans-serif;
text-transform: capitalize;
}
.timeline time {
font: 700 2.5em/1.25 roboto mono, monospace;
}
.timeline hr {
opacity: 0.3;
}
.timeline p {
margin: 0;
padding-top: 0.5em;
font: 1em proza libre, sans-serif;
}
.timeline img {
box-sizing: border-box;
border: solid 2px;
width: min(100%, 13em);
aspect-ratio: 1.3;
object-fit: cover;
}
Congratulations! You’ve successfully created a responsive vertical timeline. Feel free to customize the styling and content to match your needs.
