Project: Profile Card

Introduction

This project combines core CSS skills into one practical component: a responsive profile card. You will use spacing tokens, typography hierarchy, media handling, interaction states, and accessible links/buttons. By the end, you will have a reusable card pattern for portfolio pages, team lists, and author blocks.

Prerequisites

  • Basic HTML and CSS setup
  • Familiarity with box model, Flexbox, and responsive basics
  • Understanding of hover/focus-visible states

Project Goal

Build a profile card with:

  • avatar image
  • name and role
  • short bio
  • skill tags
  • social/action links

Quality goals:

  • clean visual hierarchy
  • responsive behavior
  • accessible interaction states
  • reusable class naming

Folder Setup

text
profile-card/
├── index.html
├── css/
│   └── styles.css
└── images/
    └── avatar.jpg

Keep structure simple and easy to extend.

Step 1: HTML Structure

Create index.html:

Structure explanation:

  • semantic article for a standalone profile block
  • clear component-part class names for maintainability
  • avatar has meaningful alt
  • actions are links here because they represent navigation-style behavior

Step 2: Base Styles and Tokens

Create css/styles.css:

Code explanation:

  • tokens keep visual language consistent
  • global border-box makes sizing predictable
  • centered page layout keeps project preview clean

Step 3: Card Layout

Add:

Code explanation:

  • mobile-first card starts as vertical stack
  • avatar uses aspect-ratio + object-fit for consistent shape
  • min-width: 0 prevents overflow issues in flexible contexts

Step 4: Typography and Content Styling

Add:

This creates clear hierarchy: identity first, supporting description second.

Step 5: Tags and Actions

Add:

This provides clear action affordance and keyboard-visible focus treatment.

Step 6: Responsive Enhancement

Add:

css
@media (min-width: 640px) {
  .profile-card {
    grid-template-columns: 160px 1fr;
    align-items: center;
  }
 
  .profile-card__avatar {
    margin-inline: auto;
  }
}

Code explanation:

  • narrow screen: stacked layout
  • wider screen: avatar + content side-by-side
  • same markup adapts cleanly across sizes

Final Full CSS (Reference)

css
/* Combine all snippets from steps above into one styles.css file */

Reference note:

  • keep the file organized in sections (tokens, layout, component parts, responsive)
  • avoid random rule scattering

Accessibility and Quality Checklist

  • Avatar has meaningful alt
  • Buttons/links have visible focus ring
  • Text contrast is readable
  • Tap targets are comfortable (min-height: 44px)
  • Layout works on narrow mobile widths
  • No horizontal overflow

Common Mistakes

MistakeWhy it hurtsBetter approach
Fixed card width onlyBreaks on mobileUse width: min(..., 100%)
Missing avatar constraintsDistorted imageUse aspect-ratio + object-fit
No focus styles on actionsKeyboard UX failureAdd :focus-visible styles
Hardcoded random spacingInconsistent rhythmUse spacing tokens
Overly complex class namesHard maintenanceUse consistent component-part naming

Stretch Goals

Try these enhancements:

  1. Add dark mode tokens and theme switch attribute
  2. Add social icon row with accessible labels
  3. Add status badge (Available for work)
  4. Add hover animation to card (translateY) with reduced-motion fallback
  5. Build a 3-card team grid using this component

FAQ

If they navigate to other pages, use links. If they trigger in-page actions (open modal, follow toggle), use buttons.

Why use aspect-ratio for avatar?

It reserves consistent shape and prevents layout shifts before image load.

Is one card enough as a real project?

Yes. If built cleanly and made reusable, it is a strong component-level project.

How do I make card content equal height in a grid?

Wrap cards in a Grid/Flex parent and make cards stretch (align-stretch) with consistent internal structure.

Can I reuse this card in frameworks later?

Absolutely. The HTML/CSS structure maps well into React/Vue/Svelte component patterns.