What is a viewport? CSS pixels vs screen resolution
A viewport is the area your page is laid out in, measured in CSS pixels, not screen pixels. See real numbers from iPhones and MacBooks, then check yours.
A viewport is the rectangle your web page is laid out in, measured in CSS pixels. It is usually much smaller than the screen resolution: an iPhone 17 Pro has 1206×2622 physical pixels, but it gives websites a 402×874 viewport. Your CSS, your media queries and your layout all react to the viewport, never to the resolution on the box.
That one fact explains a lot of "why does my site look like that?" moments. Here's how it works, with real numbers.
CSS pixels vs physical pixels
A physical pixel is one of the tiny dots of light on the panel. A CSS pixel is the unit you write in your stylesheet (16px, width: 400px). They used to be the same thing. On modern screens they're not.
If phones mapped one CSS pixel to one physical pixel, a 16px paragraph on an iPhone 17 Pro would be about a third of the size you'd expect and completely unreadable. So the phone says: "treat every CSS pixel as a 3×3 block of real pixels." That multiplier is the device pixel ratio, or DPR (we cover it properly in Device pixel ratio explained).
Physical pixels ÷ DPR ≈ CSS viewport. Here's what that looks like on real devices:
| Device | Physical pixels | CSS viewport | DPR |
|---|---|---|---|
| iPhone 17 Pro | 1206×2622 | 402×874 | 3 |
| iPhone SE (2nd & 3rd gen) | 750×1334 | 375×667 | 2 |
| Galaxy S25 | 1080×2340 | 360×780 | 3 |
| Pixel 10 | 1080×2424 | 412×924 | 2.625 |
| iPad Air 11″ | 1640×2360 | 820×1180 | 2 |
| MacBook Air 13″ | 2560×1664 | 1470×956 | 2 |
| 15.6″ Full HD laptop @ 125% | 1920×1080 | 1536×864 | 1.25 |
| 24″ Full HD monitor | 1920×1080 | 1920×1080 | 1 |
Every device's numbers are on the devices page, and the screen sizes overview groups them by viewport. A few things jump out.
- Phones are all roughly 360 to 440 CSS pixels wide, even though their panels are mostly 1080 to 1440 physical pixels wide. Your mobile layout has to work at /screen-sizes/360x780, not at 1080.
- Android rounds. The Pixel 10's 1080 physical pixels divided by 2.625 is 411.4, and Chrome on Android rounds the CSS size up to 412.
- The MacBook Air doesn't divide neatly. Its 2560×1664 panel defaults to a 1470×956 CSS viewport, yet CSS still reports a DPR of 2. macOS draws the screen at 2940×1912 and scales it down to fit the panel. There's more on that in MacBook resolution vs CSS pixels.
- Windows laptops shrink too. A Full HD laptop at the common 125% scaling gives websites 1536×864, not 1920×1080. See Windows display scaling and the 1536×864 viewport.
The screen isn't the viewport either
Even in CSS pixels, "screen size" and "viewport" are different things.
On a desktop or laptop, the viewport is the inside of the browser window, not the screen. The MacBook Air 13″ screen is 1470×956, but a maximized Chrome window loses the menu bar at the top and 87px for Chrome's tab strip and toolbar. Resize the window and the viewport changes with it. Plenty of people browse in a half-width window, so a "laptop" visitor can easily be 735px wide.
On a phone, the viewport width matches the screen width (as long as your page has the meta viewport tag), but the visible height doesn't. Safari's status area and toolbars, or Chrome's toolbar and gesture bar, sit on top. On a 402×874 iPhone, Safari leaves about 718px of page visible on first load. That gap is why 100vh misbehaves on phones: see 100vh on mobile is broken and how much of the screen iPhone users see in Safari.
Layout viewport vs visual viewport
Phones have two viewports, and it helps to know which is which.
- The layout viewport is the box the browser lays your page out in. Percentage widths,
vwunits,position: fixedand media queries are all based on it. On an iPhone 17 Pro with the viewport tag in place, it's 402px wide. - The visual viewport is the part of the page you can actually see right now.
Most of the time they're the same size. They split apart when you pinch to zoom: zoom in 2× and the visual viewport shrinks to about 201 CSS pixels of the page across, while the layout viewport stays at 402 wide. Your layout doesn't reflow, you're just looking at a smaller piece of it. The on-screen keyboard works the same way in Safari and in Chrome on Android (since Chrome 108): by default it shrinks the visual viewport, not the layout one.
MDN has a good diagram of this in its viewport concepts guide.
One more thing: if a page has no meta viewport tag, mobile browsers make the layout viewport about 980px wide and shrink the whole thing to fit the screen. That's the classic "my site looks like a tiny desktop page" problem, covered in Why your website looks zoomed out on phones.
How to read the viewport in JavaScript
There are several numbers, and they mean different things:
window.innerWidth // layout viewport width, scrollbar included
document.documentElement.clientWidth // layout viewport width, scrollbar excluded
window.visualViewport.width // the part you can see (shrinks when pinch-zoomed)
screen.width // the whole screen, in CSS pixels
window.devicePixelRatio // physical pixels per CSS pixel
Here's what you'd get on two real setups:
| Property | iPhone 17 Pro, Safari, not zoomed | Full HD laptop @ 125%, Chrome maximized |
|---|---|---|
window.innerWidth |
402 | 1536 |
document.documentElement.clientWidth |
402 | 1536 minus the scrollbar |
window.visualViewport.width |
402 (smaller when zoomed in) | about the same as clientWidth |
screen.width |
402 | 1536 |
window.devicePixelRatio |
3 | 1.25 |
What each is good for:
window.innerWidthmatches what CSS media queries see. The MDN definition is the width of the layout viewport, including the vertical scrollbar.document.documentElement.clientWidthis the space your content can actually use. On Windows with classic scrollbars it's a little less thaninnerWidth. On phones and on Macs with overlay scrollbars they're usually equal.window.visualViewportis for things that must follow what the user sees, like a toolbar that stays put while someone pinch-zooms or types. See the Visual Viewport API.screen.widthdescribes the monitor, not your page. A visitor with a 1536px screen might have a 900px window. It also has quirks: Safari on iPad keeps reporting portrait values even when the iPad is rotated. Don't make layout decisions with it.
If you need to make a layout decision in JavaScript, ask the same question CSS asks:
const isWide = window.matchMedia('(min-width: 768px)').matches;
That way your JS and CSS never disagree about which layout is showing.
Why the viewport, not the resolution, decides your media queries
A media query like this:
@media (min-width: 768px) {
.grid { grid-template-columns: repeat(3, 1fr); }
}
checks the viewport width in CSS pixels, scrollbar included. Nothing else. That leads to results that surprise people:
- The iPhone 17 Pro has 1206 physical pixels across, but to CSS it's a 402px screen, so it gets your phone layout. Good.
- The MacBook Air 13″ has 2560 physical pixels across, but at its default setting it's 1470 CSS pixels wide. Tailwind's
2xlbreakpoint starts at 1536px, so your2xl:styles never show on that laptop with a maximized window. - A 15.6″ Full HD laptop at 125% is 1536 wide, right on that same breakpoint, while a 24″ Full HD monitor at 100% is 1920.
There used to be device-width media queries that looked at the screen instead. They're deprecated. Use width, min-width and max-width (or the newer range syntax, @media (width >= 768px)).
This is also why the right question when picking breakpoints is "what viewports do real people have?", not "what resolutions are phones sold with?". Here are the default breakpoints most frameworks ship with:
| Framework | Breakpoint | Min width | Real screens at that width or wider (portrait) |
|---|---|---|---|
| Tailwind CSS | sm | 640px | from Samsung Galaxy Z Fold 6 — unfolded (708px) up |
| Tailwind CSS | md | 768px | from iPad 9.7″ / mini (classic) (768px) up |
| Tailwind CSS | lg | 1024px | from iPad Air 13″ (M2–M4) (1024px) up |
| Tailwind CSS | xl | 1280px | from 13–14″ WUXGA 1920×1200 @ 150% (1280px) up |
| Tailwind CSS | 2xl | 1536px | from 15.6″ / 17″ Full HD @ 125% (1536px) up |
| Bootstrap 5 | sm | 576px | from Samsung Galaxy Z Fold 6 — unfolded (708px) up |
| Bootstrap 5 | md | 768px | from iPad 9.7″ / mini (classic) (768px) up |
| Bootstrap 5 | lg | 992px | from iPad Air 13″ (M2–M4) (1024px) up |
| Bootstrap 5 | xl | 1200px | from 13–14″ WUXGA 1920×1200 @ 150% (1280px) up |
| Bootstrap 5 | xxl | 1400px | from MacBook Neo 13″ (1408px) up |
And here are the viewports of some of the most popular devices right now:
For a closer look at where those breakpoints land on real hardware, read Tailwind breakpoints on real devices and Responsive breakpoints in 2026.
Check your own viewport
Open /whats-my-viewport on any device. It shows your current viewport, screen size and device pixel ratio, live. A few experiments worth trying:
- Resize your browser window on a laptop. The viewport changes, the screen size doesn't.
- Zoom the page with Ctrl/Cmd and plus. On desktop, browser zoom makes the CSS viewport smaller and the DPR bigger. At 125% zoom, a 1920px monitor behaves like a 1536px one.
- Rotate your phone. The width jumps (on a 402×874 iPhone, from 402 to something much wider), and your site may switch to its tablet layout.
- Pinch-zoom on your phone. The layout viewport stays put. That's the visual viewport doing its thing.
Knowing your own numbers is step one. Knowing your visitors' numbers is the useful part.
Does your site fit?
Paste your address (or localhost:3000). doesitfit shows it on real screen sizes at once and tells you, bluntly, where it spills.
Free, no sign-up. Or ask Claude, ChatGPT or Codex to check it.
doesitfit loads your page at the exact CSS viewport of 123 real devices side by side, from a 360px-wide Galaxy S25 up to a 5120px-wide super-ultrawide monitor, and flags any screen where the page is wider than the viewport.
The short version
- Design in CSS pixels. Phones are about 360 to 440 wide (iPhone, Samsung Galaxy, Google Pixel), tablets about 744 to 1032 (iPad, Android tablets), laptops mostly 1280 to 1728 (MacBook, Windows laptops).
- Resolution is marketing. 1206×2622 means "sharp", not "1206px of room for your layout".
- Media queries read the layout viewport, the same number as
window.innerWidth. - On desktop the viewport is the window, and it's often smaller than the screen.
- On phones the visible height is less than the screen, because of the browser bars.
- Don't use
screen.widthfor layout. UsematchMediawith the same queries as your CSS.
Questions people ask
What is the most common mobile viewport size?
In StatCounter's August 2026 worldwide data the most reported mobile size is 414×896 (13.7%), followed by 360×800 (9.2%) and 390×844 (6.83%). The 414×896 figure is likely inflated, because Safari 26 reports a fixed screen size to known fingerprinting scripts, so it is not all real iPhone 11s.
Why does my 1920×1080 laptop only give websites 1536 pixels?
Windows scales the display to 125% by default on many Full HD laptops, so 1920 physical pixels become 1536 CSS pixels at a device pixel ratio of 1.25. Your CSS sees 1536, not 1920.
Does the viewport change when I rotate my phone?
Yes. The width and height roughly swap, so media queries suddenly see a much wider viewport, while the height shrinks to a sliver once the browser bars are taken off. Test landscape as well as portrait.
Is 100vw the same as the viewport width?
1vw is 1% of the layout viewport width, and it includes the vertical scrollbar. On phones scrollbars float over the page so 100vw matches the screen, but on desktops with classic scrollbars 100vw is slightly wider than the visible area.