Ok, itās much clear for me now. Thanks @SantosGuillamot!
Just mention that srcset
and sizes
just gives information about the width
of the image so it would be the last case (only width is known) if there isnāt any other way to obtain the dimensions.
I guess this feature doesnāt need design after all.
I think there might be another case where the width and height might be defined in the src
query? Not sure if we encountered this before.
As for the solution for not known height, I think the only way to go is just defining a default height and default aspect ratio. Iād aim to something like 16:9, so the worst case scenario is a vertical image that is just too small.
Another solution to mitigate this could be to implement a zoom option within the component? It could be done with CSS or maybe just a link to the image? Even if that means to leave the blog?
Do you mean when the height is not known and a default aspect ratio is set?
So, for example, in this URL the lazy load is broken. That theme is using our image
processor, but the images donāt have a height:
<img
alt="captura de nuestro blog funcionado en localhost:3000 cargando un contenido de ejemplo"
sizes="(max-width: 1024px) 100vw, 1024px"
class="frontity-lazy-image wp-image-118"
loading="lazy"
style=""
src="https://horus.online/wp-content/uploads/2019/10/Captura-de-pantalla-2019-10-19-a-las-13.33.48-1024x700.png"
srcset="https://horus.online/wp-content/uploads/2019/10/Captura-de-pantalla-2019-10-19-a-las-13.33.48-1024x700.png 1024w, https://horus.online/wp-content/uploads/2019/10/Captura-de-pantalla-2019-10-19-a-las-13.33.48-300x205.png 300w, https://horus.online/wp-content/uploads/2019/10/Captura-de-pantalla-2019-10-19-a-las-13.33.48-768x525.png 768w, https://horus.online/wp-content/uploads/2019/10/Captura-de-pantalla-2019-10-19-a-las-13.33.48-1568x1072.png 1568w"
>
The original block image doesnāt have a height anywhere:
<div class="wp-block-image">
<figure class="aligncenter">
<img
src="https://horus.online/wp-content/uploads/2019/10/Captura-de-pantalla-2019-10-19-a-las-13.33.48-1024x700.png"
alt="captura de nuestro blog funcionado en localhost:3000 cargando un contenido de ejemplo" class="wp-image-118"
srcset="https://horus.online/wp-content/uploads/2019/10/Captura-de-pantalla-2019-10-19-a-las-13.33.48-1024x700.png 1024w, https://horus.online/wp-content/uploads/2019/10/Captura-de-pantalla-2019-10-19-a-las-13.33.48-300x205.png 300w, https://horus.online/wp-content/uploads/2019/10/Captura-de-pantalla-2019-10-19-a-las-13.33.48-768x525.png 768w, https://horus.online/wp-content/uploads/2019/10/Captura-de-pantalla-2019-10-19-a-las-13.33.48-1568x1072.png 1568w"
sizes="(max-width: 1024px) 100vw, 1024px" />
<figcaption>Aspecto inicial de nuestro blog </figcaption>
</figure>
</div>
What should we do in these cases?
Maybe the safest way would be to go back to the Intersection Observer implementationā¦
Ok, my bad⦠I have updated the Image
component on that repo and it looks like thatās exactly what we are doing right now
Sorryā¦
This the code now:
<img alt="captura de nuestro blog funcionado en localhost:3000 cargando un contenido de ejemplo"
sizes="(max-width: 1024px) 100vw, 1024px"
class="frontity-lazy-image wp-image-118"
loading="auto"
style=""
src="https://horus.online/wp-content/uploads/2019/10/Captura-de-pantalla-2019-10-19-a-las-13.33.48-1024x700.png"
srcset="https://horus.online/wp-content/uploads/2019/10/Captura-de-pantalla-2019-10-19-a-las-13.33.48-1024x700.png 1024w, https://horus.online/wp-content/uploads/2019/10/Captura-de-pantalla-2019-10-19-a-las-13.33.48-300x205.png 300w, https://horus.online/wp-content/uploads/2019/10/Captura-de-pantalla-2019-10-19-a-las-13.33.48-768x525.png 768w, https://horus.online/wp-content/uploads/2019/10/Captura-de-pantalla-2019-10-19-a-las-13.33.48-1568x1072.png 1568w"
>
And lazy loading works, so I guess itās using the IO.
Actually here you have a case where you can get the aspect ratio from the image url. I know itās kinda of a long shot, but it might make sense to cover cases like 1024x700
with a regexp or ?width1024&height=700
or ?w=1024&h=700
just parsing the query parameters.
But Iām a bit lost on what has IO to do with not having height. Did you decide to eagerly load images that donāt have height to avoid the jump later?
It looks like we fallback to IO when the image doesnāt have height because the native lazy load doesnāt work. I forgot about that. But we do lazy load it.
I think it makes sense to support aspect ratio extraction from the image URL. After all, weāre going to be dealing with images generated by WP or WP.com (Jetpack) most of the time.
Apart from that, we cannot use a container for the image because we break Gutenberg CSS. So we need to use an image placeholder instead. I hope thatās not a problem when using an aspect ratio, is it?
Is it possible to use <figure>
as the container? The problem is that I donāt think we can make the images responsive maintaining the aspect ratio without a wrapper. At least I couldnāt find a way to do so.
It would be amazing if we could. Otherwise, we can search for wp-block-image
with a higher priority processor and use its own wrapper. Then, try to get the images that are not included in a block. But that would complicate thingsā¦
For reference, these are the current Gutenberg variations of the image block:
- With no-alignment (nothing selected), the HTML of an image is:
<figure class="wp-block-image">
<img ...>
</figure>
- With align left , the HTML of an image is:
<div class="wp-block-image">
<figure class="alignleft">
<img ...>
</figure>
</div>
- With align right , the HTML of an image is:
<div class="wp-block-image">
<figure class="alignright">
<img ...>
</figure>
</div>
- With align center , the HTML of an image is:
<div class="wp-block-image">
<figure class="aligncenter">
<img ...>
</figure>
</div>
- With wide width , the HTML of an image is:
<figure class="wp-block-image alignwide">
<img ...>
</figure>
- And finally with full width , the HTML of an image is:
<figure class="wp-block-image alignfull">
<img ...>
</figure>
The library lazysizes
has some recommendations to solve this:
It also has a plugin to use an aspectratio
attribute. We can take a look at the code to understand what it does.
It looks like the Gutenberg team is going to solve the markup mess of the Image block: https://github.com/WordPress/gutenberg/issues/20650
I guess this will simplify the implementation for the fact that the aspect ratio canāt be applied directly to the img
tag.
- No Gutenberg -> add wrapper
- Gutenberg -> use
wp-block-image
wrapper
Is that right guys?
It seems like there has not been much movement in this issue since November: https://github.com/WordPress/gutenberg/issues/20650 so maybe we should not wait anymore and try to fix this, as @orballo has proposed in this other thread
@cielosky42, could you help us here by making a list of the different variations of the current Gutenberg Image block, similar to the one I did a year ago here: Image component: avoid jumps on image load? Thanks!!
Awesome, thanks
I just run into this today. Maybe itās a thing to take into account:
@luisherranz After going over this again, it does not appear that there have been any changes to the standard image markup since you documented it above. I think I was confused by the inconsistent image markup that depends on alignment.
Iāve further narrowed down issues with align left/right/center and non-aligned images.
For align left/right:
The images donāt display when floated left or right. The images themselves are absolutely positioned, and none of its parents have an explicit width set. If I set an explicit width on the wrapping figure element, the image is visible and is able to scale as needed when the constrained by the screen width.
The span in between the figure and img elements has both āwidthā and āheightā properties set. However, this syntax is not valid on spans, only images. Was this meant to be added as CSS properties instead?
If so, I am seeing issues when trying to set the CSS of the span with the width and height. If I try going that route, the image does not display in the right aspect ratio as soon as there isnāt enough room for the full image size. It becomes distorted, or doesnāt scale, or has a bunch of extra padding, depending on other CSS added.
Iām not sure about all the other scenarios listed at the top of this thread, but as far as just adding an image block with left or right alignment, the only thing that works for me without running into the issues I mentioned is if I set an explicit width on the figure with a max width of 100%.
For aligncenter and images with no alignment:
Aligncenter and images with no alignment are filling the entire available space, greater than the width should be for the given size. Setting an explicit width on the figure also resolves the problem here.
Looking at the HTML2react image processor, I donāt see a way to modify the wrapping figure element, nor a way to target the image markup differently based on alignment.
Other than the previously mentioned CSS that overrides the āpadding hackā, I was also able to āfixā this by targeting the size classes added by Gutenberg, which get added to the figure element. However, this requires adding specific styles for each avaialable image size. It would be nice if these extra steps werenāt necessary.
Hereās example CSS to fix things for the āmediumā image size:
figure.wp-block-image.size-medium,
div.wp-block-image .size-medium {
width: 300px;
max-width: 100%;
}
Lastly, the images in the Gallery block suffer from these same issues. I was not able to apply the same fix as above with the gallery, because there arenāt image size classnames added to the figures in this case. The only solution I found here was to override the āpadding hackā.
Thanks a lot for the detailed analysis @cielosky42
Thanks to you as well @orballo. Very interesting, although it seems like we would have to wait a while until all major browsers have support for this, right?
In my opinion, we have two different use cases here:
- The Gutenberg images inside of
content
. - The other images added by the theme in React, like the Feature Image in a post or an archive.
For case 1, I see no reason right now to do anything on top of what WordPress+Gutenberg is already doing.
Iāve been taking a look and it seems like Felix Arntz added a fix to WordPress 5.5 to always include the image dimensions and avoid a layout shift:
- Images should always provide dimensions Ā· Issue #23244 Ā· WordPress/gutenberg Ā· GitHub
- #50367 (Avoid layout shifting due to images not having dimension attributes) ā WordPress Trac
I am not sure this is a 100% solved problem yet and there are still some related issues open in Gutenberg:
- Images should always provide dimensions Ā· Issue #23244 Ā· WordPress/gutenberg Ā· GitHub
- Enhancement: images handling Ā· Issue #6177 Ā· WordPress/gutenberg Ā· GitHub
- Block Alignments Rethinking Ā· Issue #20650 Ā· WordPress/gutenberg Ā· GitHub
But my point here is: Why should we spend time solving an issue on top of WordPress if it can be solved in WordPress and there are people already working on solving it in WordPress? š¤·
@santosguillamot @cielosky42: what happens if we remove the image
processor and simply use the Gutenberg CSS? Are the problems solved?
For case 2, I think we could provide an Image
component that solves this for the rest of the images. Maybe we can design it to make it impossible to cause a layout shift.
I am not sure about the requirements for that, but I guess it would require at least one prop that it can use to figure out the space that needs to be reserved:
-
A fixed
height
.
Used in conjunction withwidth: 100%
to calculate the responsive size. -
An aspect ratio.
With the same value as the upcoming CSS prop (https://web.dev/aspect-ratio/) but used internally to calculate the padding hack value. -
A media ID.
So theImage
component can accessstate.source.media[id]
and get thewidth
andheight
from there.
This is just an example. I am not a CSS expert by any means and less with this image size sorcery, so maybe I am wrong in my assumptions.
EDIT: This seems like a great resource to learn how to calculate the padding hack using an aspect ratio input: Aspect Ratio Boxes | CSS-Tricks
Can we use this one code for ACF fields in image . because i have passed id value but i didnāt get attachment data from state.source.attachment[id]
API.