Open demo

CSS code

HTML
<ol class="vtl">
  <li><span class="dot" aria-hidden="true"></span><p class="date"><time datetime="2021">2021</time> · Founded</p><div class="card"><h2>Two desks and a whiteboard</h2><p>Incorporated in a co-working space with a prototype and a lot of optimism.</p></div></li>
  <li><span class="dot" aria-hidden="true"></span><p class="date"><time datetime="2022">2022</time> · Launch</p><div class="card"><h2>Public beta ships</h2><p>First thousand users in six weeks, mostly through word of mouth.</p></div></li>
  <li><span class="dot" aria-hidden="true"></span><p class="date"><time datetime="2024">2024</time> · Series A</p><div class="card"><h2>$8M to grow the team</h2><p>Hired across engineering and support; opened the Lisbon office.</p></div></li>
  <li><span class="dot" aria-hidden="true"></span><p class="date"><time datetime="2026">2026</time> · Today</p><div class="card"><h2>28,000 teams on board</h2><p>Profitable, independent, and still shipping every Tuesday.</p></div></li>
</ol>
CSS
/* Alternating vertical timeline: an ordered list on a centre line, cards left and right, one column under 680px. */
.vtl{--vtl-accent:#2563eb;--vtl-line:#dbe2ef;--vtl-muted:#5f6b84;
  position:relative;max-width:760px;margin:0 auto;padding:0;list-style:none}
.vtl::before{content:"";position:absolute;left:50%;top:0;bottom:0;width:3px;background:var(--vtl-line);transform:translateX(-50%)}
.vtl>li{position:relative;box-sizing:border-box;width:50%;padding:0 40px 44px}
.vtl>li:nth-child(odd){left:0;text-align:right}
.vtl>li:nth-child(even){left:50%}
.vtl .dot{position:absolute;top:4px;box-sizing:border-box;width:16px;height:16px;border-radius:50%;background:var(--vtl-accent);
  border:3px solid #fff;box-shadow:0 0 0 3px var(--vtl-line)}
.vtl>li:nth-child(odd) .dot{right:-8px}
.vtl>li:nth-child(even) .dot{left:-8px}
.vtl .date{display:block;margin:0 0 8px;font-size:.75rem;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:var(--vtl-accent)}
.vtl .card{display:inline-block;text-align:left;background:#fff;border:1px solid #e6eaf3;border-radius:14px;padding:18px 20px;
  box-shadow:0 10px 26px -16px rgba(24,32,51,.18);transition:transform .15s}
.vtl .card:hover{transform:translateY(-3px)}
.vtl h2{margin:0 0 6px;font-size:.98rem}
.vtl .card p{margin:0;font-size:.85rem;line-height:1.6;color:var(--vtl-muted)}
@media (max-width:680px){
  .vtl::before{left:10px}
  .vtl>li,.vtl>li:nth-child(odd),.vtl>li:nth-child(even){width:100%;left:0;text-align:left;padding:0 0 36px 42px}
  .vtl>li:nth-child(odd) .dot,.vtl>li:nth-child(even) .dot{left:2px;right:auto}
}
@media (prefers-reduced-motion:reduce){.vtl .card{transition:none}.vtl .card:hover{transform:none}}

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS

HTML
<ol class="vtl list-unstyled mb-0">
  <li><span class="dot rounded-circle" aria-hidden="true"></span><p class="date text-uppercase mb-2"><time datetime="2021">2021</time> · Founded</p><div class="card"><div class="card-body"><h2 class="card-title fw-bold">Two desks and a whiteboard</h2><p class="card-text">Incorporated in a co-working space with a prototype and a lot of optimism.</p></div></div></li>
  <li><span class="dot rounded-circle" aria-hidden="true"></span><p class="date text-uppercase mb-2"><time datetime="2022">2022</time> · Launch</p><div class="card"><div class="card-body"><h2 class="card-title fw-bold">Public beta ships</h2><p class="card-text">First thousand users in six weeks, mostly through word of mouth.</p></div></div></li>
  <li><span class="dot rounded-circle" aria-hidden="true"></span><p class="date text-uppercase mb-2"><time datetime="2024">2024</time> · Series A</p><div class="card"><div class="card-body"><h2 class="card-title fw-bold">$8M to grow the team</h2><p class="card-text">Hired across engineering and support; opened the Lisbon office.</p></div></div></li>
  <li><span class="dot rounded-circle" aria-hidden="true"></span><p class="date text-uppercase mb-2"><time datetime="2026">2026</time> · Today</p><div class="card"><div class="card-body"><h2 class="card-title fw-bold">28,000 teams on board</h2><p class="card-text">Profitable, independent, and still shipping every Tuesday.</p></div></div></li>
</ol>
CSS
/* Alternating vertical timeline on a Bootstrap .list-unstyled list with .card items.
   The centre line and dots are drawn here; the card is restyled through the --bs-card-* variables. */
.vtl{--vtl-accent:#2563eb;--vtl-line:#dbe2ef;--vtl-muted:#5f6b84;position:relative;max-width:760px;margin:0 auto}
.vtl::before{content:"";position:absolute;left:50%;top:0;bottom:0;width:3px;background:var(--vtl-line);transform:translateX(-50%)}
.vtl>li{position:relative;width:50%;padding:0 40px 44px}
.vtl>li:nth-child(odd){left:0;text-align:right}
.vtl>li:nth-child(even){left:50%}
.vtl .dot{position:absolute;top:4px;width:16px;height:16px;background:var(--vtl-accent);border:3px solid #fff;box-shadow:0 0 0 3px var(--vtl-line)}
.vtl>li:nth-child(odd) .dot{right:-8px}
.vtl>li:nth-child(even) .dot{left:-8px}
.vtl .date{font-size:.75rem;font-weight:800;letter-spacing:.07em;color:var(--vtl-accent)}
.vtl .card{--bs-card-border-color:#e6eaf3;--bs-card-border-radius:14px;--bs-card-spacer-y:18px;--bs-card-spacer-x:20px;--bs-card-title-spacer-y:6px;
  display:inline-flex;text-align:left;box-shadow:0 10px 26px -16px rgba(24,32,51,.18);transition:transform .15s}
.vtl .card:hover{transform:translateY(-3px)}
.vtl .card-title{font-size:.98rem;line-height:normal}
.vtl .card-text{font-size:.85rem;line-height:1.6;color:var(--vtl-muted)}
@media (max-width:680px){
  .vtl::before{left:10px}
  .vtl>li,.vtl>li:nth-child(odd),.vtl>li:nth-child(even){width:100%;left:0;text-align:left;padding:0 0 36px 42px}
  .vtl>li:nth-child(odd) .dot,.vtl>li:nth-child(even) .dot{left:2px;right:auto}
}
@media (prefers-reduced-motion:reduce){.vtl .card{transition:none}.vtl .card:hover{transform:none}}

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<ol class="relative mx-auto max-w-[760px] before:absolute before:inset-y-0 before:left-[10px] before:w-[3px] before:-translate-x-1/2 before:bg-[#dbe2ef] min-[681px]:before:left-1/2">
  <li class="group relative pb-9 pl-[42px] min-[681px]:w-1/2 min-[681px]:px-10 min-[681px]:pb-11 min-[681px]:odd:text-right min-[681px]:even:left-1/2"><span aria-hidden="true" class="absolute top-1 left-[2px] size-4 rounded-full border-3 border-white bg-[#2563eb] shadow-[0_0_0_3px_#dbe2ef] min-[681px]:group-odd:-right-2 min-[681px]:group-odd:left-auto min-[681px]:group-even:-left-2"></span><p class="mb-2 text-[.75rem] font-extrabold tracking-[.07em] text-[#2563eb] uppercase"><time datetime="2021">2021</time> · Founded</p><div class="inline-block rounded-[14px] border border-[#e6eaf3] bg-white px-5 py-[18px] text-left shadow-[0_10px_26px_-16px_rgba(24,32,51,.18)] transition-transform duration-150 hover:-translate-y-[3px] motion-reduce:transition-none motion-reduce:hover:translate-y-0"><h2 class="mb-1.5 text-[.98rem] font-bold">Two desks and a whiteboard</h2><p class="text-[.85rem] leading-[1.6] text-[#5f6b84]">Incorporated in a co-working space with a prototype and a lot of optimism.</p></div></li>
  <li class="group relative pb-9 pl-[42px] min-[681px]:w-1/2 min-[681px]:px-10 min-[681px]:pb-11 min-[681px]:odd:text-right min-[681px]:even:left-1/2"><span aria-hidden="true" class="absolute top-1 left-[2px] size-4 rounded-full border-3 border-white bg-[#2563eb] shadow-[0_0_0_3px_#dbe2ef] min-[681px]:group-odd:-right-2 min-[681px]:group-odd:left-auto min-[681px]:group-even:-left-2"></span><p class="mb-2 text-[.75rem] font-extrabold tracking-[.07em] text-[#2563eb] uppercase"><time datetime="2022">2022</time> · Launch</p><div class="inline-block rounded-[14px] border border-[#e6eaf3] bg-white px-5 py-[18px] text-left shadow-[0_10px_26px_-16px_rgba(24,32,51,.18)] transition-transform duration-150 hover:-translate-y-[3px] motion-reduce:transition-none motion-reduce:hover:translate-y-0"><h2 class="mb-1.5 text-[.98rem] font-bold">Public beta ships</h2><p class="text-[.85rem] leading-[1.6] text-[#5f6b84]">First thousand users in six weeks, mostly through word of mouth.</p></div></li>
  <li class="group relative pb-9 pl-[42px] min-[681px]:w-1/2 min-[681px]:px-10 min-[681px]:pb-11 min-[681px]:odd:text-right min-[681px]:even:left-1/2"><span aria-hidden="true" class="absolute top-1 left-[2px] size-4 rounded-full border-3 border-white bg-[#2563eb] shadow-[0_0_0_3px_#dbe2ef] min-[681px]:group-odd:-right-2 min-[681px]:group-odd:left-auto min-[681px]:group-even:-left-2"></span><p class="mb-2 text-[.75rem] font-extrabold tracking-[.07em] text-[#2563eb] uppercase"><time datetime="2024">2024</time> · Series A</p><div class="inline-block rounded-[14px] border border-[#e6eaf3] bg-white px-5 py-[18px] text-left shadow-[0_10px_26px_-16px_rgba(24,32,51,.18)] transition-transform duration-150 hover:-translate-y-[3px] motion-reduce:transition-none motion-reduce:hover:translate-y-0"><h2 class="mb-1.5 text-[.98rem] font-bold">$8M to grow the team</h2><p class="text-[.85rem] leading-[1.6] text-[#5f6b84]">Hired across engineering and support; opened the Lisbon office.</p></div></li>
  <li class="group relative pb-9 pl-[42px] min-[681px]:w-1/2 min-[681px]:px-10 min-[681px]:pb-11 min-[681px]:odd:text-right min-[681px]:even:left-1/2"><span aria-hidden="true" class="absolute top-1 left-[2px] size-4 rounded-full border-3 border-white bg-[#2563eb] shadow-[0_0_0_3px_#dbe2ef] min-[681px]:group-odd:-right-2 min-[681px]:group-odd:left-auto min-[681px]:group-even:-left-2"></span><p class="mb-2 text-[.75rem] font-extrabold tracking-[.07em] text-[#2563eb] uppercase"><time datetime="2026">2026</time> · Today</p><div class="inline-block rounded-[14px] border border-[#e6eaf3] bg-white px-5 py-[18px] text-left shadow-[0_10px_26px_-16px_rgba(24,32,51,.18)] transition-transform duration-150 hover:-translate-y-[3px] motion-reduce:transition-none motion-reduce:hover:translate-y-0"><h2 class="mb-1.5 text-[.98rem] font-bold">28,000 teams on board</h2><p class="text-[.85rem] leading-[1.6] text-[#5f6b84]">Profitable, independent, and still shipping every Tuesday.</p></div></li>
</ol>

About this set

A company history laid out as an alternating vertical timeline: a 3px centre line, a blue dot for each event, and white cards that switch sides from left to right as the story moves down the page. Every entry has an uppercase date line such as 2021 · Founded, a short heading and one or two sentences. Use it for an About page, a founding story or a list of product milestones, where four to eight events read better as a sequence than as a table. The markup is an ordered list, so the order is part of the content, and the years sit in time elements with a datetime attribute. The odd and even items are positioned with nth-child, so adding an entry needs no extra classes. Below 680 pixels the line moves to the left edge and every card stacks in a single column, so long text never squeezes into half the width of a phone. Cards lift by 3 pixels on hover. The Bootstrap version uses .card with –bs-card-* variables, and the Tailwind version builds the same layout with odd:, even: and group-odd: variants.

What’s included

  • Ordered list with cards alternating left and right of a centre line
  • Years marked up with time and a datetime attribute
  • Collapses to a single left-aligned column under 680px
  • Dots are decorative and hidden from screen readers
  • Hover lift that is switched off under reduced motion

Accessibility

The events are an ordered list, so screen readers announce how many there are and read them in order, and each card has its own heading. The dots are aria-hidden. Date text is the 4.7:1 accent blue on the page background. The 3px hover lift is removed when prefers-reduced-motion is set. There are no interactive controls.

Customise it

Change --vtl-accent, --vtl-line and --vtl-muted on .vtl in the plain CSS and Bootstrap versions; Bootstrap cards also take --bs-card-border-color and --bs-card-border-radius. In Tailwind edit the #2563eb and #dbe2ef arbitrary colours and the min-[681px]: breakpoint.