Open demo

CSS code

HTML
<div class="htl" role="region" aria-label="Studio history, 1926 to 2026" tabindex="0">
  <ol>
    <li><p class="year"><time datetime="1926">1926</time></p><h2>The letterpress years</h2><p>Founded as a two-man print shop above a bakery. The original press still works.</p></li>
    <li><p class="year"><time datetime="1954">1954</time></p><h2>First identity work</h2><p>The city commissions a crest refresh — the studio's first branding job.</p></li>
    <li><p class="year"><time datetime="1987">1987</time></p><h2>Going digital</h2><p>A Macintosh II replaces the paste-up tables. Half the staff threatens to quit; nobody does.</p></li>
    <li><p class="year"><time datetime="2003">2003</time></p><h2>The web era</h2><p>First website ships for a client. It has a splash page. We are sorry.</p></li>
    <li><p class="year"><time datetime="2015">2015</time></p><h2>Product design</h2><p>From posters to platforms — the studio's first SaaS design system.</p></li>
    <li><p class="year"><time datetime="2026">2026</time></p><h2>One hundred years</h2><p>Twelve people, four time zones, and the same rule: make it useful, then make it beautiful.</p></li>
  </ol>
</div>
CSS
/* Horizontal scroll timeline: a focusable scroller that snaps era by era. Tab into it and use the arrow keys,
   or scroll sideways. The rail and the glowing dot are drawn per era with ::before and ::after. */
.htl{--htl-accent:#eab308;--htl-rail:#2c2f3b;--htl-text:#9ba0af;--htl-bg:#101015;
  overflow-x:auto;scroll-snap-type:x mandatory;padding:30px 40px 40px;scroll-padding-inline:40px;
  scrollbar-width:thin;scrollbar-color:#3a3d4a var(--htl-bg)}
.htl:focus-visible{outline:2px solid var(--htl-accent);outline-offset:-2px;border-radius:6px}
.htl ol{display:flex;width:max-content;margin:0;padding:0;list-style:none}
.htl li{position:relative;flex:0 0 300px;scroll-snap-align:start;box-sizing:border-box;padding:26px 28px 0 0}
.htl li::before{content:"";position:absolute;top:0;left:0;right:0;height:3px;background:var(--htl-rail)}
.htl li::after{content:"";position:absolute;top:-5px;left:0;width:13px;height:13px;border-radius:50%;background:var(--htl-accent);
  box-shadow:0 0 12px rgba(234,179,8,.5)}
.htl .year{margin:0;font-size:2rem;line-height:normal;font-weight:900;letter-spacing:-.04em;color:var(--htl-accent)}
.htl h2{margin:8px 0;font-size:1rem}
.htl p{margin:0;font-size:.85rem;line-height:1.65;color:var(--htl-text)}
@media (max-width:480px){.htl{padding:30px 20px 40px;scroll-padding-inline:20px}.htl li{flex-basis:260px}}

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS

HTML
<div class="htl overflow-x-auto" role="region" aria-label="Studio history, 1926 to 2026" tabindex="0">
  <ol class="d-flex list-unstyled mb-0">
    <li><p class="year mb-0"><time datetime="1926">1926</time></p><h2 class="fw-bold">The letterpress years</h2><p class="mb-0">Founded as a two-man print shop above a bakery. The original press still works.</p></li>
    <li><p class="year mb-0"><time datetime="1954">1954</time></p><h2 class="fw-bold">First identity work</h2><p class="mb-0">The city commissions a crest refresh — the studio's first branding job.</p></li>
    <li><p class="year mb-0"><time datetime="1987">1987</time></p><h2 class="fw-bold">Going digital</h2><p class="mb-0">A Macintosh II replaces the paste-up tables. Half the staff threatens to quit; nobody does.</p></li>
    <li><p class="year mb-0"><time datetime="2003">2003</time></p><h2 class="fw-bold">The web era</h2><p class="mb-0">First website ships for a client. It has a splash page. We are sorry.</p></li>
    <li><p class="year mb-0"><time datetime="2015">2015</time></p><h2 class="fw-bold">Product design</h2><p class="mb-0">From posters to platforms — the studio's first SaaS design system.</p></li>
    <li><p class="year mb-0"><time datetime="2026">2026</time></p><h2 class="fw-bold">One hundred years</h2><p class="mb-0">Twelve people, four time zones, and the same rule: make it useful, then make it beautiful.</p></li>
  </ol>
</div>
CSS
/* Horizontal scroll timeline: Bootstrap's .overflow-x-auto scroller with .d-flex list, made focusable
   (tabindex="0") so the arrow keys scroll it. The rail and glowing dot are drawn per era. */
.htl{--htl-accent:#eab308;--htl-rail:#2c2f3b;--htl-text:#9ba0af;--htl-bg:#101015;
  scroll-snap-type:x mandatory;padding:30px 40px 40px;scroll-padding-inline:40px;scrollbar-width:thin;scrollbar-color:#3a3d4a var(--htl-bg)}
.htl:focus-visible{outline:2px solid var(--htl-accent);outline-offset:-2px;border-radius:6px}
.htl ol{width:max-content}
.htl li{position:relative;flex:0 0 300px;scroll-snap-align:start;padding:26px 28px 0 0}
.htl li::before{content:"";position:absolute;top:0;left:0;right:0;height:3px;background:var(--htl-rail)}
.htl li::after{content:"";position:absolute;top:-5px;left:0;width:13px;height:13px;border-radius:50%;background:var(--htl-accent);box-shadow:0 0 12px rgba(234,179,8,.5)}
.htl .year{font-size:2rem;font-weight:900;letter-spacing:-.04em;line-height:normal;color:var(--htl-accent)}
.htl h2{margin:8px 0;font-size:1rem;line-height:normal}
.htl p{font-size:.85rem;line-height:1.65;color:var(--htl-text)}
@media (max-width:480px){.htl{padding:30px 20px 40px;scroll-padding-inline:20px}.htl li{flex-basis:260px}}

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<div role="region" aria-label="Studio history, 1926 to 2026" tabindex="0" class="snap-x snap-mandatory scroll-px-5 overflow-x-auto px-5 pt-[30px] pb-10 [scrollbar-color:#3a3d4a_#101015] [scrollbar-width:thin] focus-visible:rounded-md focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-[#eab308] min-[481px]:scroll-px-10 min-[481px]:px-10">
  <ol class="flex w-max">
    <li class="relative w-[260px] flex-none snap-start pt-[26px] pr-7 before:absolute before:inset-x-0 before:top-0 before:h-[3px] before:bg-[#2c2f3b] after:absolute after:-top-[5px] after:left-0 after:size-[13px] after:rounded-full after:bg-[#eab308] after:shadow-[0_0_12px_rgba(234,179,8,.5)] min-[481px]:w-[300px]"><p class="text-[2rem] font-black tracking-[-.04em] text-[#eab308]"><time datetime="1926">1926</time></p><h2 class="my-2 text-[1rem] font-bold">The letterpress years</h2><p class="text-[.85rem] leading-[1.65] text-[#9ba0af]">Founded as a two-man print shop above a bakery. The original press still works.</p></li>
    <li class="relative w-[260px] flex-none snap-start pt-[26px] pr-7 before:absolute before:inset-x-0 before:top-0 before:h-[3px] before:bg-[#2c2f3b] after:absolute after:-top-[5px] after:left-0 after:size-[13px] after:rounded-full after:bg-[#eab308] after:shadow-[0_0_12px_rgba(234,179,8,.5)] min-[481px]:w-[300px]"><p class="text-[2rem] font-black tracking-[-.04em] text-[#eab308]"><time datetime="1954">1954</time></p><h2 class="my-2 text-[1rem] font-bold">First identity work</h2><p class="text-[.85rem] leading-[1.65] text-[#9ba0af]">The city commissions a crest refresh — the studio's first branding job.</p></li>
    <li class="relative w-[260px] flex-none snap-start pt-[26px] pr-7 before:absolute before:inset-x-0 before:top-0 before:h-[3px] before:bg-[#2c2f3b] after:absolute after:-top-[5px] after:left-0 after:size-[13px] after:rounded-full after:bg-[#eab308] after:shadow-[0_0_12px_rgba(234,179,8,.5)] min-[481px]:w-[300px]"><p class="text-[2rem] font-black tracking-[-.04em] text-[#eab308]"><time datetime="1987">1987</time></p><h2 class="my-2 text-[1rem] font-bold">Going digital</h2><p class="text-[.85rem] leading-[1.65] text-[#9ba0af]">A Macintosh II replaces the paste-up tables. Half the staff threatens to quit; nobody does.</p></li>
    <li class="relative w-[260px] flex-none snap-start pt-[26px] pr-7 before:absolute before:inset-x-0 before:top-0 before:h-[3px] before:bg-[#2c2f3b] after:absolute after:-top-[5px] after:left-0 after:size-[13px] after:rounded-full after:bg-[#eab308] after:shadow-[0_0_12px_rgba(234,179,8,.5)] min-[481px]:w-[300px]"><p class="text-[2rem] font-black tracking-[-.04em] text-[#eab308]"><time datetime="2003">2003</time></p><h2 class="my-2 text-[1rem] font-bold">The web era</h2><p class="text-[.85rem] leading-[1.65] text-[#9ba0af]">First website ships for a client. It has a splash page. We are sorry.</p></li>
    <li class="relative w-[260px] flex-none snap-start pt-[26px] pr-7 before:absolute before:inset-x-0 before:top-0 before:h-[3px] before:bg-[#2c2f3b] after:absolute after:-top-[5px] after:left-0 after:size-[13px] after:rounded-full after:bg-[#eab308] after:shadow-[0_0_12px_rgba(234,179,8,.5)] min-[481px]:w-[300px]"><p class="text-[2rem] font-black tracking-[-.04em] text-[#eab308]"><time datetime="2015">2015</time></p><h2 class="my-2 text-[1rem] font-bold">Product design</h2><p class="text-[.85rem] leading-[1.65] text-[#9ba0af]">From posters to platforms — the studio's first SaaS design system.</p></li>
    <li class="relative w-[260px] flex-none snap-start pt-[26px] pr-7 before:absolute before:inset-x-0 before:top-0 before:h-[3px] before:bg-[#2c2f3b] after:absolute after:-top-[5px] after:left-0 after:size-[13px] after:rounded-full after:bg-[#eab308] after:shadow-[0_0_12px_rgba(234,179,8,.5)] min-[481px]:w-[300px]"><p class="text-[2rem] font-black tracking-[-.04em] text-[#eab308]"><time datetime="2026">2026</time></p><h2 class="my-2 text-[1rem] font-bold">One hundred years</h2><p class="text-[.85rem] leading-[1.65] text-[#9ba0af]">Twelve people, four time zones, and the same rule: make it useful, then make it beautiful.</p></li>
  </ol>
</div>

About this set

A dark, horizontally scrolling timeline that tells a hundred-year studio history in six eras, from 1926 The letterpress years to 2026 One hundred years. Each era is a 300 pixel column with a large yellow year, a heading and a short paragraph, hung from a thin rail with a glowing yellow dot. The track snaps era by era with CSS scroll snap, so a flick on a trackpad or phone always lands cleanly at the start of an era. Use it for company histories, product eras or any long timeline where a horizontal journey suits the page better than a tall list. The scroller is a region with an accessible name and tabindex=”0″, so keyboard users can Tab to it and move with the arrow keys, and it shows a yellow focus outline. The eras are an ordered list sized to their content, so the page itself never scrolls sideways, even at 375 pixels where the columns narrow to 260. The years are time elements. The Bootstrap version uses .overflow-x-auto and .d-flex, and the Tailwind version uses snap-x, snap-mandatory and snap-start.

What’s included

  • Horizontal scroll with mandatory snap per era
  • Focusable named region that scrolls with the arrow keys
  • Rail and glowing dot drawn with ::before and ::after
  • No page overflow at 375px; columns narrow to 260px
  • Thin dark scrollbar where the browser supports it

Accessibility

The scroller is a region named Studio history, 1926 to 2026, with tabindex="0" so it can be reached and scrolled from the keyboard, and it shows a 2px yellow outline on focus. The eras are an ordered list with headings, and years are time elements. All text passes 4.5:1 on the dark background. Nothing animates.

Customise it

Change --htl-accent, --htl-rail and --htl-text on .htl, the 300px column width on the list items, and the padding and scroll-padding together so snapping lines up. In Tailwind edit text-[#eab308], w-[300px] and the scroll-px- utilities.