Product

New 2nd edition, fully updated for 2026

Master modern CSS with a book and a video course

Fourteen chapters and 64 videos on layouts, design tokens, theming and accessible components. Read it, watch it, build it.

4.9 out of 5 from 2,100 readers

  • 380-page ebook
  • 12 hours of video
  • Lifetime updates
Watch the trailer 2:14
@use 'sprucecss/scss/spruce' as *;

.hero-product-block {
  background-image: radial-gradient(ellipse 60% 60% at 85% 20%, #{color-alpha('primary', 0.12)}, transparent);
  overflow: hidden;
  padding-block: spacer-clamp('l', 'xxl');

  &__inner {
    align-items: center;
    display: grid;
    gap: spacer-clamp('l', 'xl');

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

  &__content {
    @include layout-stack('m');
  }

  &__eyebrow {
    align-items: center;
    border: config('border-width-base', $display) solid color('border');
    border-radius: radius('pill');
    color: color('heading');
    display: inline-flex;
    font-size: config('font-size-sm', $typography);
    gap: spacer('xs');
    padding: spacer('xxs') spacer('s') spacer('xxs') spacer('xxs');
  }

  &__badge {
    background-color: color('primary');
    border-radius: radius('pill');
    color: color('primary-foreground', 'btn');
    font-weight: 700;
    padding: 0 spacer('xs');
  }

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

  &__lead {
    font-size: config('font-size-lead', $typography);
    max-inline-size: 36rem;
  }

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

  &__price {
    border-inline-start: config('border-width-base', $display) solid color-alpha('primary-foreground', 0.4, 'btn');
    margin-inline-start: spacer('xs');
    padding-inline-start: spacer('s');
  }

  &__rating {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: spacer('xs');
  }

  &__stars {
    color: color('warning', 'alert');
    letter-spacing: 0.1em;
  }

  &__points {
    display: flex;
    flex-wrap: wrap;
    gap: spacer('xs') spacer('m');
    list-style: none;
    padding: 0;

    li {
      align-items: center;
      color: color('muted');
      display: flex;
      font-size: config('font-size-sm', $typography);
      gap: spacer('xs');
    }

    .block-icon {
      block-size: 1.1rem;
      color: color('primary');
      inline-size: 1.1rem;
    }

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

  // The video and the book overlap: the book sits on the bottom start corner of the video.
  &__media {
    display: grid;
    grid-template-areas: 'stack';
    padding-block-end: spacer-clamp('l', 'xl');
    padding-inline-start: spacer-clamp('l', 'xl');
  }

  &__video {
    aspect-ratio: 4 / 3;
    border-radius: radius('lg');
    box-shadow: shadow('xl');
    color: hsl(0deg 0% 100%);
    display: block;
    grid-area: stack;
    overflow: hidden;
    position: relative;
    text-decoration: none;

    img {
      block-size: 100%;
      inline-size: 100%;
      object-fit: cover;
    }

    &::after {
      background-image: linear-gradient(to bottom, hsl(0deg 0% 0% / 55%), transparent 45%);
      content: '';
      inset: 0;
      position: absolute;
    }

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

  &__play {
    align-items: center;
    background-color: color('surface');
    block-size: 4.5rem;
    border-radius: 50%;
    box-shadow: shadow('lg');
    color: color('primary');
    display: flex;
    inline-size: 4.5rem;
    inset: 0;
    justify-content: center;
    margin: auto;
    position: absolute;
    z-index: 1;

    svg {
      block-size: 1.75rem;
      inline-size: 1.75rem;
      margin-inline-start: 0.2rem;
    }
  }

  &__video-label {
    align-items: center;
    display: flex;
    font-weight: 700;
    gap: spacer('xs');
    // Top end: the book covers the bottom start corner.
    inset-block-start: spacer('m');
    inset-inline-end: spacer('m');
    position: absolute;
    z-index: 1;
  }

  &__duration {
    background-color: hsl(0deg 0% 0% / 60%);
    border-radius: radius('sm');
    font-size: config('font-size-sm', $typography);
    font-variant-numeric: tabular-nums;
    padding: 0 spacer('xxs');
  }

  &__book {
    align-self: end;
    grid-area: stack;
    inline-size: clamp(8rem, 38%, 13rem);
    justify-self: start;
    margin-block-end: calc(#{spacer-clamp('l', 'xl')} * -1);
    margin-inline-start: calc(#{spacer-clamp('l', 'xl')} * -1);
    position: relative;
    z-index: 2;

    .book-cover {
      --book-cover-inline-size: 100%;
    }
  }

  @include motion-safe {
    &__play {
      transition: scale 0.2s ease;
    }

    &__video:hover &__play {
      scale: 1.08;
    }
  }
}
<section class="hero-product-block" aria-labelledby="hero-product-title">
    <div class="container">
        <div class="hero-product-block__inner">
            <div class="hero-product-block__content">
                <p class="hero-product-block__eyebrow"><span class="hero-product-block__badge">New</span> 2nd edition, fully updated for 2026</p>
                <h1 class="hero-product-block__title" id="hero-product-title">Master modern CSS with a book and a video course</h1>
                <p class="hero-product-block__lead">Fourteen chapters and 64 videos on layouts, design tokens, theming and accessible components. Read it, watch it, build it.</p>
                <div class="hero-product-block__actions">
                    <a class="btn btn--primary btn--lg" href="#pricing">Get the bundle <span class="hero-product-block__price">$129</span></a>
                    <a class="btn btn--outline-primary btn--lg" href="#book-preview">
                        <svg class="btn__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="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m7 10 5 5 5-5"/><path d="M12 15V3"/>
</svg>
                        Read a free chapter
                    </a>
                </div>
                <p class="hero-product-block__rating">
                    <span class="hero-product-block__stars" aria-hidden="true">★★★★★</span>
                    <span><strong>4.9</strong><span class="sr-only"> out of 5</span> from 2,100 readers</span>
                </p>
                <ul class="hero-product-block__points" role="list">
                    <li><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>
 380-page ebook</li>
                    <li><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="m22 8-6 4 6 4V8z"/><rect width="14" height="12" x="2" y="6" rx="2"/>
</svg>
 12 hours of video</li>
                    <li><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 12c-2-2.7-4-4-6-4a4 4 0 0 0 0 8c2 0 4-1.3 6-4zm0 0c2 2.7 4 4 6 4a4 4 0 0 0 0-8c-2 0-4 1.3-6 4z"/>
</svg>
 Lifetime updates</li>
                </ul>
            </div>
            <div class="hero-product-block__media">
                <a class="hero-product-block__video" href="#video-library">
                    <img src="https://images.unsplash.com/photo-1517694712202-14dd9538aa97?auto=format&amp;fit=crop&amp;w=900&amp;q=70" alt="" width="900" height="600" fetchpriority="high">
                    <span class="hero-product-block__play" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" focusable="false"><path d="M7 4v16l13-8z"/></svg></span>
                    <span class="hero-product-block__video-label">Watch the trailer <span class="hero-product-block__duration">2:14</span></span>
                </a>
                <div class="hero-product-block__book">
                    <div class="book-cover" role="img" aria-label="The cover of Modern CSS, Explained by Daniel Okafor">
                        <div class="book-cover__front">
                            <p class="book-cover__edition">2nd edition</p>
                            <div class="book-cover__heading">
                                <p class="book-cover__title">Modern CSS, Explained</p>
                                <p class="book-cover__subtitle">From the cascade to design systems</p>
                            </div>
                            <p class="book-cover__author">Daniel Okafor</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</section>

Product

On this page

A sales hero for a digital product: the offer, the price on the buy button, the rating and the formats, next to the product itself, a book cover on top of a video thumbnail.

Technical Details

  • It combines the Book Cover; load its stylesheet too.
  • The buy button shows the price, so there's no surprise on the pricing section; it jumps to #pricing. The second button jumps to the free chapter (#book-preview), and the video thumbnail to the video library (#video-library).
  • The stars are decorative; the rating is in the text with a hidden "out of 5".
  • The video and the book overlap in one grid area, without absolute positioning: the book sits on the bottom start corner and mirrors in RTL.
  • The video thumbnail is the hero image, so it loads with fetchpriority="high", not lazily.
  • Override the content with heroProductBlock; the cover takes the book object (see the book cover's data).

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.