Skip to content

Commit

Permalink
Force size containment for auto-sizes
Browse files Browse the repository at this point in the history
The 'concrete object size ignoring natural dimensions' concept was not implementable. This change makes `sizes=auto` required on `img` to use auto-sizes (still optional on `source`)
and forces size containment so that the image size is the same before and after an image has loaded, to prevent double downloads.

Fixes #9448, fixes #9648, and fixes #9649.
  • Loading branch information
zcorpan committed Nov 30, 2023
1 parent 4aac34e commit 193c67d
Showing 1 changed file with 77 additions and 63 deletions.
140 changes: 77 additions & 63 deletions source
Expand Up @@ -28570,12 +28570,16 @@ interface <dfn interface>HTMLSourceElement</dfn> : <span>HTMLElement</span> {
<p>If the <code data-x="attr-source-srcset">srcset</code> attribute has any <span data-x="image
candidate string">image candidate strings</span> using a <span>width descriptor</span>, the
<code data-x="attr-source-sizes">sizes</code> attribute may also be present. If, additionally,
the following sibling <code>img</code> element's <code data-x="attr-img-loading">loading</code>
attribute is in the <span data-x="attr-loading-eager-state">Eager</span> state, the <code
data-x="attr-source-sizes">sizes</code> attribute must be present. The <dfn element-attr
for="source" data-x="attr-source-sizes"><code>sizes</code></dfn> attribute is a <span>sizes
attribute</span>, which contributes the <span>source size</span> to the <span>source set</span>,
if the <code>source</code> element is selected.</p>
the following sibling <code>img</code> element does not <span data-x="allows auto-sizes">allow
auto-sizes</span>, the <code data-x="attr-source-sizes">sizes</code> attribute must be present.
The <dfn element-attr for="source" data-x="attr-source-sizes"><code>sizes</code></dfn>
attribute is a <span>sizes attribute</span>, which contributes the <span>source size</span> to
the <span>source set</span>, if the <code>source</code> element is selected.</p>

<p class="note">If the <code>img</code> element <span>allows auto-sizes</span>, then the <code
data-x="attr-source-sizes">sizes</code> attribute can be omitted on previous sibling
<code>source</code> elements. In such cases, it is equivalent to specifying <code
data-x="valdef-sizes-auto">auto</code>.</p>

<p>The <code>source</code> element supports <span>dimension attributes</span>. The
<code>img</code> element can use the <code data-x="attr-dim-width">width</code> and <code
Expand Down Expand Up @@ -28907,18 +28911,26 @@ interface <dfn interface>HTMLImageElement</dfn> : <span>HTMLElement</span> {

<p>If the <code data-x="attr-img-srcset">srcset</code> attribute is present and has any <span
data-x="image candidate string">image candidate strings</span> using a <span>width
descriptor</span>, the <code data-x="attr-img-sizes">sizes</code> attribute may also be present.
If, additionally, the <code data-x="attr-img-loading">loading</code> attribute is in the <span
data-x="attr-loading-eager-state">Eager</span> state, the <code
data-x="attr-img-sizes">sizes</code> attribute must be present. The <dfn element-attr for="img"
descriptor</span>, the <code data-x="attr-img-sizes">sizes</code> attribute must also be present.
If the <code data-x="attr-img-srcset">srcset</code> attribute is <em>not</em> specified, and the
<code data-x="attr-img-loading">loading</code> attribute is in the <span
data-x="attr-loading-lazy-state">Lazy</span> state, the <code
data-x="attr-img-sizes">sizes</code> attribute may be specified with the value "<code
data-x="">auto</code>" (<span>ASCII case-insensitive</span>). The <dfn element-attr for="img"
data-x="attr-img-sizes"><code>sizes</code></dfn> attribute is a <span>sizes attribute</span>,
which contributes the <span>source size</span> to the <span>source set</span> (if no
<code>source</code> element was selected).</p>

<p class="note">When the <code data-x="attr-img-loading">loading</code> attribute is in the <span
data-x="attr-loading-lazy-state">Lazy</span> state, the <code
data-x="attr-img-sizes">sizes</code> attribute can be omitted, which is equivalent to <code
data-x="valdef-sizes-auto">sizes="auto"</code>.</p>
<p>An <code>img</code> element <dfn>allows auto-sizes</dfn> if:</p>

<ul>
<li>its <code data-x="attr-img-loading">loading</code> attribute is in the <span
data-x="attr-loading-lazy-state">Lazy</span> state, and</li>

<li>its <code data-x="attr-img-sizes">sizes</code> attribute's value is "<code
data-x="">auto</code>" (<span>ASCII case-insensitive</span>), or starts with "<code
data-x="">auto,</code>" (<span>ASCII case-insensitive</span>).</li>
</ul>

<p>The <dfn element-attr for="img" data-x="attr-img-crossorigin"><code>crossorigin</code></dfn>
attribute is a <span>CORS settings attribute</span>. Its purpose is to allow images from
Expand Down Expand Up @@ -29986,9 +29998,8 @@ was an English &lt;a href="/wiki/Music_hall">music hall&lt;/a> singer, ...</code
<p>This example is the same as the previous example, but the image is <span
data-x="attr-loading-lazy-state">lazy-loaded</span>. In this case, the <code
data-x="attr-img-sizes">sizes</code> attribute can use the <code
data-x="valdef-sizes-auto">auto</code> keyword (or the <code
data-x="attr-img-sizes">sizes</code> attribute can be omitted), and the user agent will use the
<code data-x="attr-dim-width">width</code> attribute (or the width specified in CSS) for the
data-x="valdef-sizes-auto">auto</code> keyword, and the user agent will use the <code
data-x="attr-dim-width">width</code> attribute (or the width specified in CSS) for the
<span>source size</span>.</p>

<pre><code class="html">&lt;img <strong>loading="lazy" width="200" height="200" sizes="auto"</strong>
Expand Down Expand Up @@ -30276,24 +30287,17 @@ was an English &lt;a href="/wiki/Music_hall">music hall&lt;/a> singer, ...</code
and must not use CSS functions other than the <span>math functions</span>.</p>

<p>The keyword <dfn><code data-x="valdef-sizes-auto">auto</code></dfn> is a width that is
computed in <span>parse a sizes attribute</span>.</p>
computed in <span>parse a sizes attribute</span>. If present, it must be the first entry and the
entire <span>&lt;source-size-list></span> value must either be the string "<code
data-x="">auto</code>" (<span>ASCII case-insensitive</span>) or start with the string "<code
data-x="">auto,</code>" (<span>ASCII case-insensitive</span>).</p>

<p class="note">If the <code>img</code> element that initiated the image loading (with the
<span>update the image data</span> or <span data-x="img-environment-changes">react to environment
changes</span> algorithms) is <span>being rendered</span>, and its <code
data-x="attr-img-loading">loading</code> attribute is in the <span
data-x="attr-loading-lazy-state">Lazy</span> state, and its <span>concrete object size ignoring
natural dimensions</span> width is not zero, then <code data-x="valdef-sizes-auto">auto</code> is
the <span>concrete object size ignoring natural dimensions</span> width. Otherwise, <code
data-x="valdef-sizes-auto">auto</code> is <code data-x="">100vw</code>.</p>

<p>The <dfn export>concrete object size ignoring natural dimensions</dfn> of an element is its
<span>concrete object size</span> but acting as if there are no <span>natural dimensions</span>,
thus producing a rectangle with an absolute width and height. <ref>CSSIMAGES</ref></p>

<p class="note">The <span>concrete object size ignoring natural dimensions</span> of an
<code>img</code> element will match the <span>concrete object size</span> before an image has
loaded.</p>
changes</span> algorithms) <span>allows auto-sizes</span> and is <span>being rendered</span>,
then <code data-x="valdef-sizes-auto">auto</code> is the <span>concrete object size</span> width.
Otherwise, the <code data-x="valdef-sizes-auto">auto</code> value is ignored and the next
<span>source size</span> is used instead, if any.</p>

<p>The <code data-x="valdef-sizes-auto">auto</code> keyword may be specified in the <code
data-x="attr-source-sizes">sizes</code> attribute of <code>source</code> elements and <code
Expand All @@ -30307,15 +30311,15 @@ was an English &lt;a href="/wiki/Music_hall">music hall&lt;/a> singer, ...</code

<li><p>The element is an <code>img</code> element.</p></li>

<li><p>The <code>img</code> element referenced in either condition above has a <code
data-x="attr-img-loading">loading</code> attribute which is in the <span
data-x="attr-loading-lazy-state">Lazy</span> state.</p></li>
<li><p>The <code>img</code> element referenced in either condition above <span>allows
auto-sizes</span>.</p></li>
</ul>

<p class="note">In addition, it is strongly encouraged to specify dimensions using the <code
data-x="attr-dim-width">width</code> and <code data-x="attr-dim-height">height</code> attributes
or with CSS. Without a specified width, the <code data-x="valdef-sizes-auto">auto</code> keyword
is equivalent to <code data-x="">100vw</code>.</p>
or with CSS. Without specified dimensions, the image will likely render with 300x150 dimensions
because <code data-x="">sizes="auto"</code> implies <code data-x="">contain-intrinsic-size: 300px
150px</code> in <a href="#img-contain-size">the Rendering section</a>.</p>

<p>The <span>&lt;source-size-value></span> gives the intended layout width of the image. The
author can specify different widths for different environments with
Expand Down Expand Up @@ -30529,14 +30533,9 @@ was an English &lt;a href="/wiki/Music_hall">music hall&lt;/a> singer, ...</code

<li><p>The element's <span data-x="concept-node-adopt-ext">adopting steps</span> are run.</p></li>

<li><p>If the element's <code data-x="attr-img-loading">loading</code> attribute is in the <span
data-x="attr-loading-lazy-state">Lazy</span> state, and either the element has a <code
data-x="attr-img-srcset">srcset</code> attribute with a <span>width descriptor</span> or the
element's parent is a <code>picture</code> element and a previous sibling <code>source</code>
element that has a <code data-x="attr-source-srcset">srcset</code> attribute with a <span>width
descriptor</span>: the element starts or stops <span>being rendered</span>, or its <span>concrete
object size ignoring natural dimensions</span> width changes. This must set the <i>maybe omit
events</i> flag for the <span>update the image data</span> algorithm.</p></li>
<li><p>If the element <span>allows auto-sizes</span>: the element starts or stops <span>being
rendered</span>, or its <span>concrete object size</span> width changes. This must set the
<i>maybe omit events</i> flag for the <span>update the image data</span> algorithm.</p></li>

<!-- NOT when the base URL changes (except for when adopted into a new doc) -->

Expand Down Expand Up @@ -31640,13 +31639,28 @@ was an English &lt;a href="/wiki/Music_hall">music hall&lt;/a> singer, ...</code
Otherwise, there is a <span data-x="concept-microsyntax-parse-error">parse error</span>;
<span>continue</span>.</p></li>

<li><p>Remove all consecutive <span>&lt;whitespace-token></span>s
from the end of <var>unparsed size</var>.
If <var>unparsed size</var> is now empty,
then return <var>size</var>.
If this was not the keyword <code data-x="valdef-sizes-auto">auto</code> and
it was not the last item in <var>unparsed sizes list</var>,
that is a <span data-x="concept-microsyntax-parse-error">parse error</span>.</p></li>
<li>
<p>If <var>size</var> is <code data-x="valdef-sizes-auto">auto</code>, and <var>img</var>
is not null, and <var>img</var> is <span>being rendered</span>, and <var>img</var>
<span>allows auto-sizes</span>, then set <var>size</var> to the <span>concrete object
size</span> width of <var>img</var>, in <span data-x="'px'">CSS pixels</span>.</p>

<p class="note">If <var>size</var> is still <code data-x="valdef-sizes-auto">auto</code>,
then it will be ignored.</p>
</li>

<li>
<p>Remove all consecutive <span>&lt;whitespace-token></span>s from the end of <var>unparsed
size</var>. If <var>unparsed size</var> is now empty:</p>

<ol>
<li><p>If this was not the last item in <var>unparsed sizes list</var>, that is a <span
data-x="concept-microsyntax-parse-error">parse error</span>.</p></li>

<li><p>If <var>size</var> is not <code data-x="valdef-sizes-auto">auto</code>, then return
<var>size</var>. Otherwise, continue.</p></li>
</ol>
</li>

<li><p>Parse the remaining <span data-x="component value">component values</span> in <var>unparsed size</var>
as a <span>&lt;media-condition></span>.
Expand All @@ -31655,20 +31669,11 @@ was an English &lt;a href="/wiki/Music_hall">music hall&lt;/a> singer, ...</code
<span>continue</span>. <ref>MQ</ref></p></li>

<li><p>If <var>size</var> is not <code data-x="valdef-sizes-auto">auto</code>, then return
<var>size</var>.</p></li>
<var>size</var>. Otherwise, continue.</p></li>
</ol>
</li>

<li><p>Assert: <var>size</var> is null or <code data-x="valdef-sizes-auto">auto</code>.</p></li>

<li><p>If <var>img</var> is null, or <var>img</var>'s <code
data-x="attr-img-loading">loading</code> attribute is not in the <span
data-x="attr-loading-lazy-state">Lazy</span> state, or <var>img</var> is not <span>being
rendered</span>, or <var>img</var>'s <span>concrete object size ignoring natural
dimensions</span> width is zero, then return <code data-x="">100vw</code>.</p></li>

<li><p>Return the <span>concrete object size ignoring natural dimensions</span> width of
<var>img</var>, in <span data-x="'px'">CSS pixels</span>.</p></li>
<li><p>Return <code data-x="">100vw</code>.</p></li>
</ol>

<p class="note">It is invalid to use a bare <span>&lt;source-size-value></span> that is a <span>&lt;length></span>
Expand Down Expand Up @@ -131753,6 +131758,15 @@ iframe { border: 2px inset; }

<hr>

<p>The following CSS rules are expected to apply:</p>

<pre><code class="css">@namespace "http://www.w3.org/1999/xhtml";

<span id="img-contain-size">img:is([sizes="auto" i], [sizes^="auto," i]) {
contain: size !important;
contain-intrinsic-size: 300px 150px;
}</span></code></pre>

<p>The following CSS rules are expected to apply when the <code>Document</code> is in <span>quirks
mode</span>:</p>

Expand Down

0 comments on commit 193c67d

Please sign in to comment.