Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Images should always provide dimensions #23244

Open
felixarntz opened this issue Jun 17, 2020 · 10 comments
Open

Images should always provide dimensions #23244

felixarntz opened this issue Jun 17, 2020 · 10 comments

Comments

@felixarntz
Copy link
Member

felixarntz commented Jun 17, 2020

Background

In order for the browser to set up a webpage's layout it's important that images have their dimension attributes width and height provided, as this will inform the browser of the effective aspect ratio of the image before it is even loaded. Without these attributes provided, the page layout will reflow once the image has loaded, causing so-called "layout shift" which is harmful for user experience (think about the experience where you want to click on something but just as you're about to do so the page content moves and you accidentally click on something else). These layout shifts always happen - the experience is worse on a slow network connection, but they are visible pretty much no matter how fast the connection is.

Historically the classic editor has always provided these attributes, but that was changed in Gutenberg, where now the majority of images is without width and height. This issue seeks to address this to reduce the cumulative layout shift across WordPress sites for content generated with Gutenberg. I've been working on a closely related core issue (feel free to chime in there as well!) that addresses this in a more "patch-y" way that will retroactively work, but we should address this in Gutenberg too to get the proper experience in the editor itself as well.

See the difference in experience here, based on the above core patch:
Before:
before the patch
After:
after the patch

The main question we should discuss and answer first is: Why was it initially decided to omit width and height attributes?

Goal

The following blocks should always provide width and height on img elements, regardless of whether the user provided a custom size or not:

  • core/image
  • core/gallery
  • core/media-text
  • (did I miss any?)

Related

@oxyc
Copy link
Member

oxyc commented Jun 17, 2020

Not sure about historical reasons but an idea to avoid the layout shift even if images are shown as max-width: 100% is using aspect ratio boxes.

<!-- (width / height) set by block based on image natrual size -->
<figure class="wp-block-image size-large" style="--aspect-ratio: 810/540;">
  <img src="">
</figure>
.wp-block-image:not(.is-resized) {
  &[style*="--aspect-ratio"] img {
    width: 100%;
    height: auto;
  }
  
  @supports (--custom:property) {
    &[style*="--aspect-ratio"] {
      position: relative;
    }

    &[style*="--aspect-ratio"]::before {
      content: "";
      display: block;
      padding-bottom: calc(100% / (var(--aspect-ratio)));
    }  

    &[style*="--aspect-ratio"] img {
      position: absolute;
      top: 0;
      left: 0;
      height: 100%;
    }  
  }
}

@adamsilverstein
Copy link
Member

adamsilverstein commented Jun 17, 2020

even if images are shown as max-width: 100%

@oxyc - Can you explain the advantage/reason for showing images as max-width: 100%? Does tagging the image with width and height negate them?

@oxyc
Copy link
Member

oxyc commented Jun 18, 2020

This confused me because specifying width and height actually did fix the layout shifting for responsive images. It did not use to do this until recently: https://chromestatus.com/feature/5695266130755584

So aspect ratio boxes (what I gave an example of in my previous comment) are a thing of the past for images and what this issue proposes makes a significant improvement by eliminating layout shift.

Can you explain the advantage/reason for showing images as max-width: 100%?

Basically it's used to ensure an image doesnt grow larger than it's container, even if the image is larger.

Does tagging the image with width and height negate them?

No, but up until recently the attributes didn't actually matter together with max-width: 100%. Now it seems browsers have shipped an internal style which leverages width/height properties to know the image aspect ratio before it has loaded:

img, video {
    aspect-ratio: attr(width) / attr(height);
} 

WICG/intrinsicsize-attribute#16 (comment) explains it and at the end of the threads it has a video that demos and explain it as well.

Available since Chrome 79, Firefox 71, Safari Tech Preview

@felixarntz
Copy link
Member Author

felixarntz commented Jun 18, 2020

No, but up until recently the attributes didn't actually matter together with max-width: 100%. Now it seems browsers have shipped an internal style which leverages width/height properties to know the image aspect ratio before it has loaded:

That's a good point. It should be fair to say though that having the dimension attributes present would not have resulted in a negative effect in that case either. For cases where e.g. an image would be left- or right-aligned beside some text, having the attributes has already been a key for reducing layout shifts much longer.

Another reason the dimension attributes on the img are crucial to reduce layout shifts is the following example: If you set an image to width:100%;height:auto, it will be displayed like that regardless of whether or not width and height attributes are present. However, without the attributes you'd get the layout shift because the browser wouldn't know the aspect ratio of the image right away.

I guess my main question at this point is: Is there any actual downside from including width and height that I may be missing?

@azaozz
Copy link
Contributor

azaozz commented Jun 27, 2020

Is there any actual downside from including width and height...

Don't think so. Having width and height in the img tag has been best practice since... late 90's? :) Seems that knowing the (intrinsic) size of images as soon as the HTML is loaded helps modern browsers too.

If you set an image to width:100%;height:auto...

Yes, as far as I've seen most images are styled with either width: 100% or max-width: 100% which makes having the width and height attributes really important.

@oxyc
Copy link
Member

oxyc commented Aug 6, 2020

Here's an earlier issue regarding this as well #6652

@dotsam
Copy link

dotsam commented Aug 26, 2020

I don't know if this should be a new issue, but with core adopting its patch to always add image width/height as of 5.5, the Block Library style for alignfull and alignwide is breaking image aspect ratios, as it overrides the image width, but does not set height: auto

&.alignfull img,
&.alignwide img {
width: 100%;
}

@sabernhardt
Copy link
Contributor

sabernhardt commented Sep 4, 2020

I think the images do need height: auto in the front-end block styles, but not only the images in alignfull and alignwide blocks.

Except when overridden, the editor scales images inside the .block-editor__container element. Then on the front-end, the height does not adjust accordingly with the max-width.

Editor (.block-editor__container img):

img {
max-width: 100%;
height: auto;
}

Front-end image block:

.wp-block-image {
// The image block is in a `figure` element, and many themes zero this out.
// This rule explicitly sets it, to ensure at least some bottom-margin in the flow.
margin-bottom: 1em;
img {
max-width: 100%;
}

@adamsilverstein
Copy link
Member

adamsilverstein commented Feb 8, 2021

@felixarntz Can you confirm this would still be an improvement, even though we added automattic image width/height markup in 5.5? I'm thinking that if Gutenberg inserted the width/height, core would respect that, so it would be potentially more accurate or customizable by the user.

@thpglobal
Copy link

thpglobal commented Feb 10, 2021

I've had to avoid using the image block because images stop being responsive. I agree with @felixarntz that the "right" default for images is width=100% and height=auto. Otherwise I get distorted pictures. At the moment it seems to fill in the actual image size and then distorts it. One dimension or the the other always needs to be auto.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants