Make data-sizes="auto" object-fit aware#3
Open
JonatanStorlund wants to merge 1 commit into
Open
Conversation
Lazyloaded images using `data-sizes="auto"` resolved `sizes` from the element's `offsetWidth`. For images rendered with `object-fit: cover` or `object-fit: contain` (e.g. fill images in core/media-text blocks) the painted image is scaled to cover/fit a box with a different aspect ratio, so the box width underestimates the pixels actually needed and the browser picks a too-small, blurry srcset candidate. Account for the object-fit by deriving the effective width from the box dimensions and the image's intrinsic aspect ratio (read from the width/height attributes so it works before the image has decoded). Default object-fit (`fill`) keeps using `offsetWidth` as before. This fixes blurry object-fit fill images out of the box without per-theme `sizes`/skip-lazyload workarounds. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Lazyloaded images using
data-sizes="auto"had theirsizesresolved purely from the element'soffsetWidthin the lozadloadedhandler:For images rendered with
object-fit: cover/object-fit: contain— e.g. fill images incore/media-textblocks (is-image-fill-element, which WP core styles withobject-fit:cover;width:100%;height:100%) — the painted image is scaled to cover/fit a box with a different aspect ratio than the source. The box width therefore underestimates the number of pixels actually painted, so the browser selects a too-smallsrcsetcandidate and the image looks blurry.On a real page this resolved to e.g.
sizes="660px"(the box width) for a 2560×1708 image filling a tall column, when ~1300px were actually needed.Themes worked around this by computing a custom
sizesand skipping lazyload for those images. This should just work out of the box.Fix
When resolving
data-sizes="auto", take the image'sobject-fitinto account:fill/none) → keep usingoffsetWidth(unchanged behavior).cover→max(offsetWidth, offsetHeight * aspectRatio)contain→min(offsetWidth, offsetHeight * aspectRatio)The intrinsic aspect ratio is read from the
width/heightattributes (always present, so it works before the image has decoded), falling back to the decoded dimensions.Result
The same fill image now resolves to
sizes="1343px"and picks a sharp candidate — with no theme-sidesizes/skip-lazyload workarounds.Test plan
npm run build:production(bundle regenerated and committed)660px→1343pxwith no theme overrides activeMade with Cursor