A responsive hero image is not one image. On a wide desktop monitor the theme shows it as a strip, something close to 1600×500 pixels, a 3.2:1 panorama. On a phone the same file fills a portrait box around 390×600, a ratio of 0.65:1. Between the two sit laptops and tablets with boxes of their own. One file, four crops, and you probably only ever approved the first.
The arithmetic is harsher than it feels. Take a normal 16:9 photo, 1600×900. The desktop strip keeps 56 percent of it, all losses vertical. The phone keeps 37 percent, all losses horizontal. And the two crops disagree about what matters: a face that sits comfortably in the panorama can lose its forehead in the portrait box, and a product placed on the right for desktop drama can leave the phone frame entirely.
What decides the outcome is object-fit: cover plus a property almost nobody sets, object-position. Its default is 50% 50%, dead center. Every hero that ships without an explicit position is a bet that the most important part of the photo happens to sit in the middle, at every screen ratio at once. On four boxes with four different overflows, that bet loses more often than it wins.
Watch the crop happen
The simulator below runs the same crop the browser will run, with the same formula. Drop in your own hero, or start with the built-in sample, a 1600×900 scene with a balloon right of center and calm space on the left. Drag the focal point (mouse, touch or arrow keys) onto the thing that must survive, and the four previews update live: desktop 1600×500, laptop 1200×400, tablet 768×480, phone 390×600, each captioned with how much of the image it keeps. Tell it which side your headline sits on and it hatches that third of the wide previews and warns when the focal point drifts underneath. When the crops look right, copy the CSS: object-fit, object-position with your focal percentages, and an aspect-ratio skeleton per breakpoint. Everything runs in your browser; the image is never uploaded anywhere.
Hero crop simulator
Drop a hero image in, drag the focal point, and watch what every breakpoint keeps of it, with the CSS ready to copy. The picture is read in this browser tab only: nothing is uploaded and nothing leaves your computer.
or press Enter to pick one. It is read on your own machine and never sent anywhere.
Sample image, drawn in this browser.
With a text side set, the two wide previews hatch that third as a reminder that the headline will cover it.
Focal point at 50% / 50%. Put the cross on the one thing that must survive every crop.
Your focal point sits under the headline at desktop widths. Move it out of the hatched third, or put the text on the other side.
Your WordPress theme prints the hero image itself, so there is nothing to install. This CSS belongs on the img inside the Cover or Image block: paste it under Appearance, Customize, Additional CSS, and swap .hero-box for the class your theme really uses.
How cover picks the crop
object-fit: cover follows two rules, and both are simpler than they look. First it scales the image by a single factor:
scale = max(boxWidth / imageWidth, boxHeight / imageHeight)
That is the smallest scale at which the image still covers the whole box, and it has a consequence that simplifies everything: after scaling, the image fits the box exactly on one axis and overflows on exactly the other. There is never a crop on both axes. The 1600×900 photo in the 1600×500 strip needs no scaling at all, the widths already match, so the entire loss is vertical: 400 of 900 pixel rows fall outside the box. The same photo on the 390×600 phone is scaled to 1067×600 so the heights match, and 677 of those 1067 columns overflow. Every hero problem you have ever had lives on that one overflowing axis.
Two patterns are worth keeping. The axis flips as the box narrows: boxes wider than the image ratio cut height, boxes narrower cut width, and near 16:9 (the tablet’s 1.6:1 is close) nearly everything survives. And cover scales up as willingly as down: feed it a source smaller than the box needs and it enlarges the pixels, one of the causes dissected in why your WordPress images look blurry. The phone is the brutal box either way. It shows roughly a third of the image, and which third is entirely up to object-position.
object-position does not center your focal point
Here is the part that surprises almost everyone, and the reason the simulator exists at all. object-position: 70% 50% does not center the point at 70 percent of your image. The percentage rule, inherited from background-position, is an alignment rule: the 70 percent point of the scaled image is placed at the 70 percent point of the box. Per axis, the crop offset is:
overflow = scaledSize - boxSize
offset = position * overflow
Work the phone through. Scaled width 1067, box 390, overflow 677. At 70 percent the crop window slides 474 pixels. The focal point at 70 percent of the image width sits at 747 scaled pixels; subtract the offset and it lands 273 pixels into a 390 pixel box, exactly 70 percent of the way across. Off center, intact, and in the same relative position it held in the original photo.
That is not a coincidence, it is an identity. Put the focal point at some fraction of the image width and set object-position to the same fraction: the point sits at that fraction of the scaled width, the offset is the same fraction of the overflow, and the difference is always that fraction of the box width. The subject keeps its relative place in every box, whatever the overflow, whatever the breakpoint. This identity is why the simulator writes your focal percentages straight into object-position, and why one pair of numbers behaves sensibly in all four previews at once.
It also explains why true centering is impossible with a static value. To pull that 70 percent subject into the middle of the phone box you would need object-position: 82%. But 82 percent lands somewhere different on the tablet, because every box has a different overflow. One CSS value cannot center one point in four boxes, so the simulator does not pretend otherwise: it computes the browser’s rule, and the previews match what the copied CSS renders, to the pixel.
The endpoints are the useful special cases. 0% pins the left or top edge and takes the whole loss from the opposite side; 100% pins the right or bottom; 50% splits the loss evenly. A face in the upper third of a photo wants a vertical position around 25 to 35 percent, which is the entire cure for the cropped forehead.
Photos that can take the punishment
Once the four crops are visible, choosing hero material stops being a matter of taste and becomes selection criteria:
- One subject, not two. A person on the left and a product on the right cannot both survive a box that keeps a third of the width.
- Slack around the subject. The phone crop reaches to within a few percent of the focal point, and a subject touching the frame edge will be clipped.
- A background that loses 60 percent gracefully: sky, water, foliage, bokeh, an even wall. Anything with its own careful composition will be recomposed by force.
- A quiet third on the side where your theme puts the headline.
Vertical position deserves a sentence of its own, because the wide crops are decided entirely by it. In the 1600×500 strip, 44 percent of the height is gone, and the 50 percent default takes half from the sky and half from the foreground. If the photo has a horizon, choose where it lives: a focal point around 30 percent height keeps sky and drops foreground, around 70 percent does the reverse. Faces are stricter still, the eyes should end up in the top half of the strip.
The headline is the second passenger. On most themes the hero text occupies the left or right third of the wide layouts, and that third has to stay quiet: low detail, steady contrast, nothing pulling attention. The text side control in the simulator hatches exactly that third and warns when the focal point sits inside it; the tablet and phone previews stay unmarked because small screens usually stack the headline above or below the image instead. If your text keeps sinking into busy pixels anyway, there are fixes short of reshooting, covered in text on a photograph that stays readable.
The classic failures all break one of these rules. The forehead crop: face in the top third, position left at its 50 percent default, and the wide strip splits the loss evenly and slices through the hairline. The vanishing product: subject parked on the right edge for desktop drama, the phone keeps the middle 37 percent, product gone. The drowned headline: focal point and text fighting over the same third. Each of them shows up in the previews within seconds, which is cheaper than finding out from a customer’s phone.
Where the CSS goes in WordPress
The percentages are only useful once they reach the site, and WordPress gives you three different routes.
If the hero is a Cover block, you may not need CSS at all. The block’s sidebar has a focal point picker, and dragging it writes an inline object-position onto the image, the same property obeying the same rule. What the picker cannot show you is the result at other widths: the editor previews one box, and the crop you approve there is not the crop a phone renders. The workflow that holds up is to find the percentages in the simulator first, then set the same point in the picker.
If the theme prints the hero as a featured image, there is no picker anywhere. The Featured Image block offers size and aspect ratio controls but no focal point, and classic themes simply echo the thumbnail markup. This is where the copied CSS earns its keep: paste it into Additional CSS (in the Customizer, or under Styles in the site editor since WordPress 6.2) and swap the selector for whatever your theme actually prints, typically .wp-post-image or the hero’s figure. How large that rendered box is, and which pixel dimensions the theme registered for it, is the theme’s decision, not core’s; WordPress featured image size walks through where those numbers are defined.
.hero img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: 68% 42%;
}
@media (min-width: 1280px) { .hero { aspect-ratio: 1600 / 500; } }
@media (max-width: 480px) { .hero { aspect-ratio: 390 / 600; } }
Two boundaries keep the mental model clean. First, object-position chooses the crop; it has no influence on which file the browser downloads. That choice belongs to srcset and the size variants WordPress generated at upload, a separate pipeline with rules of its own, laid out in every file created from a single upload. Second, the aspect-ratio lines above are deliberately a skeleton: your theme already gives its hero a height at each breakpoint, so measure the real boxes before overriding them. If those ratios are not obvious from the theme’s settings, working out the image size your theme actually wants shows how to read them out of the rendered page.
A hero is a small layout system: one source file, one CSS rule, four boxes, and a single pair of percentages deciding what every visitor sees first. Most hero advice is about file size and format, and none of it rescues a phone crop that shows empty sky where the product used to be. The crop is not a rendering accident. It is a decision, and by default the browser makes it for you, at dead center.
The order that holds up: pick a photo with one subject and quiet space, put the focal point on the thing that must survive, look at all four boxes, then ship the percentages, in the Cover block picker or in Additional CSS. Two minutes in the simulator replaces the round trip of publishing, checking your phone, wincing, and re-cropping in an editor. The pixels of a responsive hero image were always going to be cut; the only question is who chooses which ones.