gutenberg
gutenberg copied to clipboard
Image Block: Surface aspect-ratio tool for custom image dimensions
Many pattern designs rely on a specific dimension of an image in order to provide a compelling example. For example this circular avatar pattern:

At the moment, if you mean to update this person with a photo of your own, unless you replace it with a new image of the same dimensions and crop, the pattern will be broken. In order to solve this, the pattern should be able to retain its dimensions and aspect-ratio, so even if you drag a landscape photo into the pattern, it will be correctly masked to fit.
In the user interface, we can surface such preset aspect ratios in a dropdown. Shown here, 6 common presets:

The dropdown affords a rich visual shape representation of the aspect ratio numbers. When an aspect ratio is applied, the Height input field says "Auto", to indicate that its value is dynamically dependant on the width.
If you then proceed to add a custom value to the height field after all, that gives you a custom aspect ratio:

This is simple to translate to CSS as the aspect ratio of a 540x320 image as shown in the example can simply be stated using aspect-ratio: 540 / 320;
. See also this codepen for how that can work responsively.
To represent aspect ratios, especially as custom aspect ratios are possible, it would be useful if the shape icon was dynamically drawn based on each aspect ratio.
This ticket was updated Sep. 13.
See initial proposal
When you set square image dimensions on a rectangular image, the image gets skewed (note, there's a bug in the editor view at the moment). The skewed image is not that useful, and rarely what you want.
Since we know the original aspect ratio, we can surface a scaling tool when a non-natural aspect ratio is shown, letting you choose the scaling type so that the image gets masked instead of skewed:

The tool would simply apply object-fit: cover;
to the image, and work the same as how the Featured Image block does, letting you choose the scaling mode in a segmented control:

The ability to set the scaling mode would be very useful for patterns that perhaps include circular photos which when replaced with your own non-square images could become pill-shaped. Site Logo could also benefit from the maintaining the original aspect ratio.
In order for masked image to scale responsively according to a new aspect ratio, the aspect-ratio
property can be leveraged as is shown in this codepen.
See also:
- #38068
- #38556
- #31373
- #38988
- #39452
Instead of prioritizing explicit width / height, I'd want to explore using the aspect ratio tool (similar to the hard-cropping one) used. We can apply it to the cover block as well. We can still support resizing while maintaining aspect ratio.
We should also do this in conjunction with #41142 to support the creation of pattern with placeholders much better.
Instead of prioritizing explicit width / height, I'd want to explore using the aspect ratio tool
I agree.
It's a bit rudimentary, but I've experimented with aspect-ratio tied to image sizes — where selecting an aspect ratio calculates the proper height value from the width (and the object-fit crops it properly). Then when you resize, the height/width ratio is maintained.
https://user-images.githubusercontent.com/1813435/170721809-b948377d-f909-4969-becd-db3622bd2b0f.mp4
This is just an example, not the UI I think we should go with this implementation. :)
Nice, that looks good Rich. I took a quick stab at a remix based on your ideas:

As shortcuts to setting dimensions as well as applying object-fit: cover;
, a single unified control is much simpler. I imagine the settings icon takes you to setting a custom aspect ratio. I tried a slew of icon styles, but ended up in the same place as you, ultimately with square, portrait and landscape options. Seems like a good baseline to start with?
The use of a segmented control is an open question. I tried a button-control as well, but that didn't flow quite as nicely:
I was just speaking with a customer who was requesting this feature specifically in the Post Featured Image block.
Would the Aspect ratio options actually change the dimension values or would they change the aspect-ratio
CSS value?
As shortcuts to setting dimensions as well as applying object-fit: cover;, a single unified control is much simpler.
How do you decide which object fit to use in which case? And what happens when the user provides its own dimensions, do we still see the object fit controls?
Would the Aspect ratio options actually change the dimension values or would they change the aspect-ratio CSS value?
I'd love for it to set aspect-ratio. It wouldn't work in all browsers, but as a progressive enhancement it would in new ones, and it would gracefully fall back.
How do you decide which object fit to use in which case? And what happens when the user provides its own dimensions, do we still see the object fit controls?
Stretch isn't that useful, and something you could accomplish on your own if you wanted to, by supplying off dimensions. Contain could have use cases, but I also think we could start without it, and then add a choice between the type of object-fit when we find that necessary.
Would the Aspect ratio options actually change the dimension values or would they change the aspect-ratio CSS value?
I'd love for it to set aspect-ratio. It wouldn't work in all browsers, but as a progressive enhancement it would in new ones, and it would gracefully fall back.
But if dimensions are given, aspect ratio won't apply at all. And I think all images do have inline width and height values, I'd have to test it on the block. Still, controlling both dimensions and aspect ratio would be contradictory.
Just to step back for a moment, the main problem to solve with the aspect ratio presets is to enable you to drag and drop your big landscape photo into this pattern, and have the perfect circle and dimensions of the original pattern stick and be unchanged, just with your new updated photo:
When you pick an aspect ratio, I suppose the 2nd value becomes determined by the first one, so we could potentially gray out one of the width/height input fields if need be.
I also made this codepen which dives into some of the responsiveness.
When you pick an aspect ratio, I suppose the 2nd value becomes determined by the first one, so we could potentially gray out one of the width/height input fields if need be.
That sounds reasonable! and I agree that aspect-ratio is preferable, I was worried about confusing interactions with it.
Thanks for providing the extra context for this.
When we get round to this we should add the same tools to the Post Featured Image block.
Can we explore a design that combines the number presentation of the crop tools and a more visual symbol of what the rectangle looks like?
Here's an iteration that focuses on a single aspect ratio dropdown with 6 preset sizes:

The dropdown affords a richer visual shape representation of the aspect ratio numbers. When an aspect ratio is applied, the Height input field says "Auto", to indicate that its value is dynamically dependant on the width.
If you then proceed to add a custom value to the height field after all, that gives you a custom aspect ratio:

This is simple to translate to CSS as the aspect ratio of a 540x320 image as shown in the example can simply be stated using aspect-ratio: 540 / 320;
.
To represent aspect ratios, especially as custom aspect ratios are possible, it would be useful if the shape icon was dynamically drawn based on each aspect ratio.
I went ahead and updated the ticket name and description with the latest mockups.
Here's an iteration that focuses on a single aspect ratio dropdown with 6 preset sizes:
Looking good. ✨
When we get round to this we should add the same tools to the Post Featured Image block.
+1
At the moment, users need to upload a specific aspect of featured images to shape a certain layout.
This is great. The first thing users will ask is where is the Focal Point Picker? It needs to be included in the solution.
Another thing I'd like to include in the scope for this issue is being able to define aspect ratios and width / height pairs as presets from a theme perspective. Then a theme can define a specific dimension pair for a header that shows up to be reused on featured images or plain image blocks (essentially, anywhere the aspect ratio / width control shows up). Aspect ratios should be definable as an abstract unit-less ratio of width and height (16:9) but also as discrete unit values (1920px / 1080px) which would represent the same aspect ratio but also set a default width and height.
@mtias just to confirm I understand the above. We would like to add something like the below to theme.json spec:
"aspectRatio": [
{
"width": 16,
"height": 9,
"name": "16/9"
},
...
]
Could also do [[16,9],[1:1],...]
or ["16:9", "1:1", ...]
.
- If these options are defined they replace default options.
- They show up as options in the inspector as seen in @jasmussen mockup, as well as the aspect ratio dropdown in crop tool.
- The input in the inspector and crop toolbar should utilise the same component
discrete unit values (1920px / 1080px) which would represent the same aspect ratio but also set a default width and height.
I'm wondering whether an alternative and a way to kill two birds with one stone is to enable adding custom width values to layout
in theme.json. This was also mentioned here as a way to standardise containers etc across your site beyond content/wide. In the case of images you'd choose your aspect ratio and then choose your width driven by your theme with height set to auto.
In order to solve this, the pattern should be able to retain its dimensions and aspect-ratio, so even if you drag a landscape photo into the pattern, it will be correctly masked to fit.
This is an important point (acceptance criteria) to emphasise as we build this out. When replacing an image (e.g. via drag and drop) all existing values should be kept.
@SaxonF yes, though I'm not sure if we should make it additive (i.e. theme presets are appended to the default list) or an entire replacement. The former seems more correct to me given many of these aspect ratios are just table stakes and generally relevant.
I do think aspect ratio and width / height go hand in hand so we should aim for an approach that can combine its representation and use.
he former seems more correct to me given many of these aspect ratios are just table stakes and generally relevant.
@mtias Sounds good to me. Side note, it might be nice to standardise on whether we extend or replace options. It looks like in other cases such as typography->fontSize
we replace? I like how Tailwind have an an explicit theme -> extend -> aspectRatio
.
I do think aspect ratio and width / height go hand in hand so we should aim for an approach that can combine its representation and use.
Could we just lean on default block styles? In future a theme dev could also create block variations to tie together styles like borderRadius, aspectRatio, width.
"blocks": {
"core/post-featured-image": {
"aspectRatio": "var(--wp--preset--aspect-ratio--16-9)",
"layout": {
"width": "var(--wp--preset--layout--large)"
}
}
}
I don't feel too strongly about it and maybe both should be possible. If we did want to allow discrete unit values than we can just calculate aspect ratio and add default dimensions to dropdown option description.
I'm not sure if we should make it additive (i.e. theme presets are appended to the default list) or an entire replacement.
I'm thinking additive. A theme should be able to add its own, but in doing so — don't replace the existing options.
Theme.json spec
The theme.json value should be a unit-less string, either an numeral value 1.7
, or a ratio 16/9
.
Although a theme should be able to remove core-provided default aspect ratios — similar to color palettes and gradients (defaultAspectRatios
, set to true
initially). How about this:
"settings": {
"dimensions": {
"aspectRatios": [
{
"name": "Header",
"slug": "header",
"ratio": "16/11"
}
}
]
}
Visuals
Here's one way we could plug the existing aspect ratio selection pattern that we employ on the Image block's cropping mechanism, into the inspector of the Image block. I do think that this would be easier to implement initially on the Post Featured Image block though.
In this scenario, the theme has added two aspect ratios (21:9 and Header), which is added to a separate menu group.


It doesn't look/feel consistent, but we could clean it up quite a bit by adjusting the existing components:

Reference
The existing aspect ratio mechanism within the Image block crop flow:

@richtabor design wise it looks good to me with adjusted controls. I'm assuming we will want the dropdown used in image crop to use the same component.
Unrelated to this issue but worth discussing whether image dimensions belongs in settings or appearance especially with aspect ratio now part of it.
It doesn't look/feel consistent, but we could clean it up quite a bit by adjusting the existing components:
I like the cleaned up version. Doesnt seem like we need additional subheadings, ideally.
I just had a client whom tested out the FSE Twenty Twenty Three for the first time and end up using Page Templates that the Query Loop used different size images. It is important to add the feature to the Featured Image block making it possible to have all featured images be cropped to use the same size.
It is important to add the feature to the Featured Image block making it possible to have all featured images be cropped to use the same size.
@paaljoachim ✅ https://github.com/WordPress/gutenberg/pull/47854
Great! Thanks for linking in the Add aspect-ratio to post featured image block PR, @richtabor I look forward to trying this out in Gutenberg plugin 15.2. To see how it works in the Query Loop with different size featured images.
Is there any chance to add the aspect-ratio control to Site Logo block as well? It'd be nice if themes could specify the ratio for the logo. cc @richtabor
Is there any chance to add the aspect-ratio control to Site Logo block as well?
We probably could, though I wouldn't say that most logos abide by a particular aspect-ratio. I think it only works particularly well if you wanted a Site Logo to be square.
Maybe we could have width/height dimensions with the linked functionality that's proposed in https://github.com/WordPress/gutenberg/issues/47963#issuecomment-1426019838 — though I'm not 100% sure. Especially with the funky width dimension control stuff referenced here: https://github.com/WordPress/gutenberg/issues/47979
We probably could, though I wouldn't say that most logos abide by a particular aspect-ratio. I think it only works particularly well if you wanted a Site Logo to be square.
Yes, I'm thinking about an avatar like "logo" for a personal blog theme or a portfolio theme.
Is there any chance to add the aspect-ratio control to Site Logo block as well? It'd be nice if themes could specify the ratio for the logo.
Incidentally, I just filed https://github.com/WordPress/gutenberg/issues/48608 to add a preview in the block settings sidebar for when the Site Logo is selected as a Site Icon. As it stands right now, the user doesn't know that the icon is a square and they don't know how the image will get cropped.