Profile

Ava Martinez

Product Designer · Lisbon

Designing calm interfaces for busy people. Writing about design systems and accessible color.

Posts
142
Followers
8.4k
Following
312
Message
@use 'sprucecss/scss/spruce' as *;

.profile-card {
  background-color: color('surface');
  border: config('border-width-base', $display) solid color('border');
  border-radius: radius('lg');
  overflow: hidden;
  text-align: center;

  &__cover {
    background-image: linear-gradient(135deg, #{color('primary')}, #{color('secondary')});
    block-size: 6rem;
  }

  &__avatar {
    block-size: 6rem;
    border: 4px solid color('surface');
    border-radius: 50%;
    inline-size: 6rem;
    margin-block-start: -3rem;
    margin-inline: auto;
    object-fit: cover;
    position: relative;
  }

  &__body {
    padding: spacer('s') spacer-clamp('m', 'l') spacer-clamp('m', 'l');
    @include layout-stack('xs');
  }

  &__name {
    font-size: font-size('h4');
  }

  &__role {
    color: color('muted');
    font-size: config('font-size-sm', $typography);
  }

  &__stats {
    border-block: config('border-width-base', $display) solid color('border');
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    margin-block-start: spacer('m') !important;
    padding-block: spacer('s');

    div {
      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-size: font-size('h4');
      font-weight: 700;
      margin: 0;
    }
  }

  &__actions {
    display: flex;
    gap: spacer('xs');
    justify-content: center;
    padding-block-start: spacer('xs');
  }
}
<article class="profile-card">
    <div class="profile-card__cover" aria-hidden="true"></div>
    <img class="profile-card__avatar" src="https://images.unsplash.com/photo-1438761681033-6461ffad8d80?auto=format&fit=crop&w=192&h=192&q=70" alt="" width="96" height="96">
    <div class="profile-card__body">
        <h3 class="profile-card__name">Ava Martinez</h3>
        <p class="profile-card__role">Product Designer · Lisbon</p>
        <p class="profile-card__bio">Designing calm interfaces for busy people. Writing about design systems and accessible color.</p>
        <dl class="profile-card__stats">
                <div><dt>Posts</dt><dd>142</dd></div>
                <div><dt>Followers</dt><dd>8.4k</dd></div>
                <div><dt>Following</dt><dd>312</dd></div>
        </dl>
        <div class="profile-card__actions">
            <button class="btn btn--primary btn--sm" type="button" aria-pressed="false" data-follow-button>Follow</button>
            <a class="btn btn--outline-primary btn--sm" href="#">Message</a>
        </div>
    </div>
</article>
(() => {
  document.querySelectorAll('[data-follow-button]').forEach((button) => {
    button.addEventListener('click', () => {
      const isFollowing = button.getAttribute('aria-pressed') === 'true';

      button.setAttribute('aria-pressed', String(!isFollowing));
      button.textContent = isFollowing ? 'Follow' : 'Following';
      button.classList.toggle('btn--primary', isFollowing);
      button.classList.toggle('btn--soft-primary', !isFollowing);
    });
  });
})();

Profile

On this page

A profile (user) card with a cover, an avatar, a short bio, statistics and actions.

Technical Details

  • The statistics are a description list (dl); flex-direction: column-reverse shows the number above its label while the DOM order stays "label, value" for screen readers.
  • The Follow button is a toggle button (aria-pressed); the script flips its state and label.
  • The cover gradient mixes the primary and secondary colors, so it follows every style.

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.