Timeline

Our story

From a side project to a framework

  1. 2021

    The first commit

    Spruce starts as the CSS we kept copying from project to project.

  2. 2022

    Version 1.0

    The framework, the documentation and the first components are public.

  3. 2023

    Spruce UI

    A growing library of accessible, copy-paste components.

  4. 2024

    Version 2

    CSS custom property mode, dark mode and logical properties everywhere.

  5. 2026

    Version 3

    Design styles, blocks, pages and AI skills.

@use 'sprucecss/scss/spruce' as *;

.timeline-block {
  padding-block: spacer-clamp('xl', 'xxl');

  &__inner {
    display: flex;
    flex-direction: column;
    gap: spacer('l');
  }

  &__list {
    @include clear-list;
    display: grid;
    gap: spacer('m');
    inline-size: 100%;
    margin-inline: auto;
    max-inline-size: 56rem;
    position: relative;

    &::before {
      background-color: color('border');
      content: '';
      inline-size: 2px;
      inset-block: 0;
      inset-inline-start: 0.6rem;
      position: absolute;

      @include breakpoint('md') {
        inset-inline-start: calc(50% - 1px);
      }
    }

    // The items sit side by side: clear the stack margins of the base list style.
    > li {
      margin-block: 0;
      padding-block: 0;
    }
  }

  &__item {
    display: grid;
    gap: spacer('m');
    grid-template-columns: 1.25rem 1fr;
    position: relative;

    @include breakpoint('md') {
      grid-template-columns: 1fr 1.25rem 1fr;

      &:nth-child(odd) .timeline-block__card {
        grid-column: 1;
        grid-row: 1;
        text-align: end;
      }

      &:nth-child(even) .timeline-block__card {
        grid-column: 3;
      }

      .timeline-block__marker {
        grid-column: 2;
        grid-row: 1;
      }
    }
  }

  &__marker {
    background-color: color('background');
    block-size: 1.25rem;
    border: 3px solid color('primary');
    border-radius: 50%;
    inline-size: 1.25rem;
    margin-block-start: spacer('m');
    position: relative;
  }

  &__card {
    background-color: color('surface');
    border: config('border-width-base', $display) solid color('border');
    border-radius: radius('lg');
    padding: spacer('m');
    @include layout-stack('xxs');
  }

  &__date {
    color: color('primary');
    font-size: config('font-size-sm', $typography);
    font-weight: 700;
  }

  &__title {
    font-size: font-size('h4');
  }

  &__text {
    color: color('muted');
  }
}
<section class="timeline-block" aria-labelledby="timeline-title">
    <div class="container">
        <div class="timeline-block__inner">
            <header class="block-heading">
                <p class="block-heading__eyebrow">Our story</p>
                <h2 class="block-heading__title" id="timeline-title">From a side project to a framework</h2>
            </header>
            <ol class="timeline-block__list" role="list">
                <li class="timeline-block__item">
                    <span class="timeline-block__marker" aria-hidden="true"></span>
                    <div class="timeline-block__card">
                        <p class="timeline-block__date">2021</p>
                        <h3 class="timeline-block__title">The first commit</h3>
                        <p class="timeline-block__text">Spruce starts as the CSS we kept copying from project to project.</p>
                    </div>
                </li>
                <li class="timeline-block__item">
                    <span class="timeline-block__marker" aria-hidden="true"></span>
                    <div class="timeline-block__card">
                        <p class="timeline-block__date">2022</p>
                        <h3 class="timeline-block__title">Version 1.0</h3>
                        <p class="timeline-block__text">The framework, the documentation and the first components are public.</p>
                    </div>
                </li>
                <li class="timeline-block__item">
                    <span class="timeline-block__marker" aria-hidden="true"></span>
                    <div class="timeline-block__card">
                        <p class="timeline-block__date">2023</p>
                        <h3 class="timeline-block__title">Spruce UI</h3>
                        <p class="timeline-block__text">A growing library of accessible, copy-paste components.</p>
                    </div>
                </li>
                <li class="timeline-block__item">
                    <span class="timeline-block__marker" aria-hidden="true"></span>
                    <div class="timeline-block__card">
                        <p class="timeline-block__date">2024</p>
                        <h3 class="timeline-block__title">Version 2</h3>
                        <p class="timeline-block__text">CSS custom property mode, dark mode and logical properties everywhere.</p>
                    </div>
                </li>
                <li class="timeline-block__item">
                    <span class="timeline-block__marker" aria-hidden="true"></span>
                    <div class="timeline-block__card">
                        <p class="timeline-block__date">2026</p>
                        <h3 class="timeline-block__title">Version 3</h3>
                        <p class="timeline-block__text">Design styles, blocks, pages and AI skills.</p>
                    </div>
                </li>
            </ol>
        </div>
    </div>
</section>

Timeline

On this page

A vertical timeline for a company history, a roadmap or release milestones.

Technical Details

  • An ordered list of milestones; the line and the markers are decorative.
  • On small screens the line runs along the start edge; from the md breakpoint the cards alternate on both sides. Everything uses logical properties (inset-inline-start, text-align: end), so it mirrors in RTL.
  • For a dated changelog with tags, see the Changelog component.
  • Override the content with timelineBlock.

Documentation

Learn about Spruce CSS through our extensive documentation.

Components

Explore our UI library of accessible components built with Spruce CSS.

Blocks and Pages

Full-width page blocks and complete page templates, ready to copy.

Find us on GitHub

Did you find a bug? Have an idea or a question? Please open an issue to help us develop the project.