The viewport meta tag
Without this tag, phones render the page at about 980px wide and shrink it to fit. Text becomes tiny.
<meta name="viewport" content="width=device-width, initial-scale=1.0">
This line is in every module's <head>. With it, width equals the device width. Without it, mobile looks zoomed out.
Units: %, em/rem, vh/vw
| Unit | Relative to… | Use |
|---|---|---|
% | parent | Fluid widths |
em | own / parent font-size | Spacing that scales with text |
rem | root (html) font-size | Consistent sizing |
vh / vw | viewport height/width | Hero sections, full-screen |
width: 50%half of parent
width: 50vwhalf of viewport
font-size: 1.2rembigger than root
height: 40vhhtml { font-size: 16px; } /* 1rem = 16px */
h1 { font-size: 2rem; } /* 32px */
.card { padding: 1rem; width: 90%; max-width: 600px; }
.hero { height: 60vh; } /* 60% of viewport height */
Media queries: mobile first
Write base styles for mobile, then add width with min-width. Use max-width only when you need to override desktop styles.
/* base: mobile (single column) */
.cards { display: grid; gap: 12px; }
/* tablet+ : 2 columns */
@media (min-width: 600px) {
.cards { grid-template-columns: repeat(2, 1fr); }
}
/* desktop : 3 columns */
@media (min-width: 900px) {
.cards { grid-template-columns: repeat(3, 1fr); }
}
Resize window to see cards reflow. flex-wrap and grid auto-fit do this without queries.
flex-wrap: wrap and grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)) make grids responsive without media queries. Save queries for bigger layout shifts like stacking a header.max-width containers and auto-fit
max-width: 480px; margin: 0 auto;Caps width, centers, but shrinks on mobile
/* container pattern */
.container { max-width: 720px; margin: 0 auto; padding: 0 16px; }
/* grid that is responsive for free */
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; }
/* auto-fit: as many 200px columns as fit; auto-fill is similar but keeps empty tracks */
Fluid type with clamp()
One line that scales font smoothly between mobile and desktop with no media queries.
I am clamp(18px, 4vw, 32px). Resize window to see me scale
Never smaller than 18px, never larger than 32px. Prefers 4vw in between.
h1 { font-size: clamp(1.5rem, 4vw, 2.5rem); }
p { font-size: clamp(0.95rem, 2vw, 1.05rem); }
Live demo: one media query to stack header
Shrink window below 500px and the header stacks vertically. That is the media query.
header { display: flex; justify-content: space-between; }
@media (max-width: 500px) {
header { flex-direction: column; }
}
- Add
<meta name="viewport">if missing. - Wrap content in
.container { max-width: 720px; margin: 0 auto; padding: 0 16px; } - Add one media query that stacks nav or grid on small screens.
- Try
clamp()on one heading. Resize and watch it scale. - Test with DevTools device toolbar (phone and tablet).