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
profile-card/
├── index.html
├── css/
│ └── styles.css
└── images/
└── avatar.jpgKeep structure simple and easy to extend.
Step 1: HTML Structure
Create index.html:
Structure explanation:
- semantic
articlefor 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-boxmakes 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-fitfor consistent shape min-width: 0prevents 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:
@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)
/* 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
| Mistake | Why it hurts | Better approach |
|---|---|---|
| Fixed card width only | Breaks on mobile | Use width: min(..., 100%) |
| Missing avatar constraints | Distorted image | Use aspect-ratio + object-fit |
| No focus styles on actions | Keyboard UX failure | Add :focus-visible styles |
| Hardcoded random spacing | Inconsistent rhythm | Use spacing tokens |
| Overly complex class names | Hard maintenance | Use consistent component-part naming |
Stretch Goals
Try these enhancements:
- Add dark mode tokens and theme switch attribute
- Add social icon row with accessible labels
- Add status badge (
Available for work) - Add hover animation to card (
translateY) with reduced-motion fallback - Build a 3-card team grid using this component
FAQ
Should profile card actions be links or buttons?
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.