Shop

The autumn collection

Everyday things, made to last

Bags, homeware and tech accessories designed in Portland, built for years of daily use.

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

.hero-shop-block {
  padding-block: spacer('m') spacer-clamp('xl', 'xxl');

  &__inner {
    display: grid;
    gap: spacer('m');

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

  // The image fills the tile; a shade keeps the white text readable on any photo.
  &__main,
  &__tile {
    @include set-css-variable((
      --base-color-heading: hsl(0deg 0% 100%),
      --base-color-text: hsl(0deg 0% 100%),
    ));
    background-color: color('heading');
    border-radius: radius('lg');
    color: hsl(0deg 0% 100%);
    display: flex;
    isolation: isolate;
    overflow: hidden;
    position: relative;

    &::after {
      background-image: linear-gradient(to top, hsl(0deg 0% 0% / 70%), hsl(0deg 0% 0% / 10%) 70%);
      content: '';
      inset: 0;
      position: absolute;
      z-index: -1;
    }
  }

  &__main {
    align-items: flex-end;
    min-block-size: clamp(26rem, 60vb, 36rem);
  }

  &__image {
    block-size: 100%;
    inline-size: 100%;
    inset: 0;
    object-fit: cover;
    position: absolute;
    z-index: -2;
  }

  &__content {
    max-inline-size: 36rem;
    padding: spacer-clamp('m', 'xl');
    @include layout-stack('s');
  }

  &__eyebrow {
    font-size: config('font-size-sm', $typography);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }

  &__title {
    font-size: responsive-font-size(4rem, 40, '5vw + 1rem');
    letter-spacing: -0.02em;
    line-height: 1.05;
    text-wrap: balance;
  }

  &__text {
    font-size: config('font-size-lead', $typography);
    opacity: 0.9;
  }

  &__actions {
    @include layout-cluster('s');
  }

  &__primary {
    background-color: hsl(0deg 0% 100%);
    border-color: hsl(0deg 0% 100%);
    color: hsl(0deg 0% 10%);

    &:hover {
      background-color: hsl(0deg 0% 92%);
      border-color: hsl(0deg 0% 92%);
      color: hsl(0deg 0% 10%);
    }
  }

  &__secondary {
    background-color: transparent;
    border-color: hsl(0deg 0% 100% / 70%);
    color: hsl(0deg 0% 100%);

    &:hover {
      background-color: hsl(0deg 0% 100% / 15%);
      border-color: hsl(0deg 0% 100%);
      color: hsl(0deg 0% 100%);
    }
  }

  &__tiles {
    display: grid;
    gap: spacer('m');
    list-style: none;
    margin: 0;
    padding: 0;

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

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

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

  &__tile {
    @include a11y-card-link('.hero-shop-block__link', true);
    align-items: flex-end;
    min-block-size: 14rem;
  }

  &__tile-content {
    padding: spacer('m');
    @include layout-stack('xxs');
  }

  &__tile-title {
    font-size: font-size('h3');
  }

  &__link {
    color: inherit;
    text-decoration: none;

    &:focus-visible {
      outline: none;
    }

    &:focus-visible::before {
      border-radius: radius('lg');
      outline: 3px solid color('focus-ring');
      outline-offset: -3px;
    }
  }

  &__more {
    align-items: center;
    display: flex;
    font-weight: 700;
    gap: spacer('xs');

    .block-icon {
      block-size: 1rem;
      inline-size: 1rem;
    }
  }

  @include motion-safe {
    &__image {
      transition: scale 0.5s ease;
    }

    &__tile:hover &__image {
      scale: 1.05;
    }
  }
}

[dir='rtl'] .hero-shop-block__more .block-icon {
  scale: -1 1;
}
<section class="hero-shop-block" aria-labelledby="hero-shop-title">
    <div class="container">
        <div class="hero-shop-block__inner">
            <div class="hero-shop-block__main">
                <img class="hero-shop-block__image" src="https://images.unsplash.com/photo-1441986300917-64674bd600d8?auto=format&amp;fit=crop&amp;w=1400&amp;q=70" alt="" width="1400" height="933" fetchpriority="high">
                <div class="hero-shop-block__content">
                    <p class="hero-shop-block__eyebrow">The autumn collection</p>
                    <h1 class="hero-shop-block__title" id="hero-shop-title">Everyday things, made to last</h1>
                    <p class="hero-shop-block__text">Bags, homeware and tech accessories designed in Portland, built for years of daily use.</p>
                    <div class="hero-shop-block__actions">
                        <a class="btn btn--lg hero-shop-block__primary" href="#">Shop new arrivals</a>
                        <a class="btn btn--lg hero-shop-block__secondary" href="#">Explore homeware</a>
                    </div>
                </div>
            </div>
            <ul class="hero-shop-block__tiles" role="list">
                <li class="hero-shop-block__tile">
                    <img class="hero-shop-block__image" src="https://images.unsplash.com/photo-1547949003-9792a18a2601?auto=format&amp;fit=crop&amp;w=800&amp;q=70" alt="" width="800" height="600">
                    <div class="hero-shop-block__tile-content">
                        <p class="hero-shop-block__eyebrow">Up to 30% off</p>
                        <h2 class="hero-shop-block__tile-title"><a class="hero-shop-block__link" href="#">Travel bags</a></h2>
                        <p class="hero-shop-block__more" aria-hidden="true">Shop bags <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="M5 12h14"/><path d="m12 5 7 7-7 7"/>
</svg>
</p>
                    </div>
                </li>
                <li class="hero-shop-block__tile">
                    <img class="hero-shop-block__image" src="https://images.unsplash.com/photo-1495474472287-4d71bcdd2085?auto=format&amp;fit=crop&amp;w=800&amp;q=70" alt="" width="800" height="600">
                    <div class="hero-shop-block__tile-content">
                        <p class="hero-shop-block__eyebrow">New in</p>
                        <h2 class="hero-shop-block__tile-title"><a class="hero-shop-block__link" href="#">The coffee corner</a></h2>
                        <p class="hero-shop-block__more" aria-hidden="true">Shop coffee <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="M5 12h14"/><path d="m12 5 7 7-7 7"/>
</svg>
</p>
                    </div>
                </li>
            </ul>
        </div>
    </div>
</section>

Shop

On this page

A store front hero: the campaign on a large photo with two calls to action, and two smaller tiles that lead into a category or an offer.

Technical Details

  • The photos are real img elements behind the text (object-fit: cover, stacked with z-index inside an isolated tile), so they get alt, lazy loading and responsive images like any image. The main photo is the hero image, so it loads with fetchpriority="high".
  • A dark gradient shade keeps the white text readable on any photo, in every style; the tiles redefine the heading and text color tokens for their subtree.
  • The campaign title is the only h1. The side tiles are clickable cards (a11y-card-link()) with the link on their h2; the "Shop bags" line is decorative.
  • On wide screens the tiles stack next to the campaign; on tablets they sit in a row under it.
  • Override the content with heroShopBlock.

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.