Media editor: Show image and crop info in Crop panel - #78650
Conversation
| * @param height Height in pixels. | ||
| * @return A compact aspect ratio label, or undefined for invalid dimensions. | ||
| */ | ||
| export function formatAspectRatio( |
There was a problem hiding this comment.
Verbose, but required to avoid weird results on images that are out by 1px from a "natural" preset aspect ratio.
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
| { label: __( 'Square - 1:1' ), value: 1 }, | ||
| { label: __( 'Standard - 4:3' ), value: 4 / 3 }, | ||
| { label: __( 'Portrait - 3:4' ), value: 3 / 4 }, | ||
| { label: __( 'Classic - 3:2' ), value: 3 / 2 }, | ||
| { label: __( 'Classic Portrait - 2:3' ), value: 2 / 3 }, | ||
| { label: __( 'Wide - 16:9' ), value: 16 / 9 }, | ||
| { label: __( 'Tall - 9:16' ), value: 9 / 16 }, |
There was a problem hiding this comment.
This was an oversight originally. It matches the default WordPress theme.json defaults. I thought it was important to speak the same "language" as Core here.
https://github.com/WordPress/gutenberg/blob/trunk/lib/theme.json#L196
| const originalAspectRatioLabel = useMemo( () => { | ||
| if ( ! cropperImage ) { | ||
| return undefined; | ||
| } | ||
| return formatAspectRatio( | ||
| cropperImage.naturalWidth, | ||
| cropperImage.naturalHeight | ||
| ); | ||
| }, [ cropperImage ] ); | ||
|
|
||
| const aspectRatioOptions = useMemo( () => { | ||
| const options = getAspectRatioOptions( aspectRatioPresets ); | ||
| if ( ! originalAspectRatioLabel ) { | ||
| return options; | ||
| } | ||
| return options.map( ( preset ) => { | ||
| if ( preset.value !== ORIGINAL_ASPECT_RATIO ) { | ||
| return preset; | ||
| } | ||
| return { | ||
| ...preset, | ||
| label: sprintf( | ||
| /* translators: %s: Aspect ratio, e.g. 4:3. */ | ||
| __( 'Original - %s' ), | ||
| originalAspectRatioLabel | ||
| ), | ||
| }; | ||
| } ); | ||
| }, [ aspectRatioPresets, originalAspectRatioLabel ] ); |
There was a problem hiding this comment.
So we show "Original - 16:9" and not just "Original" in the dropdown
There was a problem hiding this comment.
Pull request overview
Adds a compact “Image” and “Crop” measurements section to the Media Editor Crop panel, and improves aspect-ratio labeling consistency (including appending the image’s ratio to the “Original” preset label).
Changes:
- Introduces
formatAspectRatio(width, height)(with tests) to produce snapped small-integer ratios when close, otherwise a short decimal ratio. - Updates crop UI: shows image/crop pixel dimensions + aspect ratio, and appends the computed ratio to the “Original” aspect-ratio option label.
- Aligns fallback
DEFAULT_ASPECT_RATIOSlabels/order with core naming.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/media-editor/src/utils/test/aspect-ratio.ts | Adds unit tests for the new aspect ratio formatter. |
| packages/media-editor/src/utils/index.ts | Re-exports the new formatAspectRatio util for internal consumption. |
| packages/media-editor/src/utils/aspect-ratio.ts | Implements aspect ratio formatting with snapping/decimal fallback. |
| packages/media-editor/src/image-editor/core/constants.ts | Updates default aspect ratio preset labels to core-aligned naming. |
| packages/media-editor/src/components/media-editor/use-crop-options.ts | Appends computed image ratio to the “Original” dropdown option label. |
| packages/media-editor/src/components/media-editor/test/use-crop-options.tsx | Extends tests to assert the updated “Original - {ratio}” label. |
| packages/media-editor/src/components/media-editor/style.scss | Adds styles for the crop measurements <dl> grid layout. |
| packages/media-editor/src/components/media-editor-crop-panel/test/index.tsx | Adds a test covering rendering of image/crop measurements. |
| packages/media-editor/src/components/media-editor-crop-panel/index.tsx | Renders the new measurements section and formats values for display. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <dl | ||
| className="media-editor__crop-measurements" | ||
| aria-label={ __( 'Image and crop measurements' ) } | ||
| > | ||
| <div className="media-editor__crop-measurement"> | ||
| <dt>{ __( 'Image' ) }</dt> | ||
| <dd>{ formatMeasurement( imageMeasurement ) }</dd> | ||
| </div> | ||
| <div className="media-editor__crop-measurement"> | ||
| <dt>{ __( 'Crop' ) }</dt> | ||
| <dd>{ formatMeasurement( cropMeasurement ) }</dd> | ||
| </div> | ||
| </dl> |
There was a problem hiding this comment.
This was the only semantic way I could think of to get the "grid" style layout right. There don't appear to be any components that do what we want here. Or are there?
|
Size Change: +1.06 kB (+0.01%) Total Size: 8.21 MB 📦 View Changed
ℹ️ View Unchanged
|
|
This looks helpful! Showing both original image aspect + current crop aspect should make things much clearer. |
|
Neat idea exposing the current pixel dimensions + aspect ratio! In its current form, I'm wondering if it's a little noisy visually? Apologies if this is a bit verbose, but I was curious to try out a few ideas for how it could look:
Just throwing some ideas out there — IMO it's worth trying to find a good balance between a clean and simple UI while also exposing advanced level (or details-level) stats when needed 🤔 |
|
Thanks for working on this! I recommend going with Option 2. It offers the best clarity for before/after comparison, good hierarchy. Solid improvement — happy to see this ship. 👍 |
Thanks for going to the effort of presenting those options. I agree that it's very "in your face". I also like your second option - if things get crowded we can make it collapsible. |
bb14c81 to
b7b4354
Compare
I don't mind that. Is it worth getting a designer to give this a once over? Edit: to expand, what I like about pinning to the bottom is that it makes the stats area feel more like an isolated area for stats rather than part of the UI controls. That seems promising to me! |
Good idea! I'll merge today, and get more eyes on the polish follow ups like this. |
b7b4354 to
8965cd4
Compare
|
Flaky tests detected in 7689519. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/26558898919
|
|
Thanks for the ping, some good instincts here. I know that we have some older mockups, somewhere in the archive, that puts the pixel dimensions inside the dropdown, though perhaps those were for the resolution dropdown for images. I.e.: Not sure if that's feasible or right to do, there's a question on what happens for screen readers. The "Measurements" panel feels like a good path forward too, and I think this is really where we can connect with some of the design work @fcoveram has done for the media library, which has a lot of metadata listed in a table-grid on the right (I think through DataForm usage). There's certainly room here, so no reason we can't do something similar here. |
Thanks!! Yeah it'd be unfeasible to show the sizes in the aspect ratio dropdown, but it reminds me that something like that would be useful for the media library version of the image editor where we could apply attachment-level edits, potentially with subsize regeneration. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…ns to familiar ratios
7689519 to
a3f6234
Compare
|
Interesting exploration, but in this editing context I'm drawn to think that users are looking to match a specific size rather than seeing the exact pixels as they drag and drop the handles. That said, I think it adds more value to add a width and height controls that resize the image immediately. The live info seems to fit better in the Details tab. I'm working on an idea for this editing flow and will include my suggestions above to see how it feels |
There was a running PR to wire things up for something along these lines:
To me, having to click to another panel for information that directly relates to the image manipulation surface seems disconnected. I think you're instinct about the width and height controls could the be the sweet spot. So something #78187 would be more useful. I'll revive that one. Thanks for the feedback! |
|
Going to close this PR out. I think eventually it'll compete with advanced controls anyway. If folks think something like this is still necessary, let's regroup! |




What?
Another episode of "How much can we over-engineer a small feature?"
This PR adds an info section to the bottom of the Media Editor's Crop panel showing the original image's dimensions and aspect ratio, plus the current crop region's dimensions and aspect ratio.
While we're on the topic of Aspect Ratios, it also:
Original - 3:2), andDEFAULT_ASPECT_RATIOSconstant with core'slib/theme.jsonnaming.Follow-up to discussion on #73771
Why?
The Crop panel previously surfaced no information about the image's actual dimensions or aspect ratio.
The dropdown shows preset labels like "Standard - 4:3" but doesn't tell you what the image you're editing actually is.
That means you can't see whether you're cropping toward or away from its native proportions, or how far the current crop has diverged from the source.
Showing both rows side-by-side answers "what am I working with, and how much have I changed it?"
How?
New
formatAspectRatio(width, height)util. Finds the closest small-integer ratio (a:b with both ≤ 20) and snaps to it when within tolerance; otherwise falls back to a short decimal form. Off-spec resolutions like 1350×899 read as3:2, matching the dropdown label for that ratio. The search runs on the ≥1 form so landscape and portrait orientations snap symmetrically.Crop panel info section. A
<dl>rendered as a 2-column CSS grid (grid-template-columns: auto 1fr). Per-row wrappers usedisplay: contentsso the grid aligns across rows. When the crop region's dimensions equal the source image's (no cropping yet), the "Crop" row gets.is-untouchedand drops to a muted gray.Originaldropdown label. Now appends the image's computed ratio with the same hyphen separator core'slib/theme.jsonuses forSquare - 1:1,Wide - 16:9, etc.DEFAULT_ASPECT_RATIOSaligned with core. The hardcoded fallback (only used when a site has no theme aspect-ratio settings) now mirrorslib/theme.jsonexactly — same names, same order, same- ratioformat. Previously used a different naming scheme ("Landscape (16:9)" vs core's "Wide - 16:9").Testing Instructions
Image 1920 × 1080 px (16:9)Crop 1920 × 1080 px (16:9)Original - 16:9).Worth testing with off-spec resolutions:
3:2(matchesClassic - 3:2in the dropdown)16:9(matchesWide - 16:9)1.61:1(no clean small-integer fit)Screenshots
Kapture.2026-05-28.at.16.04.46.mp4
What it looked like before: