Author

Daniel Okafor smiling in front of a bright wall.

Your teacher

Hi, I’m Daniel Okafor

Frontend architect · Author · Speaker

I’ve spent ten years building CSS architectures for products used by millions, from a banking app to the design system of a large e-commerce platform.

I wrote this book because I kept explaining the same ideas to new teammates. The videos are those explanations, recorded with the code on the screen.

years of CSS architecture
10
newsletter readers
40k
conference talks
25
@use 'sprucecss/scss/spruce' as *;

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

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

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

  &__media {
    margin: 0;
    position: relative;

    // A brand-colored frame offset behind the photo.
    &::before {
      background-color: color-alpha('primary', 0.16);
      border-radius: radius('lg');
      content: '';
      inset: spacer('m') spacer('m') calc(#{spacer('m')} * -1) calc(#{spacer('m')} * -1);
      position: absolute;
    }

    img {
      aspect-ratio: 9 / 11;
      border-radius: radius('lg');
      box-shadow: shadow('lg');
      inline-size: 100%;
      object-fit: cover;
      position: relative;
    }
  }

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

  &__heading {
    @include layout-stack('xxs'); // eyebrow, name, role
  }

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

  &__title {
    font-size: responsive-font-size(2.75rem, 35, '3vw + 1rem');
  }

  &__role {
    color: color('muted');
    font-weight: 600;
  }

  &__bio {
    font-size: config('font-size-lead', $typography);
    @include layout-stack('s');
  }

  &__stats {
    border-block: config('border-width-base', $display) solid color('border');
    display: grid;
    gap: spacer('s');
    grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr));
    padding-block: spacer('m');
  }

  &__stat {
    display: flex;
    flex-direction: column-reverse;

    dt {
      color: color('muted');
      font-size: config('font-size-sm', $typography);
      font-weight: 400;
    }

    dd {
      color: color('heading');
      font-family: config('font-family-heading', $typography);
      font-size: font-size('h2');
      font-weight: config('font-weight-heading', $typography);
      line-height: 1.1;
      margin: 0;
    }
  }

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

    a {
      font-weight: 700;
    }

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

// The frame sits on the other side in RTL.
[dir='rtl'] .author-block__media::before {
  inset: spacer('m') calc(#{spacer('m')} * -1) calc(#{spacer('m')} * -1) spacer('m');
}
<section class="author-block" aria-labelledby="author-title">
    <div class="container">
        <div class="author-block__inner">
            <figure class="author-block__media">
                <img src="https://images.unsplash.com/photo-1500648767791-00dcc994a43e?auto=format&amp;fit=crop&amp;w=720&amp;h=880&amp;q=70" alt="Daniel Okafor smiling in front of a bright wall." loading="lazy" width="720" height="880">
            </figure>
            <div class="author-block__content">
                <div class="author-block__heading">
                    <p class="author-block__eyebrow">Your teacher</p>
                    <h2 class="author-block__title" id="author-title">Hi, I’m Daniel Okafor</h2>
                    <p class="author-block__role">Frontend architect · Author · Speaker</p>
                </div>
                <div class="author-block__bio">
                    <p>I’ve spent ten years building CSS architectures for products used by millions, from a banking app to the design system of a large e-commerce platform.</p>
                    <p>I wrote this book because I kept explaining the same ideas to new teammates. The videos are those explanations, recorded with the code on the screen.</p>
                </div>
                <dl class="author-block__stats">
                    <div class="author-block__stat">
                        <dt>years of CSS architecture</dt>
                        <dd>10</dd>
                    </div>
                    <div class="author-block__stat">
                        <dt>newsletter readers</dt>
                        <dd>40k</dd>
                    </div>
                    <div class="author-block__stat">
                        <dt>conference talks</dt>
                        <dd>25</dd>
                    </div>
                </dl>
                <ul class="author-block__links" role="list" aria-label="Find Daniel online">
                    <li><a href="#">Newsletter</a></li>
                    <li><a href="#">GitHub</a></li>
                    <li><a href="#">Mastodon</a></li>
                </ul>
            </div>
        </div>
    </div>
</section>

Author

On this page

Introduce the person behind a book, a course or a product: a photo, a personal introduction, the credentials in numbers and where to follow them.

Technical Details

  • The block is labelled by its h2 (the greeting with the name); the eyebrow and the role around it are a stacked text group.
  • The credentials are a description list shown value first (column-reverse), so they're read in a natural order.
  • The photo has a meaningful alt; the offset frame behind it is a decorative pseudo-element that mirrors in RTL.
  • Keep the bio personal and short: why you made it, and why the reader should trust you.
  • Override the content with authorBlock.

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.