Changelog

  1. v3.0.0 Latest

    • Added Design styles: switch the whole look with one data-spruce-style attribute.
    • Added Built-in dark mode that can follow the system preference.
    • Changed The form controls use block-size instead of height.
    • Fixed The select icon in right-to-left layouts.

    Release notes for v3.0.0

  2. v2.4.0

    • Added The layout-cluster() mixin.
    • Deprecated The $btn-font-family variable; use the $btn map.

    Release notes for v2.4.0

  3. v2.3.1

    • Fixed The focus ring of the outline buttons in Safari.
    • Security Updated the build dependencies.

    Release notes for v2.3.1

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

.l-changelog {
  @include clear-list;
  @include layout-stack('l');

  &__item {
    align-items: start;
    display: grid;
    gap: spacer('s') spacer('l');
    grid-template-columns: minmax(0, 1fr);

    @include breakpoint('md') {
      grid-template-columns: minmax(0, 9rem) minmax(0, 1fr);
    }

    + .l-changelog__item {
      border-block-start: config('border-width-base', $display) solid color('border');
      padding-block-start: spacer('l');
    }
  }

  &__date {
    color: color('muted');
    font-size: config('font-size-sm', $typography);
    font-variant-numeric: tabular-nums;
    font-weight: 700;

    @include breakpoint('md') {
      inset-block-start: spacer('m');
      position: sticky;
    }
  }

  &__body {
    @include layout-stack('s');
  }

  &__title {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    font-size: font-size('h3');
    gap: spacer('xs');
    margin-block: 0;
  }

  &__latest {
    background-color: color('primary');
    border-radius: radius('pill');
    color: color('primary-foreground', 'btn');
    font-size: 0.75rem;
    font-weight: 700;
    padding: 0 0.7em;
  }

  &__list {
    list-style: none;
    padding: 0;
    @include layout-stack('xs');
  }

  &__tag {
    border-radius: radius('sm');
    display: inline-block;
    font-size: 0.75rem;
    font-weight: 700;
    margin-inline-end: spacer('xxs');
    min-inline-size: 6.5rem;
    padding: 0.15em 0.5em;
    text-align: center;

    &--added { background-color: color-alpha('success', 0.12, 'alert');
      color: color('success', 'alert'); }

    &--changed { background-color: color-alpha('primary', 0.12);
      color: color('primary'); }

    &--deprecated,
    &--security { background-color: color-alpha('warning', 0.15, 'alert');
      color: color('warning', 'alert'); }

    &--fixed { background-color: color-alpha('info', 0.12, 'alert');
      color: color('info', 'alert'); }

    &--removed { background-color: color-alpha('danger', 0.12, 'alert');
      color: color('danger', 'alert'); }
  }

  &__link {
    font-size: config('font-size-sm', $typography);
    font-weight: 600;
  }
}
<ol class="l-changelog" reversed>
    <li class="l-changelog__item" aria-labelledby="release-v3-0-0">
        <time class="l-changelog__date" datetime="2026-10-01">Oct 1, 2026</time>
        <div class="l-changelog__body">
            <h2 class="l-changelog__title" id="release-v3-0-0">v3.0.0 <span class="l-changelog__latest">Latest</span></h2>
            <ul class="l-changelog__list">
                <li><span class="l-changelog__tag l-changelog__tag--added">Added</span> Design styles: switch the whole look with one <code>data-spruce-style</code> attribute.</li>
                <li><span class="l-changelog__tag l-changelog__tag--added">Added</span> Built-in dark mode that can follow the system preference.</li>
                <li><span class="l-changelog__tag l-changelog__tag--changed">Changed</span> The form controls use <code>block-size</code> instead of <code>height</code>.</li>
                <li><span class="l-changelog__tag l-changelog__tag--fixed">Fixed</span> The select icon in right-to-left layouts.</li>
            </ul>
            <p class="l-changelog__more"><a class="l-changelog__link" href="#">Release notes for v3.0.0</a></p>
        </div>
    </li>
    <li class="l-changelog__item" aria-labelledby="release-v2-4-0">
        <time class="l-changelog__date" datetime="2026-03-12">Mar 12, 2026</time>
        <div class="l-changelog__body">
            <h2 class="l-changelog__title" id="release-v2-4-0">v2.4.0</h2>
            <ul class="l-changelog__list">
                <li><span class="l-changelog__tag l-changelog__tag--added">Added</span> The <code>layout-cluster()</code> mixin.</li>
                <li><span class="l-changelog__tag l-changelog__tag--deprecated">Deprecated</span> The <code>$btn-font-family</code> variable; use the <code>$btn</code> map.</li>
            </ul>
            <p class="l-changelog__more"><a class="l-changelog__link" href="#">Release notes for v2.4.0</a></p>
        </div>
    </li>
    <li class="l-changelog__item" aria-labelledby="release-v2-3-1">
        <time class="l-changelog__date" datetime="2025-11-03">Nov 3, 2025</time>
        <div class="l-changelog__body">
            <h2 class="l-changelog__title" id="release-v2-3-1">v2.3.1</h2>
            <ul class="l-changelog__list">
                <li><span class="l-changelog__tag l-changelog__tag--fixed">Fixed</span> The focus ring of the outline buttons in Safari.</li>
                <li><span class="l-changelog__tag l-changelog__tag--security">Security</span> Updated the build dependencies.</li>
            </ul>
            <p class="l-changelog__more"><a class="l-changelog__link" href="#">Release notes for v2.3.1</a></p>
        </div>
    </li>
</ol>

Changelog

A release history: every version with its date, a "Latest" badge and the changes grouped by type, following the Keep a Changelog conventions.

Anatomy

  • .l-changelog is an ordered list with reversed, so the newest release comes first and the numbering stays meaningful.
  • .l-changelog__item is one release: a time element (__date) and the body (__title, __list, __link).
  • .l-changelog__latest marks the current version.
  • .l-changelog__tag labels each change: --added, --changed, --deprecated, --removed, --fixed and --security.

Accessibility

  • The tags are real text ("Added", "Fixed") in front of the change, not only colors, so they're read out and work in high contrast mode.
  • Every release is a heading, so screen reader users can jump between versions, and the list item is labelled by it.
  • The time element has a machine-readable datetime.

Technical Details

  • From the md breakpoint, the date sits in its own column and sticks to the top while you scroll a long release.
  • The tag colors use the alert colors (success, info, warning, danger) and color-alpha(), so they follow the dark mode.
  • The tags have the same minimum width, so the change texts line up.

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.