Store

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

.site-header-store {
  background-color: color('background');
  border-block-end: config('border-width-base', $display) solid color('border');
  position: relative;

  &__bar {
    background-color: color('heading');
    color: color('background');
    font-size: config('font-size-sm', $typography);
  }

  &__bar-inner {
    align-items: center;
    display: flex;
    gap: spacer('s');
    justify-content: center;
    min-block-size: 2.25rem;

    @include breakpoint('md') {
      justify-content: space-between;
    }

    p {
      margin: 0;
    }
  }

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

    @include breakpoint('md') {
      display: flex;
    }

    li {
      margin: 0;
    }

    a {
      color: inherit;
      text-decoration: none;

      &:hover {
        text-decoration: underline;
      }
    }

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

  // The search moves to its own row on small screens.
  &__main {
    align-items: center;
    display: grid;
    gap: spacer('s') spacer-clamp('s', 'l');
    grid-template-areas:
      'logo actions'
      'search search';
    grid-template-columns: minmax(0, 1fr) auto;
    padding-block: spacer('s');

    @include breakpoint('md') {
      grid-template-areas: 'logo search actions';
      grid-template-columns: auto minmax(0, 1fr) auto;
    }
  }

  &__logo {
    align-items: center;
    color: color('heading');
    display: inline-flex;
    font-family: config('font-family-heading', $typography);
    font-size: font-size('h5');
    font-weight: config('font-weight-heading', $typography);
    gap: spacer('xs');
    grid-area: logo;
    text-decoration: none;

    img {
      block-size: 2rem;
      inline-size: 2rem;
    }
  }

  &__search {
    display: flex;
    gap: spacer('xxs');
    grid-area: search;
    inline-size: 100%;
    margin-inline: auto;
    max-inline-size: 40rem;

    .form-control {
      flex: 1 1 auto;
      min-inline-size: 0;
    }
  }

  &__actions {
    display: flex;
    gap: spacer('xxs');
    grid-area: actions;
    list-style: none;
    margin: 0;
    padding: 0;

    li {
      margin: 0;
    }

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

  &__action {
    align-items: center;
    border-radius: radius('md');
    color: color('heading');
    display: flex;
    flex-direction: column;
    font-size: 0.75rem;
    font-weight: 600;
    gap: 2px;
    min-block-size: 2.75rem;
    min-inline-size: 2.75rem;
    padding: spacer('xxs') spacer('xs');
    position: relative;
    text-decoration: none;

    &:hover {
      background-color: color('surface-muted');
      color: color('primary');
    }

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

  // The labels are visible from md; below it, they're still there for screen readers.
  &__label {
    @include breakpoint-down('md') {
      @include visually-hidden;
    }
  }

  &__count {
    align-items: center;
    background-color: color('primary');
    block-size: 1.15rem;
    border-radius: radius('pill');
    color: color('primary-foreground', 'btn');
    display: flex;
    font-size: 0.7rem;
    font-weight: 700;
    inset-block-start: 0;
    inset-inline-end: 0;
    justify-content: center;
    min-inline-size: 1.15rem;
    padding-inline: 0.3rem;
    position: absolute;
  }

  &__navigation {
    padding-block-end: spacer('s');

    @include breakpoint('md') {
      padding-block: 0 spacer('s');
    }

    a,
    .site-navigation__toggle {
      font-size: config('font-size-sm', $typography);
    }
  }

  &__sale {
    color: color('danger', 'alert') !important;
  }
}
<a class="skip-link sr-only-focusable" href="#content">Skip to content</a>
<header class="site-header-store">
    <div class="site-header-store__bar">
        <div class="container">
            <div class="site-header-store__bar-inner">
                <p>Free shipping on orders over $50</p>
                <ul class="site-header-store__links" role="list">
                    <li><a href="#">Help</a></li>
                    <li><a href="#">Track order</a></li>
                    <li><a href="#">Stores</a></li>
                </ul>
            </div>
        </div>
    </div>
    <div class="container">
        <div class="site-header-store__main">
            <a class="site-header-store__logo" href="#">
                <img src="/img/cone-logo.svg" alt="" width="40" height="40">
                <span>Cone Store</span>
            </a>
            <form class="site-header-store__search" action="#" method="get" role="search">
                <label class="sr-only" for="store-search">Search products</label>
                <input class="form-control" id="store-search" name="q" type="search" placeholder="Search products…">
                <button class="btn btn--primary btn--icon" type="submit">
                    <svg class="btn__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" aria-hidden="true" focusable="false"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>
                    <span class="sr-only">Search</span>
                </button>
            </form>
            <ul class="site-header-store__actions" role="list">
                <li>
                    <a class="site-header-store__action" href="#">
                        <svg 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="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
                        <span class="site-header-store__label">Account</span>
                    </a>
                </li>
                <li>
                    <a class="site-header-store__action" href="#">
                        <svg 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="M19 14c1.5-1.5 3-3.2 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.8 0-3 .5-4.5 2-1.5-1.5-2.7-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4 3 5.5l7 7z"/></svg>
                        <span class="site-header-store__label">Wishlist</span>
                    </a>
                </li>
                <li>
                    <a class="site-header-store__action" href="#" data-drawer-open="cart-drawer">
                        <svg 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="M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"/><path d="M3 6h18"/><path d="M16 10a4 4 0 0 1-8 0"/></svg>
                        <span class="site-header-store__label">Cart</span>
                        <span class="site-header-store__count">2<span class="sr-only"> items</span></span>
                    </a>
                </li>
            </ul>
        </div>
        <nav class="site-navigation site-header-store__navigation" aria-label="Categories" data-site-navigation>
            <button class="btn btn--secondary btn--sm site-navigation__btn" type="button" aria-controls="store-menu" aria-expanded="false">
                <svg class="btn__icon" aria-hidden="true" fill="none" focusable="false" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path class="site-navigation__line site-navigation__line--top" d="M4 6h16"/><path class="site-navigation__line site-navigation__line--middle" d="M4 12h16"/><path class="site-navigation__line site-navigation__line--bottom" d="M4 18h16"/></svg>
                Categories
            </button>
            <ul class="navigation-menu" id="store-menu">
                <li><a href="#">New in</a></li>
                <li class="site-navigation__item">
                    <button class="site-navigation__toggle" type="button" aria-expanded="false" aria-controls="store-submenu-women">
                        Women
                        <svg class="site-navigation__chevron" aria-hidden="true" fill="none" focusable="false" stroke-linecap="round" stroke-linejoin="round" stroke-width="3" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m6 9 6 6 6-6"/></svg>
                    </button>
                    <ul class="site-navigation__submenu" id="store-submenu-women">
                        <li><a href="#">Clothing</a></li>
                        <li><a href="#">Shoes</a></li>
                        <li><a href="#">Accessories</a></li>
                        <li><a href="#">View all</a></li>
                    </ul>
                </li>
                <li class="site-navigation__item">
                    <button class="site-navigation__toggle" type="button" aria-expanded="false" aria-controls="store-submenu-men">
                        Men
                        <svg class="site-navigation__chevron" aria-hidden="true" fill="none" focusable="false" stroke-linecap="round" stroke-linejoin="round" stroke-width="3" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m6 9 6 6 6-6"/></svg>
                    </button>
                    <ul class="site-navigation__submenu" id="store-submenu-men">
                        <li><a href="#">Clothing</a></li>
                        <li><a href="#">Shoes</a></li>
                        <li><a href="#">Accessories</a></li>
                        <li><a href="#">View all</a></li>
                    </ul>
                </li>
                <li><a href="#" aria-current="page">Home</a></li>
                <li><a href="#">Bags</a></li>
                <li><a href="#">Gifts</a></li>
                <li><a class="site-header-store__sale" href="#">Sale</a></li>
            </ul>
        </nav>
    </div>
</header>

Store

An online store header: an announcement and utility bar, the logo, a wide product search, the account, wishlist and cart links with a counter, and the category navigation.

Anatomy

  • .site-header-store__bar: a dark strip with a message and the utility __links (from the md breakpoint).
  • .site-header-store__main: the __logo, the __search form and the __actions (icon links with a __label and the cart __count). On small screens, the search moves to its own full-width row.
  • .site-header-store__navigation: the categories in a Site Navigation, with a "Categories" button on small screens.

Accessibility

  • The search is a form with role="search" (a search landmark) and a hidden label; the submit button has hidden text.
  • The action labels (Account, Wishlist, Cart) are visible from md and visually hidden below it, so the icon links always have a name. The cart counter reads "Cart, 3 items".
  • The category navigation is labeled "Categories", so it's distinct from other navigation landmarks on the page.
  • The icon links are at least 2.75rem (44px) in both directions.

Technical Details

  • The main row is a grid with named areas: logo search actions from md, and logo actions / search search below it.
  • The sale link keeps its red color with !important, because the navigation sets the link colors with a more specific selector.
  • Connect the search to the Autocomplete for suggestions, and update the cart count when the cart changes (see Mini Cart).
  • The cart link has data-drawer-open="cart-drawer": with the Cart Drawer on the page (and the drawer script), it opens the cart in place; without them it's a normal link to the cart page.
  • "Women" and "Men" have dropdowns with their subcategories.

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.