Bento

Platform

Everything in one place

A flexible toolkit that grows with your product.

  • Analytics

    Understand your visitors with privacy-friendly analytics.

  • 99.99% uptime

    Global edge network with automatic failover.

  • Design styles

    Eight looks, one markup.

  • Developer friendly

    Sass helpers, tokens and a clean API for your own components.

  • Team roles

    Invite editors, reviewers and admins.

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

.bento-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');
    grid-auto-flow: dense;

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

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

  &__tile {
    background-color: color('surface');
    border: config('border-width-base', $display) solid color('border');
    border-radius: radius('lg');
    // Flex, not layout-stack: the visual grows to fill the tall and large tiles.
    display: flex;
    flex-direction: column;
    gap: spacer('xs');
    overflow: hidden;
    padding: spacer-clamp('m', 'l');

    @include breakpoint('md') {
      &--wide {
        grid-column: span 2;
      }

      &--tall {
        grid-row: span 2;
      }

      &--large {
        grid-column: span 2;
        grid-row: span 2;
      }
    }
  }

  &__visual {
    align-items: flex-end;
    background-color: color('surface-muted');
    border-radius: radius('md');
    display: flex;
    flex-grow: 1;
    gap: spacer('xs');
    justify-content: center;
    margin-block-end: spacer('xs');
    min-block-size: 8rem;
    padding: spacer('m');

    &--chart span {
      background-image: linear-gradient(to top, #{color('primary')}, #{color-alpha('primary', 0.4)});
      block-size: var(--h);
      border-radius: radius('sm') radius('sm') 0 0;
      flex: 1;
      max-inline-size: 3rem;
    }

    &--stat {
      align-items: center;

      strong {
        color: color('primary');
        font-family: config('font-family-heading', $typography);
        font-size: responsive-font-size(3rem, 30, '3vw + 1rem');
      }
    }

    &--swatches {
      align-items: center;

      span {
        block-size: 2.5rem;
        border-radius: 50%;
        box-shadow: 0 0 0 3px color('surface');
        inline-size: 2.5rem;
        margin-inline-start: -0.75rem;

        &:nth-child(1) { background-color: color('primary'); }
        &:nth-child(2) { background-color: color('secondary'); }
        &:nth-child(3) { background-color: color('success', 'alert'); }
        &:nth-child(4) { background-color: color('warning', 'alert'); }
      }
    }

    &--code {
      align-items: flex-start;
      flex-direction: column;
      justify-content: center;
    }

    &--people {
      align-items: center;

      span {
        background-color: color-alpha('primary', 0.25);
        block-size: 3rem;
        border: 3px solid color('surface');
        border-radius: 50%;
        inline-size: 3rem;
        margin-inline-start: -0.75rem;

        &:nth-child(2) { background-color: color-alpha('secondary', 0.35); }
        &:nth-child(3) { background-color: color-alpha('primary', 0.5); }
      }
    }
  }

  // The tile is a flex column, so its text children drop the browser margins.
  &__title {
    font-size: font-size('h4');
    margin-block: 0;
  }

  &__text {
    color: color('muted');
    margin-block: 0;
  }
}
<section class="bento-block" aria-labelledby="bento-title">
    <div class="container">
        <div class="bento-block__inner">
            <header class="block-heading">
                <p class="block-heading__eyebrow">Platform</p>
                <h2 class="block-heading__title" id="bento-title">Everything in one place</h2>
                <p class="block-heading__text">A flexible toolkit that grows with your product.</p>
            </header>
            <ul class="bento-block__grid" role="list">
                <li class="bento-block__tile bento-block__tile--large">
                    <div class="bento-block__visual bento-block__visual--chart" aria-hidden="true"><span style="--h: 40%"></span><span style="--h: 65%"></span><span style="--h: 50%"></span><span style="--h: 80%"></span><span style="--h: 70%"></span><span style="--h: 95%"></span>
                    </div>
                    <h3 class="bento-block__title">Analytics</h3>
                    <p class="bento-block__text">Understand your visitors with privacy-friendly analytics.</p>
                </li>
                <li class="bento-block__tile">
                    <div class="bento-block__visual bento-block__visual--stat" aria-hidden="true"><strong>99.99%</strong>
                    </div>
                    <h3 class="bento-block__title">99.99% uptime</h3>
                    <p class="bento-block__text">Global edge network with automatic failover.</p>
                </li>
                <li class="bento-block__tile">
                    <div class="bento-block__visual bento-block__visual--swatches" aria-hidden="true"><span></span><span></span><span></span><span></span>
                    </div>
                    <h3 class="bento-block__title">Design styles</h3>
                    <p class="bento-block__text">Eight looks, one markup.</p>
                </li>
                <li class="bento-block__tile bento-block__tile--wide">
                    <div class="bento-block__visual bento-block__visual--code" aria-hidden="true"><code>@include layout-grid('m', 16rem);</code><code>border-radius: radius('lg');</code>
                    </div>
                    <h3 class="bento-block__title">Developer friendly</h3>
                    <p class="bento-block__text">Sass helpers, tokens and a clean API for your own components.</p>
                </li>
                <li class="bento-block__tile">
                    <div class="bento-block__visual bento-block__visual--people" aria-hidden="true"><span></span><span></span><span></span>
                    </div>
                    <h3 class="bento-block__title">Team roles</h3>
                    <p class="bento-block__text">Invite editors, reviewers and admins.</p>
                </li>
            </ul>
        </div>
    </div>
</section>

Bento

On this page

A bento grid of feature tiles in different sizes, each with a small decorative visual.

Technical Details

  • A three-column grid from the md breakpoint; tiles can span with the wide (2 columns), tall (2 rows) and large (2×2) sizes. grid-auto-flow: dense fills the gaps.
  • The visuals (chart, stat, swatches, code, people) are pure CSS, decorative (aria-hidden) and built from the color tokens, so they adapt to every style.
  • Each tile is a list item with a heading; the order of the items is the reading order.
  • Override the content with bentoBlock.

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.