Layout

Spruce CSS has no classical grid system. Instead, it gives you a set of intrinsic layout primitives: they adapt to the available space, mostly without media queries.

Every primitive exists as a mixin for your components, and (new in v3) as an opt-in utility class for quick prototyping and content pages.

Turn On the Utilities

@use 'sprucecss/scss/spruce' with (
  $settings: (
    'utilities': (
      'layout': true,
    ),
  ),
);

Each class is configurable with custom properties, inline or in your CSS.

Stack

Vertical rhythm: equal space between the direct children.

One
Two
Three
<div class="l-stack" style="--stack-gap: 0.5rem;">…</div>
.article { @include layout-stack('m'); }

Cluster

Inline items that wrap, like tags, buttons or navigation links.

HTML
CSS
Sass
JavaScript
Accessibility
<div class="l-cluster" style="--cluster-gap: 0.5rem; --cluster-justify: center;">…</div>
.tags { @include layout-cluster('xs', $justify: flex-start, $align: center); }

Grid

Responsive columns with a minimum width, without media queries.

One
Two
Three
Four
<div class="l-grid" style="--grid-min: 15rem; --grid-gap: 1rem;">…</div>
.cards { @include layout-grid('m', 15rem); }

A fixed-width sidebar next to a fluid main area; they stack when the main area would get narrower than 50%.

<div class="l-sidebar" style="--sidebar-inline-size: 15rem;">
    <aside>…</aside>
    <main>…</main>
</div>
.page { @include layout-sidebar('l', 15rem); }

Switcher

A row of equal columns that switches to a column when the container is narrower than the threshold.

One
Two
Three
<div class="l-switcher" style="--switcher-threshold: 40rem;">…</div>
.features { @include layout-switcher(40rem, 'm', $limit: 4); }

Reel

A horizontally scrollable row with scroll snapping, for carousels and card rows.

One
Two
Three
Four
Five
Six
<div class="l-reel" style="--reel-item-inline-size: 16rem;">…</div>
.gallery { @include layout-reel(16rem, 's'); }

Center

A centered container with a maximum width and inline padding.

<div class="l-center" style="--center-inline-size: 60rem;">…</div>
.container { @include layout-center('m', 70rem); }

Custom Properties

ClassCustom properties (defaults)
.l-stack--stack-gap (spacer('m'))
.l-cluster--cluster-gap (spacer('s')), --cluster-justify (flex-start)
.l-grid--grid-gap (spacer('m')), --grid-min (12.5rem)
.l-sidebar--sidebar-gap (spacer('m')), --sidebar-inline-size (18.75rem)
.l-switcher--switcher-gap (spacer('m')), --switcher-threshold (30rem)
.l-reel--reel-gap (spacer('m')), --reel-item-inline-size (18rem)
.l-center--center-gap (spacer('m')), --center-inline-size (container-inline-size)

Responsive Helpers

When you need a breakpoint, use the breakpoint mixins: breakpoint('md') (min-width), breakpoint-down('md'), breakpoint-between('md', 'xl'), or the container-query() mixin for component-level responsiveness.

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.