What Is a Responsive Website? A Complete Developer Guide
A responsive website adapts layout, content, and media to different screen sizes and device capabilities. Learn the CSS patterns, viewport rules, testing steps, and common fixes.
A responsive website adapts its layout and content to the available viewport and device capabilities. The same site can remain readable and usable on a narrow phone, a tablet, and a large desktop display by using flexible layouts, scalable media, and conditional styles. Responsive design is an approach built with standard HTML and CSS; it is not a separate technology, and responsiveness alone does not prove that a site is accessible.
In practice, responsive pages avoid forcing users to zoom or scroll horizontally. Columns can stack, navigation can change arrangement, images can shrink within their containers, and spacing or typography can adjust when the available width changes.
How responsive design works
Most responsive sites combine three techniques:
- Flexible layout: Grid, Flexbox, percentages, relative units, and intrinsic sizing let components use the space available.
- Flexible media: Images, video, and other embedded content are constrained so they do not overflow their containers.
- Conditional rules: Media queries can change styles when viewport width, orientation, pointer type, color scheme, or other capabilities change.
These techniques are described in MDN’s responsive web design guide and web.dev’s responsive design basics. Media queries are useful, but a layout does not need a large collection of breakpoints to be responsive.
The viewport meta tag
Put this element in the <head> of every page intended to work on mobile browsers:
<meta name='viewport' content='width=device-width, initial-scale=1'>
It tells the browser to use the device’s actual CSS width instead of laying the page out against a wider virtual viewport and shrinking the result. Without it, a carefully written mobile layout can appear tiny or behave as if the device were much wider. See MDN’s explanation of the viewport tag.
A complete responsive example
The following file is runnable as-is. Save it as index.html and open it in a browser.
<!doctype html>
<html lang='en'>
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<title>Responsive card grid</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; font: 1rem/1.5 system-ui, sans-serif; color: #172033; background: #f5f7fb; }
.shell { width: min(100% - 2rem, 72rem); margin-inline: auto; }
.site-header { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding-block: 1rem; }
.nav { display: flex; flex-wrap: wrap; gap: .75rem 1rem; }
.hero { padding: clamp(2rem, 8vw, 6rem) 0 2rem; }
.hero h1 { max-width: 12ch; font-size: clamp(2rem, 7vw, 4.5rem); line-height: 1.05; margin: 0 0 1rem; }
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); gap: 1rem; padding-bottom: 3rem; }
.card { background: white; border: 1px solid #dce2ec; border-radius: .75rem; padding: 1.25rem; }
.card img { display: block; width: 100%; height: auto; border-radius: .5rem; }
@media (prefers-color-scheme: dark) {
body { color: #eef2ff; background: #111827; }
.card { background: #1f2937; border-color: #374151; }
}
</style>
</head>
<body>
<header class='site-header shell'>
<a href='/'>Example site</a>
<nav class='nav' aria-label='Primary'>
<a href='#features'>Features</a>
<a href='#pricing'>Pricing</a>
<a href='#contact'>Contact</a>
</nav>
</header>
<main>
<section class='hero shell'>
<p>Responsive by default</p>
<h1>Content that fits every screen</h1>
<p>The grid below grows and shrinks without a device-specific page.</p>
</section>
<section id='features' class='cards shell' aria-label='Features'>
<article class='card'><h2>Flexible width</h2><p>The shell uses a maximum width and side gutters.</p></article>
<article class='card'><h2>Fluid type</h2><p>The heading scales with clamp() while retaining limits.</p></article>
<article class='card'><h2>Automatic columns</h2><p>Cards wrap with auto-fit and a minimum usable width.</p></article>
</section>
</main>
</body>
</html>
Choosing layout rules and breakpoints
Start with the content, not a device list. Let text, controls, and cards determine when the layout needs to change. Use relative units such as %, rem, em, ch, vw, and grid fractions where they express the relationship you want.
Fluid layout patterns
width: min(100% - 2rem, 72rem)keeps a readable maximum while preserving gutters.grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr))allows cards to wrap without a breakpoint for every device.clamp(min, preferred, max)provides bounded fluid typography and spacing.flex-wrap: wraplets navigation and action groups move to another line when necessary.
Media queries
Use a media query when a component needs a different presentation. For example:
.toolbar { display: flex; gap: .75rem; align-items: center; }
@media (max-width: fortyrem) {
.toolbar { align-items: stretch; flex-direction: column; }
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
}
Replace fortyrem with a valid value such as 40rem; it is written out here only to keep the example readable in prose. Media queries can target width, height, orientation, resolution, pointer accuracy, hover support, color scheme, and more. The MDN media queries guide lists the available features.
Responsive images and embedded media
Prevent replaced elements from exceeding their containers:
img, picture, video, canvas, svg { max-width: 100%; height: auto; }
iframe { max-width: 100%; border: 0; }
Use srcset and sizes when different image widths are worth serving:
<img
src='hero-800.jpg'
srcset='hero-400.jpg 400w, hero-800.jpg 800w, hero-1600.jpg 1600w'
sizes='(max-width: 60rem) 100vw, 60rem'
width='1600'
height='900'
alt='A mountain trail at sunrise'>
Give images intrinsic width and height values to reserve space and reduce layout shifts. Use object-fit only when cropping is intentional.
Responsive versus fixed and adaptive layouts
| Approach | How it behaves | Typical risk |
|---|---|---|
| Fixed width | Uses one rigid size. | Horizontal scrolling on narrow screens and unused space on wide screens. |
| Adaptive | Switches among a small number of predefined layouts. | Widths between breakpoints can feel cramped or leave awkward gaps. |
| Responsive | Uses fluid sizing and component changes across a range of widths. | Requires careful constraints so lines do not become too long or controls too small. |
A responsive site can still make deliberate structural changes at breakpoints. It does not require a separate mobile site or identical markup at every width.
Responsive design and accessibility
Responsive behavior can help people who zoom pages or use different viewport sizes. W3C WAI recommends adapting display for zoom states and for phones and tablets in its accessibility tips. Responsive styling by itself does not establish accessibility conformance. Test keyboard access, focus visibility, headings, labels, color contrast, text resizing, and screen-reader output separately.
How to check whether a site is responsive
- Open the page at a narrow phone width, a tablet width, and a wide desktop width.
- Resize continuously between those widths; look for overflow, clipped content, and abrupt gaps.
- Test browser zoom at 200% and higher where practical.
- Check long headings, translated text, empty states, tables, forms, menus, and error messages.
- Inspect images, videos, maps, and third-party embeds.
- Use keyboard navigation and a screen reader; visual reflow is only one part of usability.
Quick browser checks
/* Paste into DevTools to reveal horizontal overflow sources */
* { outline: 1px solid rgba(255, 0, 0, .08); }
html, body { overflow-x: auto; }
/* Find elements wider than the viewport in the console */
[...document.querySelectorAll('*')].filter(el => el.getBoundingClientRect().right > document.documentElement.clientWidth);
Common responsive failures and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| Everything looks tiny on a phone | Missing or incorrect viewport meta tag. | Add width=device-width, initial-scale=1. |
| Horizontal scrollbar | Fixed width, long unbroken text, oversized image, or transformed element. | Use flexible sizing, constrain media, and allow safe wrapping or horizontal scrolling for data tables. |
| Cards become unreadably narrow | Columns shrink without a minimum width. | Use grid minmax() or stack the component at a content-driven breakpoint. |
| Navigation overlaps | Items cannot wrap or the breakpoint is based on a device model. | Allow wrapping, provide a menu button, or change the layout when the content no longer fits. |
| Images cause layout jumps | No intrinsic dimensions or reserved aspect ratio. | Set width/height or use aspect-ratio. |
| Text is cut off after zoom | Fixed heights or hidden overflow around text. | Use automatic heights, avoid clipping, and test reflow at high zoom. |
| Embedded content breaks the layout | Third-party iframe or widget has a fixed width. | Wrap it, constrain it, or provide a deliberate scroll region. |
Performance and reliability considerations
- Prefer CSS layout over JavaScript width detection; it avoids synchronization bugs and extra work.
- Use responsive image candidates so small screens do not download desktop-sized assets.
- Reserve media space to reduce cumulative layout movement.
- Keep breakpoints few and meaningful; every breakpoint adds combinations to review.
- Test slow networks and a cold load. A layout that works only after fonts, scripts, and widgets finish loading is fragile.
- Lazy-load below-the-fold images when appropriate, but do not lazy-load the primary content needed for the first view.
Or skip the browser setup
If you need screenshots of responsive states for documentation, visual regression checks, or previews, ScreenshotNeo captures a URL with one request. It can use device presets or any viewport, full-page capture, retina scale, dark mode, custom CSS and JavaScript, waits, cookies, headers, geolocation, and other capture options. See the ScreenshotNeo API documentation for parameter details.
Cookie and consent banners are accepted and 60+ known consent platforms, newsletter popups, and chat widgets are removed before the shot; each step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers report the page verdict and billing result.
cURL
curl -G 'https://api.screenshotneo.com/v1/shot' -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get('https://api.screenshotneo.com/v1/shot', params={'access_key': 'YOUR_API_KEY', 'url': 'https://stripe.com'}, timeout=90)
r.raise_for_status()
open('shot.webp', 'wb').write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
require('fs').writeFileSync('shot.webp', Buffer.from(await res.arrayBuffer()));
ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 screenshots. Create a free ScreenshotNeo account.
FAQ
Does responsive design require media queries?
No. Flexible Grid, Flexbox, intrinsic sizing, and relative units can produce responsive behavior without many media queries. Use queries when a component needs a different presentation.
Is a responsive website the same as a mobile website?
No. A responsive site usually uses one codebase and adapts across widths. A separate mobile site is a different delivery approach.
Does responsive mean accessible?
No. Responsive layouts can support zoom and reflow, but accessibility also depends on semantics, keyboard support, focus management, contrast, labels, and assistive technology testing.
What is the best breakpoint?
Choose breakpoints where your content stops fitting comfortably. There is no universal breakpoint list that matches every design.
Can a responsive page use different content on different devices?
It can, but hiding essential content solely by viewport can harm usability and accessibility. Prefer a layout that keeps the same core information available.


