Fixes8 min read·

Landscape on phones: what breaks and how to fix it

Phones on their side are wide but short, like 874×402 on an iPhone 17 Pro. See which breakpoints they hit, what breaks in landscape and the CSS that fixes it.

A phone on its side is wide but very short: an iPhone 17 Pro turns into 874×402 CSS px and a Galaxy S25 into 780×360. That width is enough to trigger your tablet (md) layout, while Safari leaves only about 337px of height for the page, so sticky headers, full-height heroes, modals and cookie banners are what break. The fix is a height-based media query such as (max-height: 500px), not more width breakpoints.

Real landscape viewports

Turn a phone sideways and its portrait width and height swap. Real phones, in CSS pixels:

Phone On its side (CSS px) Tailwind Bootstrap
iPhone SE (2nd & 3rd gen) 667×375 sm sm
Galaxy S25 780×360 md md
iPhone 13 mini / 12 mini 812×375 md md
Galaxy S25 Ultra, Galaxy A56 / A36 832×384 md md
iPhone 17e, iPhone 14 / 13 / 12 844×390 md md
iPhone 16 852×393 md md
iPhone 17 Pro, iPhone 17 874×402 md md
iPhone Air 912×420 md md
Pixel 10 924×412 md md
iPhone 17 Pro Max 956×440 md md
Pixel 10 Pro XL 998×448 md lg
Galaxy Z Flip 6 1006×412 md lg

Tailwind's md runs from 768 to 1023px; Bootstrap's md from 768 to 991px, then lg from 992. So apart from the SE, every phone in the table gets your tablet layout on its side, and the biggest Androids get Bootstrap's desktop-ish lg. Class-by-class detail is in Tailwind breakpoints on real devices.

Two things shrink these numbers in practice:

  • Height goes to the browser. In landscape Safari shows a compact address bar at the top (about 44px) and keeps a strip for the home indicator at the bottom (about 21px). Those are estimates, but they leave an iPhone 17 Pro roughly 402 − 44 − 21 = 337px of page height and a 17 Pro Max about 375px. The full table is in How much of the screen iPhone users see in Safari.
  • Width goes to the cutout. On iPhones with a notch or Dynamic Island, Safari keeps the page out of the strips beside the cutout unless you use viewport-fit=cover, so the width your CSS sees is less than the screen width (Chrome adds similar margins beside camera cutouts on Android). For a phone near 768, that can decide which side of the breakpoint it lands on. Safe areas on iPhone explains the insets; to read the real number, open /whats-my-viewport on the phone and rotate it.

So think of a phone in landscape as "tablet width, letterbox height": 360–466px tall on the screen, less once the browser has taken its share.

What breaks

Your "phone" rules switch off

If your mobile styles live in @media (max-width: 767px), they stop applying the moment most phones rotate. The hamburger menu disappears and your desktop navigation appears, often a row of links that doesn't fit, or dropdowns that only open on hover, which a touch screen can't do. Either design the md layout for touch too, or keep the compact menu until a wider breakpoint. There's more on menus in Mobile menus that work.

Sticky headers eat a fifth of the screen

A 64px sticky header is fine in portrait, where an iPhone 17 Pro shows about 718px of page. In landscape it takes 64 of about 337px, nearly 20%, before the page has shown anything. Add a sticky "Book now" bar at the bottom and the reading area is a slot.

On short screens, let the header scroll away with the page:

@media (max-height: 500px) {
  .site-header {
    position: static;
  }
}

Full-height heroes

A hero with height: 100vh is sized to the viewport with the browser bars hidden, so it's taller than what people see on first load, in either orientation (why, and the dvh/svh fix). In landscape there's a second problem: your headline, paragraph, button and image may simply need more than 337px. With a fixed height and overflow: hidden, the button gets cut off.

.hero {
  min-height: 100vh;   /* fallback */
  min-height: 100svh;  /* fits with the browser bars showing */
}

@media (max-height: 500px) {
  .hero {
    min-height: auto;  /* let the content decide */
    padding-block: 24px;
  }
}

min-height lets the section grow when the content needs it, and on a short screen it's usually better to drop the full-screen idea altogether.

Modals, drawers and full-screen menus

A modal that's 500px tall with its buttons at the bottom is unreachable on a 337px screen if the modal itself can't scroll. The same goes for a full-screen menu with twelve links. Cap the height and let the inside scroll:

.modal {
  max-height: calc(100vh - 32px);   /* fallback */
  max-height: calc(100dvh - 32px);  /* follows the browser bars */
  overflow-y: auto;
  overscroll-behavior: contain;     /* don't scroll the page behind it */
}

A 120px cookie banner is a nuisance in portrait. In landscape it covers a third of the page, and on top of a sticky header, the visitor may see almost nothing else. Keep banners short, and let them wrap into two columns (text beside buttons) on wide, short screens.

Text gets bigger when you rotate

If your text jumps up a size when the phone turns, iOS's automatic text-size adjustment is kicking in. This line on html stops it while leaving pinch-zoom alone:

html {
  -webkit-text-size-adjust: 100%;
}

Tailwind's Preflight already includes it, with the comment "Prevent adjustments of font size after orientation changes in iOS", as does normalize.css.

Targeting phones on their side

@media (orientation: landscape) sounds like the answer, but it only means "the viewport is wider than it is tall". Every laptop and desktop monitor matches it. It can even match a phone held upright: MDN notes that opening the on-screen keyboard can make a portrait viewport wider than it is tall on some devices.

Height is the better signal. Across the 123 devices we track, every closed phone on its side is 360–466px tall, the smallest tablet on its side (the iPad mini) is 744px tall, and the shortest laptop screen is 720px. So max-height: 500px catches sideways phones and nothing else, apart from a desktop window someone has dragged very short, which also benefits.

/* Phones on their side */
@media (orientation: landscape) and (max-height: 500px) {
  .site-header { position: static; }
  .cookie-banner { display: flex; gap: 16px; align-items: center; }
}

The orientation part is optional; it keeps a tiny portrait window from matching.

Tailwind has landscape: and portrait: variants built in (Tailwind docs), but for height you need an arbitrary variant or, in Tailwind v4, your own:

<header class="sticky top-0 [@media(max-height:500px)]:static">
/* Tailwind v4: a reusable short: variant */
@custom-variant short {
  @media (max-height: 500px) {
    @slot;
  }
}

Then write short:static, short:min-h-0 and so on.

Bootstrap has no height breakpoints, so add the plain CSS media query above to your own stylesheet after Bootstrap's.

In JavaScript, use the same query with matchMedia rather than reading screen.width or listening for the old orientationchange event:

const sideways = window.matchMedia('(orientation: landscape) and (max-height: 500px)');

function update() {
  document.documentElement.classList.toggle('is-sideways-phone', sideways.matches);
}

sideways.addEventListener('change', update);
update();

Safe areas on their side

In portrait, the notch or Dynamic Island sits in the status bar. In landscape it's on the left or right, where your text starts, and the home indicator runs along the bottom. By default Safari keeps your page clear of all of it. If you've added viewport-fit=cover for an edge-to-edge look, pad the sides with max(16px, env(safe-area-inset-left)) and max(16px, env(safe-area-inset-right)), and fixed bottom bars with env(safe-area-inset-bottom). The full pattern is in Safe areas on iPhone, and mobile padding that works covers side padding in general.

Don't lock it to portrait

You can't make an ordinary web page stay upright. The Screen Orientation API's lock() typically only works in fullscreen, and MDN marks it as not working in some of the most widely used browsers. A "please rotate your phone" overlay is the other trick, and it's worse: WCAG's Orientation criterion asks that content isn't restricted to one orientation unless that's essential. Some people have their phone mounted sideways, or simply prefer it. Make landscape work instead; it's usually three or four rules.

Testing landscape

  • In doesitfit: press Rotate and every phone in the grid turns on its side, so you can see iPhones, Galaxies and Pixels in landscape together. Turn on Browser bars to add Safari's landscape address bar and home-indicator strip, and, with Browser bars off, Mockups to see where the Dynamic Island sits. If you check sites from Claude or ChatGPT through doesitfit's MCP server, you can ask for landscape there too.
  • On a real phone: load the page, rotate, then scroll to the bottom and open every modal and menu. Rotate back and check nothing stayed stuck in the landscape layout.
  • In DevTools: device mode has a rotate button, but it runs Chrome's engine and doesn't show Safari's toolbars; here's what else it misses.

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.

A prompt for your AI tool

My site breaks when phones are turned sideways (about 667–1006px wide but only 360–466px tall, less after the browser's bars). Add a media query for short screens, @media (orientation: landscape) and (max-height: 500px) (in Tailwind, the arbitrary variant [@media(max-height:500px)]: or a custom short: variant), and inside it: make sticky or fixed headers position: static; replace full-height heroes with min-height: auto and normal padding; make modals, drawers and full-screen menus max-height: calc(100dvh - 32px) with overflow-y: auto; lay the cookie banner out in one row. Check that rules written as max-width: 767px "mobile only" styles, especially the navigation, still make sense for touch screens at 768–1023px wide. Don't lock orientation or add a "rotate your device" message. Show me each change.

The takeaway

  • A phone on its side is 667–1006px wide and 360–466px tall, before the browser takes its share. Most get your md layout.
  • In Safari, an iPhone 17 Pro in landscape leaves roughly 337px of height for your page.
  • Sticky headers, 100vh heroes, tall modals and cookie banners are the usual casualties.
  • Target sideways phones with (max-height: 500px), not orientation alone.
  • Never lock orientation. Rotate, scroll and open every menu before you ship.

Questions people ask

What is the viewport size of an iPhone in landscape?

Its portrait size turned sideways: 874×402 CSS px for an iPhone 17 Pro and 956×440 for a 17 Pro Max. Safari's address bar and home-indicator strip then leave roughly 337px and 375px of height for the page (estimates).

Should I use orientation: landscape or max-height in media queries?

Use max-height, on its own or together with orientation. orientation: landscape also matches every laptop and desktop window, so by itself it can't tell you a phone is on its side; (max-height: 500px) only matches short screens like phones in landscape.

Can I force my website to stay in portrait?

No. The Screen Orientation API's lock() typically only works in fullscreen and isn't supported in some major browsers, and WCAG asks sites not to restrict content to one orientation unless it's essential.

Why does my desktop menu appear when I rotate my phone?

Most phones on their side are 768px wide or more, so they match Tailwind's md: and Bootstrap's md breakpoints. Anything written as a phone-only rule with max-width: 767px stops applying.

Keep reading