-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Add width and height attributes to source elements #5894
Add width and height attributes to source elements #5894
Conversation
Yay! 😄 I think the resource selection shouldn't "set an attribute value" on the img. Apart from invoking mutation observers, it also breaks markup that uses width and height on the img when the environment changes and it gets selected:
If A is first selected, the Another detail to consider is when you want the dimension swap to happen. Should it happen when MQ changes (in the render step of the event loop), or when the new image is fully loaded? (For |
What would be a better way to set those values on the img element? Change "if img's width and height attribute values" to take other values hanging off the element and modify those? Something else?
We definitely want this at MQ time, as the main goal here is to avoid layout shifts, by declaring the aspect ratio ahead of time. |
@yoavweiss well so how dynamic should it be? If you update the Then the interesting bit are the |
The main use-case for which I think we care about this is the intrinsic aspect ratio calculations that I linked to above. |
Sounds good to me |
@zcorpan - PTAL? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apart from the aspect ratio, I think this should also update the Rendering section's mapping of the width and height attributes to the width and height properties (to use the "aspect ratio source"). Otherwise it will still use the img
's width and height attributes to set the dimensions (without author CSS).
https://html.spec.whatwg.org/multipage/#attributes-for-embedded-content-and-images
Is it okay if the https://html.spec.whatwg.org/multipage/embedded-content-other.html#dimension-attributes
|
@mtrootyy it should be in there, but with the condition: when the parent is a |
Comments addressed. PTAL? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting there
So I thought about a problem here. What happens if you remove the aspect ratio source It will be a "relevant mutation", which will invoke "update the image data". But that algorithm waits a microtask before invoking "selecting an image source". So before that happens, aspect ratio source points to a removed element. Maybe it's ok? If aspect ratio source is a strong reference, the |
source
Outdated
data-x="attr-input-type-image">Image Button</span> state and that either represents an image or | ||
that the user expects will eventually represent an image, <span data-x="maps to the dimension | ||
property">map to the dimension properties</span> <span>'width'</span> and <span>'height'</span> | ||
on the element respectively.</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not quite sure this makes sense (or at least I don't think we have a precedent for this). This is saying that for:
<picture>
<source srcset="bar.png" width="100" height="100">
<img width="200" height="200">
</picture>
Something like getComputedStyle(img).width
should be 100px
, right? While I think this is the behavior you want, I'm not clear in how to accomplish it with the usual attribute mapping primitives.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. I think it's indeed new. But the mapping for 'aspect-ratio' would need this primitive as well, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For <source>
yeah... with this patch, you also want to map to aspect-ratio
somehow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "intrinsic aspect ratio" bit does that, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is not technically defined in terms of attribute mapping (and Chrome doesn't implement it that way, though Gecko does), that's why I didn't bring it up.
The reason for that is that when we initially added that section to the spec, we didn't have the CSS value we needed to map into. That value was added later, and we should update the spec to define it maps to aspect-ratio: <width> / <height> auto
instead of changing the definition of "intrinsic aspect ratio".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha. Right. That does seem like a separate issue though. Can you file an issue?
0a84780
to
cd685f5
Compare
That seems fine to me, but if that's not desired, maybe we could add a check to see that |
Yeah I think it's fine. I just figured it's something that could crash if the UA doesn't hold a strong reference, and you force a reflow or something while aspect ratio source points to the removed element. |
So... how will this interact with the mapping of width/height to CSS that we now do? |
@cbiesinger - as far as I can tell, https://github.com/whatwg/html/pull/6032/files and this PR can peacefully co-exist :) Doesn't seem to me like they are conflicting in any way. |
source
Outdated
<p>The <code data-x="attr-dim-width">width</code> and <code | ||
data-x="attr-dim-height">height</code> attributes may also be present. If present, their | ||
values must contain valid lengths. The user agent will use these values to calculate the | ||
<span>intrinsic aspect ratio</span> as well as the <span>intrinsic dimensions</span> of a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a sidenote, setting this as the intrinsic ratio means this won't be used when contain:size is used (by definition, size containment ignores intrinsic size of images)
source
Outdated
<p>The <code data-x="attr-dim-width">width</code> and <code | ||
data-x="attr-dim-height">height</code> attributes may also be present. If present, their | ||
values must contain valid lengths. The user agent will use these values to calculate the | ||
<span>intrinsic aspect ratio</span> as well as the <span>intrinsic dimensions</span> of a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I believe this text as written means that these attributes will override the actual dimensions of the image (once loaded); this is different from the behavior for img's attributes. Is that intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this sentence uses the word "will" and not "must", it's a non-normative statement of fact and has no effect. The part about intrinsic dimensions (now named natural dimensions) I think is incorrect; the width and height attributes map to the 'width' and 'height' properties, which are the specified size, not natural dimensions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Corrected
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this refers to DOM properties? But an img's width/height properties also map to the attribute as well as the CSS width/height property... I don't even know how to implement this in a reasonable way...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mfreed7 in case he has input on that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, not the DOM properties. I think this sentence might be confusing matters, as it's not trying to require anything, but instead helpfully describing what purpose or effect the width
and height
attributes have. As an implementer, you can ignore non-normative statements completely. The normative part is in the Rendering section: https://whatpr.org/html/5894/16667c3...d10ef5c/rendering.html#attributes-for-embedded-content-and-images:attr-dim-width
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, I also clarified the sentence, based on @zcorpan's feedback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, thanks for clarifying that.
I've put tests for this PR into web-platform-tests/wpt#27745, please review! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This LGTM. I'll give folks another day or two before we merge?
To complete the checklist here: Implementation bugs: Tests: |
@cbiesinger - Thanks! Updated the checklist up top |
[It's best practice to specify width and height on images][1], even if they are fluid, to help avoid layout shift. It tells the browser the expected size before it loads any image data, and an aspect ratio is derived from it so the browser can still know the image size even if CSS or something else is altering the image's width from its intrinsic one. Before this patch, there was not a way to allow width and height attributes to get through to the `img` element sent to the browser when using the react-imgix component while leaving the image fluid width (that is, with a srcset containing width descriptors). As soon as one specified width and height, react-imgix assumed the author wanted a fixed-width image, and it gave resolution descriptors in the srcset instead of width descriptors (and then the sizes attribute was ignored by the browser, [as per spec][2]). Imgix currently uses the width and height attributes to decide whether to use width or resolution descriptors, so to avoid altering that logic (which would be a breaking change), this patch allows width and height to be passed through the `htmlAttributes` prop. Prior to the patch they were swallowed if given in `htmlAttributes`. As of this patch they are allowed and passed through. This closes imgix#891 In future it may make sense to decide srcset type based on the presence of the `sizes` attribute, as discussed in the above ticket. This would be a breaking change, however. As part of this patch, width and height are also allowed through when using this component in `Source` mode, since [width and height attributes are now allowed and encouraged in that context][3]. [1]: https://web.dev/optimize-cls/ [2]: https://html.spec.whatwg.org/multipage/images.html#srcset-attributes [3]: whatwg/html#5894
[It's best practice to specify width and height on images][1], even if they are fluid, to help avoid layout shift. It tells the browser the expected size before it loads any image data, and an aspect ratio is derived from it so the browser can still know the image size even if CSS or something else is altering the image's width from its intrinsic one. Before this patch, there was not a way to allow width and height attributes to get through to the `img` element sent to the browser when using the react-imgix component while leaving the image fluid width (that is, with a srcset containing width descriptors). As soon as one specified width and height, react-imgix assumed the author wanted a fixed-width image, and it gave resolution descriptors in the srcset instead of width descriptors (and then the sizes attribute was ignored by the browser, [as per spec][2]). Imgix currently uses the width and height attributes to decide whether to use width or resolution descriptors, so to avoid altering that logic (which would be a breaking change), this patch allows width and height to be passed through the `htmlAttributes` prop. Prior to the patch they were swallowed if given in `htmlAttributes`. As of this patch they are allowed and passed through. This closes imgix#891 In future it may make sense to decide srcset type based on the presence of the `sizes` attribute, as discussed in the above ticket. This would be a breaking change, however. As part of this patch, width and height are also allowed through when using this component in `Source` mode, since [width and height attributes are now allowed and encouraged in that context][3]. [1]: https://web.dev/optimize-cls/ [2]: https://html.spec.whatwg.org/multipage/images.html#srcset-attributes [3]: whatwg/html#5894
[It's best practice to specify width and height on images][1], even if they are fluid, to help avoid layout shift. It tells the browser the expected size before it loads any image data, and an aspect ratio is derived from it so the browser can still know the image size even if CSS or something else is altering the image's width from its intrinsic one. Before this patch, there was not a way to allow width and height attributes to get through to the `img` element sent to the browser when using the react-imgix component while leaving the image fluid width (that is, with a srcset containing width descriptors). As soon as one specified width and height, react-imgix assumed the author wanted a fixed-width image, and it gave resolution descriptors in the srcset instead of width descriptors (and then the sizes attribute was ignored by the browser, [as per spec][2]). Imgix currently uses the width and height attributes to decide whether to use width or resolution descriptors, so to avoid altering that logic (which would be a breaking change), this patch allows width and height to be passed through the `htmlAttributes` prop. Prior to the patch they were swallowed if given in `htmlAttributes`. As of this patch they are allowed and passed through. This closes imgix#891 In future it may make sense to decide srcset type based on the presence of the `sizes` attribute, as discussed in the above ticket. This would be a breaking change, however. As part of this patch, width and height are also allowed through when using this component in `Source` mode, since [width and height attributes are now allowed and encouraged in that context][3]. [1]: https://web.dev/optimize-cls/ [2]: https://html.spec.whatwg.org/multipage/images.html#srcset-attributes [3]: whatwg/html#5894
[It's best practice to specify width and height on images][1], even if they are fluid, to help avoid layout shift. It tells the browser the expected size before it loads any image data, and an aspect ratio is derived from it so the browser can still know the image size even if CSS or something else is altering the image's width from its intrinsic one. Before this patch, there was not a way to allow width and height attributes to get through to the `img` element sent to the browser when using the react-imgix component while leaving the image fluid width (that is, with a srcset containing width descriptors). As soon as one specified width and height, react-imgix assumed the author wanted a fixed-width image, and it gave resolution descriptors in the srcset instead of width descriptors (and then the sizes attribute was ignored by the browser, [as per spec][2]). Imgix currently uses the width and height attributes to decide whether to use width or resolution descriptors, so to avoid altering that logic (which would be a breaking change), this patch allows width and height to be passed through the `htmlAttributes` prop. Prior to the patch they were swallowed if given in `htmlAttributes`. As of this patch they are allowed and passed through. This closes imgix#891 In future it may make sense to decide srcset type based on the presence of the `sizes` attribute, as discussed in the above ticket. This would be a breaking change, however. As part of this patch, width and height are also allowed through when using this component in `Source` mode, since [width and height attributes are now allowed and encouraged in that context][3]. [1]: https://web.dev/optimize-cls/ [2]: https://html.spec.whatwg.org/multipage/images.html#srcset-attributes [3]: whatwg/html#5894
[It's best practice to specify width and height on images][1], even if they are fluid, to help avoid layout shift. It tells the browser the expected size before it loads any image data, and an aspect ratio is derived from it so the browser can still know the image size even if CSS or something else is altering the image's width from its intrinsic one. Before this patch, there was not a way to allow width and height attributes to get through to the `img` element sent to the browser when using the react-imgix component while leaving the image fluid width (that is, with a srcset containing width descriptors). As soon as one specified width and height, react-imgix assumed the author wanted a fixed-width image, and it gave resolution descriptors in the srcset instead of width descriptors (and then the sizes attribute was ignored by the browser, [as per spec][2]). Imgix currently uses the width and height attributes to decide whether to use width or resolution descriptors, so to avoid altering that logic (which would be a breaking change), this patch allows width and height to be passed through the `htmlAttributes` prop. Prior to the patch they were swallowed if given in `htmlAttributes`. As of this patch they are allowed and passed through. This closes imgix#891 In future it may make sense to decide srcset type based on the presence of the `sizes` attribute, as discussed in the above ticket. This would be a breaking change, however. As part of this patch, width and height are also allowed through when using this component in `Source` mode, since [width and height attributes are now allowed and encouraged in that context][3]. [1]: https://web.dev/optimize-cls/ [2]: https://html.spec.whatwg.org/multipage/images.html#srcset-attributes [3]: whatwg/html#5894
[It's best practice to specify width and height on images][1], even if they are fluid, to help avoid layout shift. It tells the browser the expected size before it loads any image data, and an aspect ratio is derived from it so the browser can still know the image size even if CSS or something else is altering the image's width from its intrinsic one. Before this patch, there was not a way to allow width and height attributes to get through to the `img` element sent to the browser when using the react-imgix component while leaving the image fluid width (that is, with a srcset containing width descriptors). As soon as one specified width and height, react-imgix assumed the author wanted a fixed-width image, and it gave resolution descriptors in the srcset instead of width descriptors (and then the sizes attribute was ignored by the browser, [as per spec][2]). Imgix currently uses the width and height attributes to decide whether to use width or resolution descriptors, so to avoid altering that logic (which would be a breaking change), this patch allows width and height to be passed through the `htmlAttributes` prop. Prior to the patch they were swallowed if given in `htmlAttributes`. As of this patch they are allowed and passed through. This closes imgix#891 In future it may make sense to decide srcset type based on the presence of the `sizes` attribute, as discussed in the above ticket. This would be a breaking change, however. As part of this patch, width and height are also allowed through when using this component in `Source` mode, since [width and height attributes are now allowed and encouraged in that context][3]. [1]: https://web.dev/optimize-cls/ [2]: https://html.spec.whatwg.org/multipage/images.html#srcset-attributes [3]: whatwg/html#5894
[It's best practice to specify width and height on images][1], even if they are fluid, to help avoid layout shift. It tells the browser the expected size before it loads any image data, and an aspect ratio is derived from it so the browser can still know the image size even if CSS or something else is altering the image's width from its intrinsic one. Before this patch, there was not a way to allow width and height attributes to get through to the `img` element sent to the browser when using the react-imgix component while leaving the image fluid width (that is, with a srcset containing width descriptors). As soon as one specified width and height, react-imgix assumed the author wanted a fixed-width image, and it gave resolution descriptors in the srcset instead of width descriptors (and then the sizes attribute was ignored by the browser, [as per spec][2]). Imgix currently uses the width and height attributes to decide whether to use width or resolution descriptors, so to avoid altering that logic (which would be a breaking change), this patch allows width and height to be passed through the `htmlAttributes` prop. Prior to the patch they were swallowed if given in `htmlAttributes`. As of this patch they are allowed and passed through. This closes imgix#891 In future it may make sense to decide srcset type based on the presence of the `sizes` attribute, as discussed in the above ticket. This would be a breaking change, however. As part of this patch, width and height are also allowed through when using this component in `Source` mode, since [width and height attributes are now allowed and encouraged in that context][3]. [1]: https://web.dev/optimize-cls/ [2]: https://html.spec.whatwg.org/multipage/images.html#srcset-attributes [3]: whatwg/html#5894
[It's best practice to specify width and height on images][1], even if they are fluid, to help avoid layout shift. It tells the browser the expected size before it loads any image data, and an aspect ratio is derived from it so the browser can still know the image size even if CSS or something else is altering the image's width from its intrinsic one. Before this patch, there was not a way to allow width and height attributes to get through to the `img` element sent to the browser when using the react-imgix component while leaving the image fluid width (that is, with a srcset containing width descriptors). As soon as one specified width and height, react-imgix assumed the author wanted a fixed-width image, and it gave resolution descriptors in the srcset instead of width descriptors (and then the sizes attribute was ignored by the browser, [as per spec][2]). Imgix currently uses the width and height attributes to decide whether to use width or resolution descriptors, so to avoid altering that logic (which would be a breaking change), this patch allows width and height to be passed through the `htmlAttributes` prop. Prior to the patch they were swallowed if given in `htmlAttributes`. As of this patch they are allowed and passed through. This closes #891 In future it may make sense to decide srcset type based on the presence of the `sizes` attribute, as discussed in the above ticket. This would be a breaking change, however. As part of this patch, width and height are also allowed through when using this component in `Source` mode, since [width and height attributes are now allowed and encouraged in that context][3]. [1]: https://web.dev/optimize-cls/ [2]: https://html.spec.whatwg.org/multipage/images.html#srcset-attributes [3]: whatwg/html#5894
This addresses #4968
I believe this has multi-implementer interest, based on #4968 (comment), but will let others comment to that effect.
This doesn't yet have tests, as I wanted to first verify the approach I took makes sense. I'll make sure tests are added before landing. Similarly, I'll make sure implementation bugs are opened.
/cc @zcorpan @annevk @domenic @chrishtr @emilio @jensimmons @cbiesinger
(See WHATWG Working Mode: Changes for more details.)
/embedded-content-other.html ( diff )
/embedded-content.html ( diff )
/images.html ( diff )
/indices.html ( diff )
/rendering.html ( diff )