Responsive CSS cannot rescue a hero image that was composed for the wrong shape.
That is the whole argument, and it costs a week every time somebody learns it the slow way. Consider a cinematic 16:9 hero. It looks expensive on the laptop. Then a visitor opens the site on a phone held upright, the building you framed so carefully is now a wall, the headline sits across the subject's face, and the thing that made the shot worth taking is somewhere off the left edge of the viewport.
You have probably tried to fix that in CSS. A different object-position, an aspect-ratio override at a breakpoint, maybe a scale transform to buy back some subject. Those tools slide the crop window around inside the frame you already have. None of them invent pixels that were never captured.
So the portrait vs landscape hero image question on mobile is not really a styling question. It is a capture question that shows up disguised as a styling question, three weeks after the shoot, when going back for another one is expensive. Your first action is small: open your hero on a phone in portrait and check whether the subject is still where you framed it.
Why does one 16:9 hero fail on a portrait phone?
A 16:9 source in a tall phone container loses more than half its width to the crop, so an off-centre subject vanishes before CSS gets a vote.
Run the arithmetic once and you stop arguing about it. Take a 390-pixel-wide iPhone viewport with a hero occupying roughly 500 pixels of height. Fill that 390×500 box using object-fit: cover from a 1920×1080 source and the browser scales until the short axis fits: height 1080 scales to 500, a factor of 0.463, which renders the full width at about 889 pixels. The container shows 390 of those. You keep 44% of the frame and throw away the rest.
A centred crop keeps roughly the middle 44% of the source, from about 28% to 72% of its width. A subject on a one-third line can remain visible, but the surrounding composition collapses; a subject nearer the outer quarter can disappear completely. The browser may still download the whole file. object-fit decides which part it paints, not which pixels arrive over the network.
Calling that a rendering bug misplaces the blame. It is arithmetic you agreed to the moment you decided that one file would serve two aspect ratios.
Why is object-fit cover not enough for a mobile hero?
object-fit and object-position choose which rectangle of an existing image survives, so they crop rather than compose.
They are a pair of scissors with a ruler attached. Useful, and often enough for a portrait photo of a person where the head is near the middle, and useless for a composition whose meaning depends on the relationship between two things at opposite ends of a wide frame.
There is a CSS property that gets suggested here, object-view-box, which lets you define a viewbox inside a replaced element the way SVG does. MDN lists it as experimental and not Baseline, because it does not work in some of the most widely used browsers. Even if it shipped everywhere tomorrow it would not help, because it pans and zooms within the pixels you have. Same scissors, nicer handle.
There is one case where a single flexible image is the right call: when the subject is centred, the background is texture rather than content, and nothing in the frame carries meaning by its position. Skies, fabric, concrete. If your hero is a mood, one file is fine. If your hero is a statement, it is two files.
Should you ship separate portrait and landscape files?
Ship separate files whenever the subject's position inside the frame carries meaning; keep one flexible image only when the background is texture rather than content.
The decision is narrower than it looks. There are four real options and they sort by how much the composition matters and whether motion is involved.
| Approach | Assets to produce | Subject survives portrait | Choose it when |
|---|---|---|---|
One flexible image plus object-position | 1 | Only if centred | Background is texture, not content |
Art-directed <picture> with media | 2 or more crops | Yes, by construction | Composition carries meaning and the layout is static |
Poster image plus art-directed <video> | 2 clips, 2 posters | Yes, with one caveat below | Motion is the point and you control both cuts |
| Separate components per breakpoint | 2 or more | Yes | The hero's markup, not only its image, differs by device |
The third column is the one people skip, and it is the only column a client ever notices.
For the <picture> route the mechanics matter. The browser walks the <source> elements in order and evaluates each media condition. As MDN puts it, if a source's media condition evaluates to false the browser skips it and moves to the next, so the first match wins. The <img> inside is required rather than decorative, because it supplies both the fallback and the alt text. Order your portrait source before your landscape source or write conditions that cannot both be true, or you will ship the wide crop to phones and never see it on your own machine.
web.dev draws the distinction better than I can: srcset gives suggestions to the browser, while the picture element gives commands. Art direction needs the command.
Here is the decision procedure, in order:
- Ask whether the subject's position inside the frame carries meaning. If no, ship one image and set
object-positionto the focal point. Stop here. - Ask whether the hero moves. If it does not, use
<picture>with amediacondition on orientation or width, and produce a genuinely re-composed portrait crop rather than a centre cut of the wide one. - If it does move, produce two clips, two posters, and art-direct both, then read the video caveat below before you ship it.
- If the portrait and landscape heroes need different markup and not only different pixels, split the component, and keep the copy and the interaction identical so the content stays one thing.
If you work in Next.js, the docs route art direction through getImageProps instead of the Image component alone: you pull a srcSet for each crop and assemble a plain <picture> around them, with different width, height and quality per source. The current Image API reference shows 1440×875 for desktop and 750×1334 for mobile. Those are not two sizes of one picture. They are two pictures.
Why are the visual decision and the network decision the same decision?
Choosing the crop and choosing the bytes are one act, because the element that selects the source also selects the download.
This is where a lot of otherwise careful work falls apart. Teams build both crops, then deliver them by rendering both elements and hiding one with display: none. How many megabytes does your phone pull down for an asset it will never paint? On that pattern, potentially all of them. You have doubled the cost of the hero to solve a cropping problem, which leaves you worse off than the cropping problem did.
Here's how that went on Elpida Solutions.
Elpida Solutions uses dedicated landscape and portrait hero media because the dove, architecture and headline cannot share one crop without sacrificing the subject on a phone. I also had to prevent mobile from downloading the desktop clip it never displays; the wrong source selection wasted more than a megabyte per first visit. The visual decision and the network decision were the same problem.
A megabyte on a first visit is not a rounding error. The 2024 Web Almanac media chapter put the median largest image on a mobile page at 135 KB, and the 90th percentile at 1,002 KB, so a wasted clip of more than a megabyte outweighs the largest image on nine in ten mobile pages. The full Elpida Solutions case study covers the dedicated landscape and portrait media, the stable mobile viewport sizing and the reduced-motion handling.
The same chapter has a number worth sitting with. Only 9.3% of mobile pages use <picture> at all and 42% use srcset, and among pages that do use <picture>, the media attribute appears on 40% of them. Art direction is not a crowded field. Doing it properly is still a differentiator.
Why does a hero video ignore rotation?
A <video> evaluates its <source> list once when it loads and does not re-evaluate it when the media condition changes, which <picture> does.
Rotate the phone from portrait to landscape after the page has loaded and the portrait clip stays on screen, stretched or letterboxed into a shape it was not cut for. Resize a desktop window across the breakpoint and nothing swaps. Scott Jehl, who worked on getting this feature restored, documents the limitation plainly: responsive video is only responsive when the video first loads, unlike the picture element. There is also an open WHATWG issue asking the spec to make video behave like picture. Part of the difficulty is obvious once stated: swapping a source mid-playback means preserving the time code.
Support for the media attribute on video sources is not new either. Jehl's responsive video write-up records it landing in Chrome and Firefox stable, so it is usable today with the one-shot caveat. The stakes are not small: he cites a median video weight of almost 5 MB per page on mobile pages that use video, up 45% on mobile over five years.
The practical rule that falls out: art-direct on the initial load, accept that rotation will not re-cut, and choose a portrait composition that still reads acceptably at landscape phone dimensions. If you cannot accept that, listen for orientationchange, swap the source, and restore currentTime yourself. If your hero is decorative and short, do not bother.
Autoplaying heroes bring a second cost that has nothing to do with shape. A phone that holds several decoded clips at once can have its tab reclaimed by the system, which I wrote up separately in why mobile Safari reloads video-heavy pages.
What hero image size should you capture for a mobile screen?
Capture for the narrowest container you will ship, then crop outward, because you can always remove width and you can never add it back.
These are the common CSS widths worth framing against, and the landscape row is the one people forget to test. The working hero boxes are my suggested starting points, not a standard.
| Target | CSS width | Working hero box | What the frame must protect |
|---|---|---|---|
| Small phone | 320px | 320 × 420 | Subject plus 12% margin on every side |
| Common Android | 360px | 360 × 470 | Same subject, headline baseline clear |
| iPhone standard | 390px | 390 × 500 | Subject, plus room for the overlay block |
| Large phone | 430px | 430 × 560 | Subject and overlay, plus any logo lockup |
| Phone landscape | 844 × 390 | 844 × 300 | Subject survives a shallow band, no vertical detail below the fold |
Shoot or render the portrait asset at 1080×1920 and crop down. Keep the subject inside the middle 76% of the portrait frame so a 12% safe margin survives on both axes at every width in that table. Put the text overlay in a zone you deliberately left quiet, not wherever the layout happens to drop it, and check the contrast against the darkest and lightest pixels that zone can contain at 320 and at 430.
One more constraint belongs in the capture brief rather than the stylesheet. Size the hero box in svh rather than vh or dvh. MDN is direct about why: viewport units based on the dynamic viewport size can cause the content to resize while a user is scrolling, which degrades the interface and costs performance. A hero that changes height mid-scroll re-crops itself under the reader's thumb.
How should a reduced-motion hero look?
If the visitor has asked for reduced motion, the still you serve them is the hero, not a paused frame from a clip composed for movement. Pick a frame where the composition resolves on its own, export it as a proper portrait asset, and give it the same safe-area treatment as everything above.
How do you verify the hero on a real phone?
Open the network panel on a real phone profile, load the page cold, and confirm that exactly one hero asset arrived.
If two arrived, your media conditions overlap or a hidden element is still fetching. This takes ninety seconds and catches the failure that every visual review misses, because a hidden download looks perfect. Load performance work I have written about elsewhere applies here too, in how to get a Webflow site under one second. For a small-site example where one hero video pauses offscreen and swaps to a still for reduced-motion or data-saving visitors, see the Šahovski klub Dubica case study.
So: pull up your own hero on a phone right now, in portrait, and ask whether the subject is where you framed it. If it is not, the fix starts in the capture brief, not the stylesheet.





