Features

Features

Everything you need to ship faster

Spruce gives you the foundation, so you can focus on the product.

  • Design styles

    Switch the whole look with one attribute: from minimal to brutalist.

  • Design tokens

    Colors, spacing, radii and shadows as Sass variables and custom properties.

  • Tiny footprint

    Around 9 KB gzipped. Every bigger feature is opt-in.

  • Accessible

    Visible focus states, reduced motion support and semantic markup.

  • RTL ready

    Logical properties everywhere, so every layout mirrors correctly.

  • Sass helpers

    Mixins and functions for layouts, breakpoints and components.

  • Dark mode

    A complete dark palette that can follow the system preference.

  • Documented

    Every token, mixin and element explained with live examples.

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

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

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

  &__grid {
    @include clear-list;
    display: grid;
    gap: spacer('m');

    // 1, 2, then 3 or 4 columns (set by the template from the item count), so the items fill whole rows.
    @include breakpoint('sm') {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    &--3 {
      @include breakpoint('lg') {
        grid-template-columns: repeat(3, minmax(0, 1fr));
      }
    }

    &--4 {
      @include breakpoint('lg') {
        grid-template-columns: repeat(4, minmax(0, 1fr));
      }
    }

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

  &__item {
    background-color: color('surface');
    border: config('border-width-base', $display) solid color('border');
    border-radius: radius('lg');
    padding: spacer-clamp('m', 'l');
    @include layout-stack('xs');
    @include transition($property: 'box-shadow, translate');

    &:hover {
      box-shadow: shadow('md');
      translate: 0 -2px;
    }
  }

  &__icon {
    align-items: center;
    background-color: color-alpha('primary', 0.12);
    block-size: 3rem;
    border-radius: radius('md');
    color: color('primary');
    display: inline-flex;
    inline-size: 3rem;
    justify-content: center;
    margin-block-end: spacer('xs');

    svg {
      block-size: 1.5rem;
      inline-size: 1.5rem;
    }
  }

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

  &__text {
    color: color('muted');
  }
}
<section class="features-block" aria-labelledby="features-title">
    <div class="container">
        <div class="features-block__inner">
            <header class="block-heading">
                <p class="block-heading__eyebrow">Features</p>
                <h2 class="block-heading__title" id="features-title">Everything you need to ship faster</h2>
                <p class="block-heading__text">Spruce gives you the foundation, so you can focus on the product.</p>
            </header>
            <ul class="features-block__grid features-block__grid--4" role="list">
                <li class="features-block__item">
                    <span class="features-block__icon"><svg class="block-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<circle cx="13.5" cy="6.5" r="1"/><circle cx="17.5" cy="10.5" r="1"/><circle cx="8.5" cy="7.5" r="1"/><circle cx="6.5" cy="12.5" r="1"/><path d="M12 2a10 10 0 0 0 0 20 1.7 1.7 0 0 0 1.2-2.9 1.6 1.6 0 0 1 1.2-2.8h2A5.6 5.6 0 0 0 22 10.8C22 6 17.5 2 12 2z"/>
</svg>
</span>
                    <h3 class="features-block__title">Design styles</h3>
                    <p class="features-block__text">Switch the whole look with one attribute: from minimal to brutalist.</p>
                </li>
                <li class="features-block__item">
                    <span class="features-block__icon"><svg class="block-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="m12 2 10 5-10 5L2 7l10-5z"/><path d="m2 17 10 5 10-5"/><path d="m2 12 10 5 10-5"/>
</svg>
</span>
                    <h3 class="features-block__title">Design tokens</h3>
                    <p class="features-block__text">Colors, spacing, radii and shadows as Sass variables and custom properties.</p>
                </li>
                <li class="features-block__item">
                    <span class="features-block__icon"><svg class="block-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M13 2 3 14h9l-1 8 10-12h-9l1-8z"/>
</svg>
</span>
                    <h3 class="features-block__title">Tiny footprint</h3>
                    <p class="features-block__text">Around 9 KB gzipped. Every bigger feature is opt-in.</p>
                </li>
                <li class="features-block__item">
                    <span class="features-block__icon"><svg class="block-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>
</svg>
</span>
                    <h3 class="features-block__title">Accessible</h3>
                    <p class="features-block__text">Visible focus states, reduced motion support and semantic markup.</p>
                </li>
                <li class="features-block__item">
                    <span class="features-block__icon"><svg class="block-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<circle cx="12" cy="12" r="10"/><path d="M2 12h20"/><path d="M12 2a15 15 0 0 1 0 20 15 15 0 0 1 0-20z"/>
</svg>
</span>
                    <h3 class="features-block__title">RTL ready</h3>
                    <p class="features-block__text">Logical properties everywhere, so every layout mirrors correctly.</p>
                </li>
                <li class="features-block__item">
                    <span class="features-block__icon"><svg class="block-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="m16 18 6-6-6-6"/><path d="m8 6-6 6 6 6"/>
</svg>
</span>
                    <h3 class="features-block__title">Sass helpers</h3>
                    <p class="features-block__text">Mixins and functions for layouts, breakpoints and components.</p>
                </li>
                <li class="features-block__item">
                    <span class="features-block__icon"><svg class="block-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M12 3 9.5 9.5 3 12l6.5 2.5L12 21l2.5-6.5L21 12l-6.5-2.5L12 3z"/>
</svg>
</span>
                    <h3 class="features-block__title">Dark mode</h3>
                    <p class="features-block__text">A complete dark palette that can follow the system preference.</p>
                </li>
                <li class="features-block__item">
                    <span class="features-block__icon"><svg class="block-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20V2H6.5A2.5 2.5 0 0 0 4 4.5v15z"/><path d="M4 19.5A2.5 2.5 0 0 0 6.5 22H20v-5"/>
</svg>
</span>
                    <h3 class="features-block__title">Documented</h3>
                    <p class="features-block__text">Every token, mixin and element explained with live examples.</p>
                </li>
            </ul>
        </div>
    </div>
</section>

Features

On this page

A feature grid block: a heading and a responsive grid of icon cards.

Technical Details

  • The content comes from a featuresBlock object (heading and items with icon, title, text); without it, the default copy renders. The home page templates override it.
  • The heading is the Block Heading component; the block is labelled by it.
  • The items are a list (role="list" keeps the semantics) in one, two, then three or four columns from the lg breakpoint. The template picks three columns when the items fill rows of three but not of four (6 or 9 items), and four otherwise (4 or 8 items), so the rows are always full.
  • The icons are decorative and live in a shared block/icon.html partial.

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.