Skip to main content

Step-by-step tutorial

CSS Tutorial: Build a Responsive Profile Card

Style semantic profile markup into a resilient component that adapts to available space, preserves keyboard focus, and avoids fragile fixed dimensions.

CSSbeginner4 min readWeb foundations

Learning overview

Estimated time
4 minutes
Difficulty
Beginner
Prerequisites
No prior experience required
Learning outcome
Explain css using a clear mental model · Apply css in practical CSS work
Last updated
July 18, 2026

What you will build and learn

The finished component uses a small design-token layer, predictable box sizing, Grid for structure, flexible media, readable typography, and a content-driven breakpoint. Keep the supplied HTML unchanged so every visual decision remains in CSS.

  • Organize reusable values with custom properties
  • Control sizing with the box model
  • Create a responsive Grid layout
  • Design visible hover and keyboard-focus states

Step 1: Establish global foundations

Border-box sizing makes declared dimensions include padding and borders. Custom properties name repeated design decisions and provide one place to adjust color, spacing, radius, and shadow.

foundation.css
:root {
  --color-ink: #172033;
  --color-muted: #536079;
  --color-accent: #4f46e5;
  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --radius: 1rem;
}

*, *::before, *::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  color: var(--color-ink);
  font: 1rem/1.6 system-ui, sans-serif;
  background: #f5f7fb;
}

Step 2: Build the card box

A maximum width protects readability on large screens while width: 100% allows the card to fit narrow containers. Margin auto centers it without removing it from normal flow.

card.css
.profile-card {
  width: min(100% - 2rem, 48rem);
  margin-inline: auto;
  padding: var(--space-3);
  border: 1px solid #d8deea;
  border-radius: var(--radius);
  background: white;
  box-shadow: 0 1rem 2.5rem rgb(23 32 51 / 10%);
}

Step 3: Create the responsive Grid

The narrow layout starts as one column. At the point where the image and text have enough room to sit together, a min-width query introduces two tracks. The breakpoint follows content pressure rather than a named device.

layout.css
.profile-card {
  display: grid;
  gap: var(--space-3);
}

.profile-card__image {
  display: block;
  width: 100%;
  height: auto;
  border-radius: calc(var(--radius) * 0.75);
}

@media (min-width: 42rem) {
  .profile-card {
    grid-template-columns: minmax(12rem, 2fr) 3fr;
    align-items: center;
  }
}

Step 4: Create hierarchy with type and spacing

Use a limited type scale and logical properties so the component remains clear across writing directions. Clamp lets the heading grow fluidly within safe limits.

typography.css
.profile-card__title {
  margin-block: 0 var(--space-1);
  font-size: clamp(1.5rem, 1.2rem + 1.5vw, 2.5rem);
  line-height: 1.15;
}

.profile-card__role {
  margin-block: 0 var(--space-2);
  color: var(--color-muted);
}

.profile-card__skills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  padding: 0;
  list-style: none;
}

Step 5: Style interaction without hiding focus

Hover is not available to every user, so focus-visible needs an equally clear treatment. Outline does not change layout and remains distinguishable from the button’s filled background.

interaction.css
.profile-card__link {
  display: inline-block;
  padding: 0.75rem 1rem;
  border-radius: 0.65rem;
  color: white;
  background: var(--color-accent);
  text-decoration: none;
}

.profile-card__link:hover {
  background: #3730a3;
}

.profile-card__link:focus-visible {
  outline: 0.2rem solid #f59e0b;
  outline-offset: 0.2rem;
}

Step 6: Test the component under pressure

Resize gradually rather than checking only common phone and desktop widths. Zoom to 200 percent, replace the name with a long value, test keyboard focus, emulate reduced motion, and inspect winning declarations in developer tools.

  • No horizontal overflow at 320 CSS pixels
  • Long text wraps without covering other content
  • Image space remains stable while loading
  • Focus is visible against every background
  • The layout works before and after the breakpoint

Frequently asked questions

Why use Grid for this CSS tutorial?

The wide component has explicit image and content columns. Grid describes that two-dimensional relationship directly while the narrow version naturally remains one column.

Why avoid a fixed card height?

Text can grow through translation, user settings, or dynamic content. A fixed height often creates clipping or overlap; content-driven height remains resilient.

How should I choose the breakpoint?

Increase the viewport until the content has enough room for the intended columns. Choose the breakpoint from that layout transition, not from a device label.

Topic graph

A taxonomy-generated path through this subject.

  1. CSS
  2. Web foundations
  3. css
  4. tutorial
  5. responsive-design
  6. accessibility
  7. What Is CSS in Programming?
  8. Learn CSS: From Selectors to Responsive Interfaces
  9. HTML Tutorial: Build a Complete Semantic Web Page

Recommended automatically from shared technologies, topics, intent, and difficulty.

Hand-picked companion pages that deepen this topic.

Your next steps

Continue learning

  1. 1glossaryWhat Is CSS in Programming?
  2. 2guidesLearn CSS: From Selectors to Responsive Interfaces
  3. 3guidesHTML Tutorial: Build a Complete Semantic Web Page
  4. 4guidesLearn HTML: From First Page to Semantic Websites