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

Error: Missing sizes attribute on eleventy-img shortcode #107

Closed
noelforte opened this issue Jul 3, 2021 · 12 comments
Closed

Error: Missing sizes attribute on eleventy-img shortcode #107

noelforte opened this issue Jul 3, 2021 · 12 comments
Milestone

Comments

@noelforte
Copy link

Followed along with the documentation at https://www.11ty.dev/docs/plugins/image/ and attempted to implement this code below:

const Image = require("@11ty/eleventy-img");

async function imageShortcode(src, alt, sizes) {
  let metadata = await Image(src, {
    widths: [300, 600],
    formats: ["avif", "jpeg"]
  });

  let imageAttributes = {
    alt,
    sizes,
    loading: "lazy",
    decoding: "async",
  };

  // You bet we throw an error on missing alt in `imageAttributes` (alt="" works okay)
  return Image.generateHTML(metadata, imageAttributes);
}

module.exports = function(eleventyConfig) {
  eleventyConfig.addNunjucksAsyncShortcode("image", imageShortcode);
  eleventyConfig.addLiquidShortcode("image", imageShortcode);
  eleventyConfig.addJavaScriptFunction("image", imageShortcode);
};

However, when a build is run I get the following error in my terminal:

> Error with Nunjucks shortcode `image`

`EleventyShortcodeError` was thrown
> Missing `sizes` attribute on eleventy-img shortcode from: /img/3915eb99-300.jpeg

I suspect this is related to #59 and #60, but is sizes required? It doesn't seem possible to use the plugin without passing a sizes attribute to the shortcode, making this code in the docs invalid:

{% image "./src/images/cat.jpg", "photo of my cat" %} <!-- Doesn't work, throws an error. -->
{% image "./src/images/cat.jpg", "photo of my cat", "(min-width: 30em) 50vw, 100vw" %} <!-- works as intended -->

Is this a bug? Or is this behavior intentional?

@noelforte
Copy link
Author

Follow-up: just took a look at https://github.com/11ty/eleventy-img/blob/master/generate-html.js#L69 to see what I could find and caught the comment left there. If I'm using multiple formats I'll be sure to add in sizes rules.

@nhoizey
Copy link

nhoizey commented Jul 4, 2021

The comment is wrong, sizes is required when there's a srcset, whatever the number of sources in it.

@noelforte
Copy link
Author

Got it. Thanks for the clarification!

@zachleat
Copy link
Member

Of course @nhoizey is right, I’ve updated the comments to reflect the spec:

// Per the HTML specification sizes is required srcset is using the `w` unit
// https://html.spec.whatwg.org/dev/semantics.html#the-link-element:attr-link-imagesrcset-4

Just for final clarity, we only add srcset when creating more than one output width, so sizes is required when widths has more than one unique value smaller than the input image width.

Thanks y’all!

@zachleat zachleat added this to the v1.1.0 milestone Feb 23, 2022
@wommy
Copy link

wommy commented Feb 25, 2022

just to make sure we're all referencing the same thing,
the href for the blockquote that follows


The imagesrcset attribute may be present, and is a srcset attribute.

The imagesrcset and href attributes (if width descriptors are not used) together contribute the image sources to the source set.

If the imagesrcset attribute is present and has any image candidate strings using a width descriptor, the imagesizes attribute must also be present, and is a sizes attribute. The imagesizes attribute contributes the source size to the source set.

The imagesrcset and imagesizes attributes must only be specified on link elements that have both a rel attribute that specifies the preload keyword, as well as an as attribute in the "image" state.

These attributes allow preloading the appropriate resource that is later used by an img element that has the corresponding values for its srcset and sizes attributes:

<link rel="preload" as="image"
      imagesrcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w"
      imagesizes="50vw">

<!-- ... later, or perhaps inserted dynamically ... -->
<img src="wolf.jpg" alt="A rad wolf"
     srcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w"
     sizes="50vw">

Note how we omit the href attribute, as it would only be relevant for browsers that do not support imagesrcset, and in those cases it would likely cause the incorrect image to be preloaded.

The imagesrcset attribute can be combined with the media attribute to preload the appropriate resource selected from a picture element's sources, for art direction:

<link rel="preload" as="image"
      imagesrcset="dog-cropped-1x.jpg, dog-cropped-2x.jpg 2x"
      media="(max-width: 800px)">
<link rel="preload" as="image"
      imagesrcset="dog-wide-1x.jpg, dog-wide-2x.jpg 2x"
      media="(min-width: 801px)">

<!-- ... later, or perhaps inserted dynamically ... -->
<picture>
  <source srcset="dog-cropped-1x.jpg, dog-cropped-2x.jpg 2x"
          media="(max-width: 800px)">
  <img src="dog-wide-1x.jpg" srcset="dog-wide-2x.jpg 2x"
       alt="An awesome dog">
</picture>

The sizes attribute gives the sizes of icons for visual media. Its value, if present, is merely advisory. If specified, the attribute must have a value that is an unordered set of unique space-separated tokens which are ASCII case-insensitive. Each value must be either an ASCII case-insensitive match for the string "any", or a value that consists of two valid non-negative integers that do not have a leading U+0030 DIGIT ZERO (0) character and that are separated by a single U+0078 LATIN SMALL LETTER X or U+0058 LATIN CAPITAL LETTER X character. The attribute must only be specified on link elements that have a rel attribute that specifies the icon keyword or the apple-touch-icon keyword.

The apple-touch-icon keyword is a registered extension to the predefined set of link types, but user agents are not required to support it in any way.

The as attribute specifies the potential destination for a preload request for the resource given by the href attribute. It is an enumerated attribute. Each potential destination is a keyword for this attribute, mapping to a state of the same name. The attribute must be specified on link elements that have a rel attribute that contains the preload keyword. It may be specified on link elements that have a rel attribute that contains the modulepreload keyword; in such cases it must have a value which is a script-like destination. For other link elements, it must not be specified.

The attribute does not have a missing value default or invalid value default, meaning that invalid or missing values for the attribute map to no state. This is accounted for in the processing model. For preload links, both conditions are an error; for modulepreload links, a missing value will be treated as "script".

@wommy
Copy link

wommy commented Feb 25, 2022

am i crazy or is the first <p> is it formatted incorrectly? i just copied and pasted it

The imagesrcset attribute may be present, and is a srcset attribute.

vs on source

The imagesrcset attribute may be present, and is a srcset attribute.

@wommy
Copy link

wommy commented Feb 25, 2022

@wommy
Copy link

wommy commented Feb 25, 2022

Of course @nhoizey is right, I’ve updated the comments to reflect the spec:

// Per the HTML specification sizes is required srcset is using the `w` unit
// https://html.spec.whatwg.org/dev/semantics.html#the-link-element:attr-link-imagesrcset-4

Just for final clarity, we only add srcset when creating more than one output width, so sizes is required when widths has more than one unique value smaller than the input image width.

Thanks y’all!

and it seems like sizes are only required when following a Viewport-based selection

If the srcset attribute has any image candidate strings using a width descriptor, the sizes attribute must also be present, and is a sizes attribute. The sizes attribute contributes the source size to the source set, if the source element is selected.

Source

some other highlights:

@nhoizey
Copy link

nhoizey commented Feb 25, 2022

sizes is indeed required for srcset-w but not even useful for srcset-x.

@wommy
Copy link

wommy commented Feb 25, 2022

it seems like descriptors,width and pixel density, are the second argument of image candidate strings, which satisfy srcset

learning alot today,

i still think the generated picture can be optimized further

@zachleat
Copy link
Member

i still think the generated picture can be optimized further

@wommy Feel free to open another issue with suggestions!

@wommy
Copy link

wommy commented Feb 26, 2022

yeah i definitely will whenever i get the time <3 thanks for all your hard work fellas

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

4 participants