Next-Gen App & Browser Testing Cloud
Trusted by 2 Mn+ QAs & Devs to accelerate their release cycles

To make your CSS responsive, add the viewport meta tag to your HTML, replace fixed pixel sizes with relative units (%, em, rem, vw, vh), build fluid layouts with Flexbox and CSS Grid, and add mobile-first media queries that adjust the layout at sensible breakpoints. Round it off by making images and typography fluid, avoiding fixed widths, and testing the result across real screen sizes. The steps below walk through each technique with copy-paste examples.
This is the one step you cannot skip. The viewport meta tag tells mobile browsers to render the page at the device's real width instead of a fixed virtual width of around 980px. Without it, a phone shows a zoomed-out desktop layout and your media queries never trigger correctly. Add this line inside the <head> of every page:
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>width=device-width sets the layout width to the device's width, and initial-scale=1.0 sets the starting zoom level to 100%. Everything else in this guide depends on this tag being present.
Hard-coded pixel widths are the most common reason a layout breaks on small screens. Switch to relative units for anything that should scale. Each unit is measured against a different reference, so picking the right one matters:
| Unit | Relative to | Typical use |
|---|---|---|
| % | The containing block | Widths and fluid columns |
| rem | The root font size (default 16px) | Spacing and consistent type scale |
| em | The element's own / parent font size | Padding that scales with text |
| vw / vh | 1% of viewport width / height | Full-screen sections and fluid sizing |
/* Avoid: locked to one screen size */
.card { width: 600px; padding: 24px; font-size: 16px; }
/* Prefer: scales with screen and font settings */
.card { width: 80%; padding: 1.5rem; font-size: 1rem; }
.hero { height: 60vh; }Keep px only for things that genuinely should not scale, such as a 1px hairline border.
Modern layout methods are responsive by default. Flexbox arranges items in one dimension and wraps them when space runs out, while CSS Grid handles two-dimensional layouts. The repeat(auto-fit, minmax()) pattern lets a grid reflow from several columns down to one with no media query at all:
/* Flexbox: a navbar that wraps on narrow screens */
.nav {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
/* Grid: a gallery that reflows on its own */
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 1rem;
}Each card in the gallery is at least 220px wide and shares the remaining space equally (1fr). As the screen shrinks, columns drop one by one until a single column remains, all without writing a breakpoint.
When the layout itself needs to change, not just resize, reach for media queries. The mobile-first approach writes the base styles for small screens, then layers enhancements for wider screens using min-width. Set your breakpoints where the content starts to look cramped rather than at named device widths:
/* Base: single column for phones */
.layout {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
/* Tablet and up: content + sidebar */
@media (min-width: 768px) {
.layout { grid-template-columns: 2fr 1fr; }
}
/* Desktop and up: three columns */
@media (min-width: 1200px) {
.layout { grid-template-columns: 1fr 2fr 1fr; }
}For the full syntax of the @media rule, see What Is a Media Query CSS?, and for how to pick and override breakpoints, see How Do You Change the Breakpoint in CSS?.
A fixed-size image is a frequent cause of horizontal scrollbars on mobile. The one-line fix is to cap every image at the width of its container while preserving its aspect ratio:
img {
max-width: 100%;
height: auto;
}
/* Crop a banner to a fixed box without distortion */
.banner {
width: 100%;
height: 240px;
object-fit: cover;
}To serve a smaller file to small screens, use srcset for resolution switching, or the <picture> element for art direction (a different crop per screen size):
<!-- Resolution switching: browser picks the best file -->
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1600.jpg 1600w"
sizes="(max-width: 600px) 100vw, 50vw"
alt="Responsive photo">
<!-- Art direction: a different image per screen size -->
<picture>
<source media="(min-width: 800px)" srcset="hero-wide.jpg">
<img src="hero-tall.jpg" alt="Responsive hero">
</picture>Rather than overriding font sizes at every breakpoint, let type scale smoothly with the clamp() function. It takes a minimum, a preferred value, and a maximum. Mixing rem with vw inside clamp keeps text fluid while still honouring browser zoom, which a raw vw value would break:
h1 {
/* never smaller than 1.75rem, never larger than 3rem */
font-size: clamp(1.75rem, 1rem + 3vw, 3rem);
}
p {
font-size: clamp(1rem, 0.9rem + 0.4vw, 1.125rem);
line-height: 1.6;
}A container with a hard width cannot shrink below that value and will overflow narrow screens. Instead, let the container fill the available space but cap it, so it stays readable on large monitors and still fits on a phone:
/* Up to 1200px wide, but never wider than 92% of the screen */
.container {
width: min(92%, 1200px);
margin-inline: auto;
}The min() function picks whichever value is smaller at any given moment, giving you a fluid width and a sensible maximum in a single line.
Writing responsive CSS is only half the job; you have to confirm it holds up on real screens. Resizing your browser or using DevTools device mode is a good first pass, but browser engines interpret breakpoints, viewport units, and fonts in subtly different ways, so a layout that looks right in one engine can break in another. The reliable check is to view your page at many viewport sizes across real browsers and devices. You can preview your layout side by side at multiple device widths with the TestMu AI (Formerly LambdaTest) Responsive Testing Tool, all without any local setup.
Media queries respond to the size of the whole viewport. Container queries let a component respond to the size of its own container instead, so the same card can look different in a narrow sidebar versus a wide main column. This is ideal for reusable components in design systems:
/* Mark an element as a query container */
.card-wrapper {
container-type: inline-size;
}
/* Style the card based on the wrapper's width, not the viewport */
@container (min-width: 400px) {
.card {
display: flex;
gap: 1rem;
}
}Add the viewport meta tag to the <head> of your HTML: <meta name="viewport" content="width=device-width, initial-scale=1.0">. Without it, mobile browsers render the page at a fixed virtual width and your media queries will not apply correctly.
Use relative units (%, em, rem, vw, vh) for anything that should scale with the screen or the user's font size. Reserve px for things that should stay fixed, such as a 1px border. rem is measured from the root font size, em from the parent, % from the containing block, and vw/vh from the viewport.
Often not for simple reflows. Flexbox and CSS Grid are responsive by default, and a grid using repeat(auto-fit, minmax()) reflows columns with no media query at all. You still add media queries when the layout itself needs to change, for example switching from a single column to a sidebar layout on wider screens.
Mobile-first means you write your base styles for small screens first, then progressively layer on enhancements for larger screens using min-width media queries. It keeps the default CSS lightweight and is generally easier to maintain than starting from desktop and overriding downward.
Use the clamp() function, for example font-size: clamp(1.75rem, 1rem + 3vw, 3rem). It sets a minimum size, a preferred size that grows with the viewport, and a maximum cap. Mixing rem with vw inside clamp keeps the text responsive while still respecting browser zoom, unlike a raw vw value.
Resizing the browser or using DevTools device mode is a useful first pass, but engines interpret breakpoints, viewport units, and fonts slightly differently. The reliable check is to view the page at many viewport sizes across real browsers and devices, which is what a cloud responsive testing tool provides without local setup.
KaneAI - Testing Assistant
World’s first AI-Native E2E testing agent.

TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance