Next Project

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

.next-project-block {
  padding-block: spacer-clamp('xl', 'xxl');

  // A photo card: the image fills it, a shade keeps the white text readable.
  &__card {
    @include a11y-card-link('.next-project-block__link', true);
    @include set-css-variable((
      --base-color-heading: hsl(0deg 0% 100%),
      --base-color-text: hsl(0deg 0% 100%),
      --base-color-link: hsl(0deg 0% 100%),
      --base-color-link-hover: hsl(0deg 0% 100% / 0.75),
    ));
    align-items: flex-end;
    background-color: color('heading');
    border-radius: radius('lg');
    color: hsl(0deg 0% 100%);
    display: flex;
    gap: spacer('m');
    isolation: isolate;
    justify-content: space-between;
    min-block-size: clamp(18rem, 40vb, 26rem);
    overflow: hidden;
    padding: spacer-clamp('m', 'xl');

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

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

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

  &__content {
    max-inline-size: 40rem;
    @include layout-stack('xs');
  }

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

  &__client {
    font-weight: 700;
  }

  &__title {
    font-size: responsive-font-size(3rem, 30, '3vw + 1rem');
    line-height: 1.1;
    text-wrap: balance;
  }

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

    &:focus {
      outline: none;
    }
  }

  &__text {
    opacity: 0.9;
  }

  &__arrow {
    align-items: center;
    background-color: hsl(0deg 0% 100%);
    block-size: 3.5rem;
    border-radius: 50%;
    color: hsl(0deg 0% 10%);
    display: flex;
    flex-shrink: 0;
    inline-size: 3.5rem;
    justify-content: center;

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

  @include motion-safe {
    &__image,
    &__arrow {
      transition: scale 0.4s ease, translate 0.2s ease;
    }

    &__card:hover &__image {
      scale: 1.04;
    }

    &__card:hover &__arrow {
      translate: 0.25rem 0;
    }
  }
}

[dir='rtl'] .next-project-block__arrow .block-icon {
  scale: -1 1;
}

@media (prefers-reduced-motion: no-preference) {
  [dir='rtl'] .next-project-block__card:hover .next-project-block__arrow {
    translate: -0.25rem 0;
  }
}
<section class="next-project-block" aria-labelledby="next-project-title">
    <div class="container">
        <article class="next-project-block__card">
            <img class="next-project-block__image" src="https://images.unsplash.com/photo-1551288049-bebda4e38f71?auto=format&amp;fit=crop&amp;w=1400&amp;q=70" alt="" width="1400" height="700" loading="lazy">
            <div class="next-project-block__content">
                <h2 class="next-project-block__eyebrow" id="next-project-title">Next case study</h2>
                <p class="next-project-block__client">Lumen</p>
                <h3 class="next-project-block__title"><a class="next-project-block__link" href="#">Analytics that answer questions</a></h3>
                <p class="next-project-block__text">From 40 charts to six answers: a dashboard redesign built around the questions customers ask.</p>
            </div>
            <span class="next-project-block__arrow" aria-hidden="true"><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>
</span>
        </article>
    </div>
</section>

Next Project

On this page

The end of a case study: one large photo card that leads to the next project, so the reader keeps going instead of going back.

Technical Details

  • The block is labelled by its eyebrow ("Next case study", an h2); the project title is an h3 with the link.
  • The whole card is clickable with the a11y-card-link() mixin; keyboard focus outlines the card. The arrow is decorative.
  • The photo is a real img behind the text with a dark shade, so the white text stays readable on any image; the card redefines the heading and text color tokens.
  • The arrow mirrors and moves the other way in RTL; the hover motion runs only when the user doesn't prefer reduced motion.
  • Override the content with nextProjectBlock.

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.