The HTML Viewport Meta Tag
Imagine opening a website on your phone, and seeing a tiny copy of the desktop page: text too small to read, and you have to pinch and drag to find anything. That experience is common on pages without the viewport tag, and it is the reason this one line of HTML exists.
<meta name="viewport" content="width=device-width, initial-scale=1">
In this lesson you will learn what it means, why zooming must always stay on, and how it works together with your CSS.
What You Will Learnβ
- What a viewport is, and why phones are different
- What
width=device-widthandinitial-scale=1do - Why
user-scalable=noandmaximum-scale=1are harmful - Safe areas and
viewport-fit=coverfor notched phones - How the tag works with media queries and flexible CSS
- Testing on real and simulated devices
The Big Ideaβ
- HTML Code
- Mobile Simulator
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Mobile-friendly page</title>
</head>
<body>
<h1>The Bread Bin</h1>
</body>
</html>
<meta name="viewport" content="width=device-width, initial-scale=1">- The browser lays the page out at 360px wide, then fits it on a 360px screen without shrinking.
- The mobile layout is used, because the page is narrower than 600px.
This is a simulation. The page inside the frame is real, but the shrinking is done with a CSS scale, to imitate what a phone does. The 980px default is typical for mobile browsers, but can differ. Real phones may also treat user-scalable=no differently, and many ignore it on purpose.
Untick width=device-width and look at the phone frame: the page is laid out as if the screen were wide, then shrunk until it fits.
What Is a Viewport?β
The viewport is the window onto your page: the part of the page you can see right now. On a desktop, it is the browser window. On a phone, there are really two:
| Term | Meaning |
|---|---|
| Layout viewport | The width the browser uses to lay out your page. CSS percentages and media queries use this |
| Visual viewport | The part the visitor can currently see. It shrinks when they pinch-zoom in, or when the on-screen keyboard appears |
Early phone browsers faced a problem: most websites were built for wide desktop screens. So phones pretended the screen was about 980 pixels wide, laid out the page that way, then shrank the result to fit. That kept old sites readable-ish, but it makes modern, responsive sites look wrong.
The viewport tag is how you tell the phone: "This page is built for small screens. Do not pretend."
The Two Settings You Needβ
<meta name="viewport" content="width=device-width, initial-scale=1">
| Part | Meaning |
|---|---|
width=device-width | Make the layout width equal to the real screen width, measured in CSS pixels |
initial-scale=1 | Start at normal size, with no zoom in or out |
CSS pixels are not the same as the physical dots on the screen. A modern phone may have a 1170-dot-wide screen, and still report about 390 CSS pixels, so that text stays readable. Your CSS works in CSS pixels.
See What Your Device Reportsβ
Try this on a phone and on a desktop, and compare:
- HTML Code
- Browser Output
console.log(window.innerWidth); // layout width in CSS pixels
console.log(window.devicePixelRatio); // physical dots per CSS pixel
console.log(window.visualViewport.scale); // the current pinch-zoom level
Reading your screenβ¦
Other Settings (and Which to Avoid)β
You can add more properties. Some are useful. Some are harmful.
| Property | Example | Advice |
|---|---|---|
width | device-width or 600 | Use device-width. A fixed number is rarely right |
initial-scale | 1 | Keep at 1 |
minimum-scale | 1 | Not needed |
maximum-scale | 5 | If you must set it, keep it at least 2 or higher. Never 1 |
user-scalable | no | Never. It blocks zooming |
viewport-fit | cover | Useful for full-screen designs on notched phones, with safe-area padding (see below) |
interactive-widget | resizes-content | Controls how the on-screen keyboard changes the layout. Support is newer and varies, so test |
Why Blocking Zoom Is Harmfulβ
<!-- Do not do this -->
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, maximum-scale=1">
People zoom for many reasons: low vision, small text, a bright screen, a hard-to-read font, or just looking at a photo more closely. Taking that away makes your page unusable for some visitors, and it goes against the Web Content Accessibility Guidelines, which expect text to be resizable up to 200 percent without loss of content.
Some browsers now ignore attempts to block zoom for this reason, but you cannot rely on that. Simply do not write it.
Do not add user-scalable=no. Do not set maximum-scale=1. If a layout "breaks" when zoomed, fix the layout, not the zoom.
The Viewport Tag Is Only Half the Jobβ
The tag makes the layout width equal to the screen width. Your CSS must then adapt to that width:
/* Flexible images and media */
img, video { max-width: 100%; height: auto; }
/* Mobile-first: base styles are for small screens */
.cards { display: grid; gap: 1rem; }
/* Wider screens get more columns */
@media (min-width: 600px) {
.cards { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 900px) {
.cards { grid-template-columns: repeat(3, 1fr); }
}
Tips:
- Design mobile first. Write the small-screen styles first, then add rules for wider screens with
min-width. - Use relative units (
rem,%,fr,ch) rather than fixed pixel widths. - Avoid horizontal scrolling. Wide tables, long words, and fixed-width elements are common causes.
- Make touch targets big enough: at least about 44 by 44 CSS pixels is a common guideline for buttons and links.
- Use
100dvh(dynamic viewport height) instead of100vhfor full-height sections, because phone address bars appear and disappear, and100vhcan be taller than what you can see.
Notches and Safe Areasβ
Some phones have a notch, rounded corners, or a home bar that covers part of the screen. By default, browsers keep your page inside the safe area. If you want content to run edge to edge, opt in:
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
Then add padding so text never hides behind the notch:
body {
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
padding-bottom: env(safe-area-inset-bottom);
}
Only use viewport-fit=cover if you are ready to handle those insets.
Text Size and Zoom on Inputsβ
A few extra mobile details:
- Keep body text at 16 pixels or larger. Some mobile browsers zoom in automatically when a visitor taps a form field with text smaller than 16 pixels, which can be disorienting.
- Use
remfor font sizes, so the visitor's own text-size setting is respected. - Test with the browser's text size set to large.
The Viewport in Docusaurusβ
Docusaurus adds a viewport tag to its pages by default, so you rarely need to write one. Still, check the built page's source to see it. If you build custom pages outside Docusaurus, include it yourself.
Good Habitsβ
- Always include
width=device-width, initial-scale=1. - Never block zoom.
- Build mobile first, then enhance for larger screens.
- Use relative units and flexible images.
- Test on a real phone, and in your browser's device mode.
- Test at 200 percent zoom, and at about 320 CSS pixels wide.
- Use
dvhunits for full-height layouts on phones. - Respect safe areas if you use
viewport-fit=cover.
Accessibility Checklistβ
- The viewport tag is present, and does not disable zoom.
- The page works at 320 CSS pixels wide without sideways scrolling (except for things like data tables or maps that need two dimensions).
- Text can be enlarged to 200 percent without loss of content.
- Touch targets are large enough, with space between them.
- Fixed or sticky bars do not cover content when zoomed.
- The layout still works in both portrait and landscape.
- Orientation is not locked without a real need.
Security and Privacy Notesβ
- The viewport tag itself is harmless, but what it controls is not just visual: a page that blocks zoom makes it harder for people to read warnings, consent text, and security prompts, and to notice details in a web address.
- Clickjacking and tiny controls: with a fixed, tiny layout, tapping the wrong thing is easy. Large targets with space between them reduce accidental taps on buttons such as "Delete" or "Pay".
- Do not use viewport data to track people. Combining screen size, pixel ratio, and other values can contribute to fingerprinting. Use these values for layout, and avoid collecting them without a reason.
- Safe-area use: make sure important controls, such as a consent button, are not hidden under a notch or home bar.
Global Audience Notesβ
- Many people in the world use phones as their only computer, often small, older, or low-cost models. The viewport tag is not optional for them.
- Test narrow widths, such as 320 pixels, and with larger system text, which is common among older users.
- Right-to-left and long-word languages may need more room. Use flexible layouts, and let text wrap.
- Translations can be 30 percent longer, which can break fixed-width buttons.
- Do not rely on hover. Touch screens have none.
- On slow networks, a mobile-first page that loads small images first is faster and cheaper to use.
Common Mistakes to Avoidβ
- No viewport tag, so phones show a tiny desktop page.
user-scalable=no.maximum-scale=1.- A fixed pixel width, such as
width=1024. - Forgetting responsive CSS, so the tag does not help.
- Elements wider than the screen, causing sideways scrolling.
- Using
100vhfor full-height sections on phones. viewport-fit=coverwithout safe-area padding.- Tiny tap targets.
- Text smaller than 16px in inputs.
- Testing only on a desktop browser.
- Two viewport tags with conflicting values.
Practice Timeβ
Try these in your editor:
- Add the viewport tag, then open the page in your browser's device mode.
- Remove it, and compare the result on a phone, or in device mode.
- Add
max-width: 100%to images, and check there is no sideways scrolling. - Write a mobile-first stylesheet with one
min-widthmedia query. - Use the reader above on your phone, and note your layout width.
- Zoom a page to 200 percent, and check that all content is still reachable.
- Replace
100vhwith100dvh, and test on a phone. - Add
viewport-fit=coverwith safe-area padding, and test on a phone with a notch. - Make all buttons at least 44 by 44 pixels.
- Bonus: check three popular websites for
user-scalable=no, and read what their source says.
Quick Recapβ
Click a question to check your answer.
1. What does the viewport tag do?
It tells mobile browsers to use the real screen width for the layout, and to start at normal zoom, instead of pretending the screen is a wide desktop.
2. What does width=device-width mean?
The layout width equals the screen's width in CSS pixels.
3. Why should you never use user-scalable=no?
It blocks pinch-zoom, and people with low vision and others rely on zoom to read. It also conflicts with accessibility guidelines.
4. Is the viewport tag enough to make a site mobile-friendly?
No. You also need flexible, responsive CSS: relative units, flexible images, and media queries.
5. What is viewport-fit=cover for?
It lets the page extend under the notch and rounded corners of some phones. You must then add padding with env(safe-area-inset-*).
6. What is the difference between the layout viewport and the visual viewport?
The layout viewport is the width used to lay out the page. The visual viewport is the part currently visible, which changes with pinch-zoom or the on-screen keyboard.
Key Takeawaysβ
- Without a viewport tag, phones lay out your page at about 980 pixels and shrink it.
- Use
<meta name="viewport" content="width=device-width, initial-scale=1">on every page. - Never block zoom: no
user-scalable=no, nomaximum-scale=1. - The tag only sets the width. Responsive CSS does the rest.
- Build mobile first, use relative units, and test on real devices at 320 pixels and 200 percent zoom.
- Use
dvh, safe-area insets, and large touch targets for a good phone experience. - Be careful with screen data, to avoid fingerprinting.
Next, connect files to your page with the Link element.