Free Online Code Editor
Build pages that work on phones, tablets, and desktops. Covers the viewport tag, clamp(), mobile-first media queries, flexible images, and testing.
More than half of web visits happen on phones. If your page only looks right on a wide monitor, it's broken for most people.
Responsive design means one page that adapts to any screen. It doesn't require a framework. It takes a handful of habits, and this guide covers them in the order you'd use them.
Without this line in your <head>, phones pretend to be a wide desktop screen and shrink your page down to fit.
<meta name="viewport" content="width=device-width, initial-scale=1">Add it to every page. Nothing else on this list works properly without it.
"Mobile-first" means writing your base CSS for phones, then adding rules for bigger screens. It forces you to decide what matters most, and it keeps your CSS simpler, since small screens get the plain single-column layout without extra overrides.
The tool for adding rules is min-width media queries:
<style>
body { font-family: sans-serif; margin: 0; padding: 16px; }
.cards { display: grid; gap: 12px; } /* phone: one column */
.card { padding: 20px; background: #f0fdf4; border: 1px solid #86efac; border-radius: 8px; }
@media (min-width: 600px) {
.cards { grid-template-columns: repeat(2, 1fr); } /* tablet */
}
@media (min-width: 960px) {
.cards { grid-template-columns: repeat(4, 1fr); } /* desktop */
}
</style>
<div class="cards">
<div class="card">One</div>
<div class="card">Two</div>
<div class="card">Three</div>
<div class="card">Four</div>
</div>Drag the editor's preview wider and narrower and watch the columns change. Notice that you didn't write any rules for phones. That's the whole idea.
Don't pick breakpoints by device names, since new devices keep appearing. Instead, start narrow, stretch the window, and add a breakpoint at the point where your layout starts to look bad. Common starting points are around 600px, 900px, and 1200px, but your content decides.
Fixed pixel sizes either look huge on a phone or tiny on a monitor. clamp(min, preferred, max) gives you a size that grows with the screen but stops at sensible limits.
<style>
body { font-family: sans-serif; margin: 0; padding: 16px; }
h1 {
font-size: clamp(1.6rem, 4vw + 1rem, 3rem);
margin: 0 0 8px;
}
.wrap {
width: min(100% - 32px, 720px);
margin-inline: auto;
}
</style>
<div class="wrap">
<h1>This heading scales smoothly</h1>
<p>The container is as wide as the screen, up to 720px, and stays centered.</p>
</div>min(100% - 32px, 720px) is a one-line replacement for the old "max-width plus padding" pattern. No media query is needed for either of these.
Images have a fixed size by default and will overflow small screens. This small reset fixes it:
img, video {
max-width: 100%;
height: auto;
display: block;
}For large photos, use srcset so phones download a smaller file:
<img src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1600.jpg 1600w"
sizes="(min-width: 960px) 50vw, 100vw"
alt="A mountain lake at sunrise"
width="800" height="533" loading="lazy">Always include width and height so the browser reserves the space before the image loads. That stops the page from jumping around. loading="lazy" delays offscreen images until the user scrolls near them.
Often, you can skip media queries completely. A Grid with auto-fit or auto-fill rearranges itself:
<style>
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 12px;
font-family: sans-serif;
}
.grid div { background: #dcfce7; padding: 24px; border-radius: 8px; text-align: center; }
</style>
<div class="grid">
<div>A</div><div>B</div><div>C</div><div>D</div><div>E</div>
</div>Flexbox with flex-wrap: wrap does something similar for rows of items. Reach for media queries when the layout changes in structure, such as moving a sidebar below the content.
Fingers are bigger than mouse pointers. Make buttons and links at least about 44 by 44 pixels, with some space between them. Don't rely on hover for anything essential, since touch screens don't have it. Text should be at least 16px, or iOS zooms in when someone taps a form field.
Media queries look at the screen. Container queries look at the box a component sits in, so one card can adapt whether it's in a wide main area or a narrow sidebar. All current major browsers support them.
<style>
.slot { container-type: inline-size; border: 1px dashed #999; padding: 8px; resize: horizontal; overflow: auto; width: 420px; }
.product { display: grid; gap: 8px; font-family: sans-serif; }
.thumb { background: #bbf7d0; height: 60px; border-radius: 6px; }
@container (min-width: 360px) {
.product { grid-template-columns: 100px 1fr; }
}
</style>
<div class="slot">
<div class="product">
<div class="thumb"></div>
<div><strong>Trail shoes</strong><br>Light and grippy.</div>
</div>
</div>Drag the bottom-right corner of the dashed box to resize it. The layout switches based on the box's width, not the browser window.
min-width media queries.clamp(), min(), and auto-fit grids so layouts flex without extra rules.width and height.Reading helps, but typing the code is what makes it stick. Open the editor, paste any example from this article, and change it until it breaks.
Open the HTML/CSS editorStop guessing between Flexbox and CSS Grid. Learn the one question that decides it, with copy-and-run layouts for navbars, card galleries, and page templates.
Validate forms with plain HTML attributes, style valid and invalid states with CSS, and use the Constraint Validation API for custom messages.
Learn when to use CSS transitions and when to use keyframe animations, which properties stay smooth, and how to respect users who prefer reduced motion.