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.