Responsive Design Starts in the Markup
The viewport tag, flexible images, relative units and the mobile first habit. Half of responsive design is decided before a single media query is written.
- Concept
- The three foundations
- 1. The viewport meta tag
- 2. Flexible images
- 3. Relative units
- Mobile first
- Markup decisions that matter
- Responsive images
- Wide content needs a container
- Source order is mobile order
- Touch targets
- Form fields at sixteen pixels
- Testing properly
- Useful media queries beyond width
- Important rules
- Common mistakes
- Best practices
- Practice
-
HTML Basics
- What is HTML: The Structure Layer of Every Web Page
- HTML Document Structure: DOCTYPE, html, head and body
- Elements, Tags and Attributes: The Vocabulary of HTML
- HTML Comments: Notes That Ship With Your Code
- Block Level and Inline Elements
- Writing and Running Your First HTML Page
- How a Browser Turns Markup Into a Page
- Text and Formatting
- Links and Navigation
- Images and Media
- Lists
- Tables
-
Forms
- Form Structure: form, action and method
- Input Types: Text, Email, Number, Date and the Rest
- Labels: The Most Important Element in a Form
- Checkboxes, Radio Buttons and Grouping
- select, option, optgroup and datalist
- textarea, File Uploads and Hidden Fields
- Buttons: submit, reset and button
- Built In Form Validation
- GET or POST: What Happens When a Form Is Submitted
- Semantic HTML
- HTML5 Features
- Head and Metadata
- HTML with CSS
- HTML with JavaScript
- Accessibility
-
HTML SEO
- How Google Works: Crawling, Indexing and Ranking
- SEO Friendly HTML Structure
- Titles and Descriptions That Earn Clicks
- Headings and Content Structure for Search
- Internal Linking and Anchor Text
- robots.txt and XML Sitemaps
- Canonical URLs and Duplicate Content
- Structured Data and JSON-LD
- Image SEO
- Core Web Vitals and Mobile Friendliness
- DevTools and Debugging
- Editor Productivity
- HTML Best Practices
- HTML Projects
- Advanced Projects
- Practice and Exams
Concept
Responsive design means one document that adapts to any screen, rather than separate mobile and desktop sites. Most of the work is CSS, but several decisions live in the markup and no stylesheet can rescue them.
The three foundations
1. The viewport meta tag
<meta name="viewport" content="width=device-width, initial-scale=1">Without it a mobile browser pretends the screen is about nine hundred and eighty pixels wide and scales the whole page down. Every media query is then evaluated against that fiction and none of them fire. This one line is the difference between a responsive site and a shrunken desktop site.
2. Flexible images
img, video, svg, iframe {
max-width: 100%;
height: auto;
}Without max-width, a wide image forces the page wider than the screen and the whole document scrolls sideways. Without height: auto, the image is squashed rather than scaled.
The width and height attributes stay on the element regardless - they reserve the correct space and prevent layout shift while the file downloads.
3. Relative units
/* brittle */
.card { width: 400px; font-size: 14px; padding: 20px; }
/* adapts */
.card { max-width: 25rem; font-size: 1rem; padding: 1.25rem; }| Unit | Relative to | Good for |
|---|---|---|
rem | The root font size | Almost everything |
em | The element font size | Spacing that scales with its own text |
% | The parent | Widths within a container |
vw, vh | The viewport | Full screen sections |
ch | Character width | Line length |
px | Nothing | Borders and hairlines |
Setting font sizes in pixels overrides the browser font size a reader has deliberately chosen. Using rem respects it.
Mobile first
/* base: the narrowest screen, no media query */
.layout {
display: grid;
gap: 1.5rem;
}
/* then add complexity as space allows */
@media (min-width: 50rem) {
.layout { grid-template-columns: 2fr 1fr; }
}
@media (min-width: 70rem) {
.layout { gap: 2.5rem; }
}Writing the small screen styles first and adding with min-width queries produces simpler CSS than the reverse, because a narrow layout is usually a single column - the simplest case - and each query adds rather than undoes.
Choose breakpoints where the design starts to look wrong, not at device names. Device sizes change; the point at which your line length becomes uncomfortable does not.
Markup decisions that matter
Responsive images
<img src="/images/hall-800.jpg"
srcset="/images/hall-400.jpg 400w,
/images/hall-800.jpg 800w,
/images/hall-1600.jpg 1600w"
sizes="(max-width: 50rem) 100vw, 50vw"
alt="An empty lecture hall"
width="1600" height="900">Sending a 1600 pixel image to a 360 pixel phone wastes most of the download on a connection that can least afford it.
Wide content needs a container
<div class="table-scroll" tabindex="0" role="region" aria-label="Fee structure">
<table>...</table>
</div>Tables, code blocks and preformatted text do not reflow. Give each its own scroll container so the page body never scrolls sideways.
.table-scroll, pre { overflow-x: auto; }Source order is mobile order
On a narrow screen a multi column layout collapses into a single column in source order. So the markup order should already be the priority order, which is another reason to put the main content before the sidebar.
Touch targets
a, button, input, select, summary {
min-height: 44px;
min-width: 44px;
}Roughly forty four pixels square is the common guidance for a comfortable tap target. Links in body text are an exception - they inherit the line height - but standalone controls should meet it.
Form fields at sixteen pixels
input, select, textarea { font-size: 16px; }Below sixteen pixels, iOS zooms in when a field is focused and does not zoom back out. The correct fix is the font size, not disabling zoom.
Testing properly
- 320 pixels wide - the narrowest screen still in common use. If it works there it works nearly everywhere.
- Zoom to 200 percent - required by accessibility guidelines and a good test of relative units.
- A real device - a resized desktop window does not reproduce touch, keyboards, or the browser interface eating vertical space.
- Landscape on a phone - very short viewports break fixed height designs.
- A throttled connection - which is the real experience for a large share of readers.
Useful media queries beyond width
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
@media (prefers-color-scheme: dark) { }
@media (prefers-contrast: more) { }
@media (hover: none) { } /* touch device */
@media (pointer: coarse) { } /* finger sized pointer */
@media print { }The reduced motion query is the one to add first. It costs three lines and it matters a great deal to readers who experience motion sickness.
Important rules
- No viewport tag means no responsive behaviour, whatever the CSS says.
- Never disable zoom.
- Images need
max-width: 100%andheight: autoin CSS, pluswidthandheightattributes in the markup. - Source order is the order a narrow screen shows.
- Breakpoints belong to the design, not to device names.
- Tables and code blocks need their own scroll containers.
Common mistakes
- Omitting the viewport tag.
- Fixed pixel widths that overflow narrow screens.
- Font sizes in pixels, ignoring the reader browser setting.
- Testing only by resizing a desktop window.
- Tap targets too small or too close together.
- Sending desktop sized images to phones.
- Disabling zoom to work around the iOS form field zoom.
Best practices
- Viewport tag on every page.
- Mobile first CSS with
min-widthqueries. remfor type and spacing,pxonly for hairlines.- Responsive images with
srcsetandsizes. - Scroll containers for anything that cannot reflow.
- Honour
prefers-reduced-motionandprefers-color-scheme. - Test at 320 pixels and at 200 percent zoom before shipping.
Practice
- Remove the viewport tag from a responsive page, open it on a phone, and describe what happens to the media queries.
- Set a container to 800 pixels wide and view it at 320 pixels. Fix it with
max-width. - Convert a stylesheet from pixel font sizes to
rem, then change the browser default size and observe. - Add a reduced motion query and confirm animations stop when the system setting is on.