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.
: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.
.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.
.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.
.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.
.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.
Related courses
Related learning
Recommended automatically from shared technologies, topics, intent, and difficulty.
Related Guides
Related Tutorials
Related Glossary
Related Cheatsheets
Related Projects
Related Interview Questions
Related reading
Hand-picked companion pages that deepen this topic.
Your next steps
