question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support `<picture>` with multiple sources

See original GitHub issue

It seems the picture tag implementation in the nuxt/image package is lacking basic picture tag features.

The picture tag and its sources (who act like regular images - with srcset and sizes, but with the addition of the “media” attribute) is meant to be able to show a different image for different matches in that media attribute.

Currently one source is added in the code which acts as a normal image tag with srcset and sizes. However, there is no mention of the media attribute in the implementation. see: https://github.com/nuxt/image/blob/main/src/runtime/components/nuxt-picture.vue

A picture tag is mainly used in a more “Art Direction” way and not “Resolution Switching”.

<picture> is capable of handling resolution switching, however you shouldn’t use it if that’s all you need. In such cases stick with a regular element plus srcset and sizes.

Example of average picture tag usage:

  1. On landscape devices I show an image in a 22:9 aspect ratio and a specific crop.
  2. On portrait devices I show an image in 1:1 ratio and with a crop on the face.

These two images are different. Not just their width/height, they are actually different files with different aspects ratios and compositions. Each one is a source in the picture tag. Each of these <source /> tags also has a srcset and a sizes attribute so they behave like a normal image nuxt image would. They have an additional media attribute which defines when they are shown. This field has a media query in it that tells the browser in which context to show the source.

An HTML example:

<picture>
    <source
        media="(orientation: landscape)"
        srcset="image-small.png 320w,
                image-medium.png 800w,
                image-large.png 1200w"
        sizes="(min-width: 60rem) 80vw,
               (min-width: 40rem) 90vw,
               100vw">
    <source
        media="(orientation: portrait)"
        srcset="image-small-portrait.png 160w,
                image-medium-portrait.png 400w,
                image-large-portrait.png 600w"
        sizes="(min-width: 60rem) 80vw,
               (min-width: 40rem) 90vw,
               100vw">
    <img src="image-small.png" alt="Image description">
</picture>

You can of course also use the picture tag for file type support etc

<picture>
  <source type="image/webp" srcset="illustration.webp">
  <img src="illustration.png" alt="A hand-made illustration">
</picture>

With the above in mind we should be able to add multiple images into the nuxt picture tag so sources can be generated with media attributes.

See image for differences: img-picture

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:27
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

16reactions
pi0commented, Jun 2, 2021

With the current nuxt-picture, one cannot use different versions of image/src with media selectors but is simply an img replacement with the ability for serving modern formats alongside legacy support.

As @Atinux mentioned, It is possible to directly use $img and $img.getSizes API creating any structure like media variable sources. We can also create a shortcut like <nuxt-source> to make it sexier:

      <picture>
        <nuxt-source
          media="(orientation: landscape)"
          src="image.jpg"
          sizes="xs:200px md:500px lg:1024"
        />
        <nuxt-source
          media="(orientation: portrait)"
          src="image-portrait.jpg"
          sizes="xs:200px md:500px lg:1024"
        />
        <nuxt-img
          src="image.jpg"
          width="200"
        />
      </picture>

POC: https://codesandbox.io/s/intelligent-water-nbikw?file=/pages/index.vue

In addition, we probably support scoped slots for nuxt-picuture, this way we can make it more minimalistic. (subject to discuss when added)

One alternative would be supporting more complex syntax for sizes prop. Combining source and sizes. We had it in previous versions but removed it due to complexities for simpler usecases and implementation.

5reactions
pi0commented, Jun 2, 2021
  • Option 1 is probably not possible since will cause rendering double img tags inside picture unless checking parent for conditional rendering (which is anti-pattern)
  • Option 3 is introducing complex syntax mentioned earlier

I guess best would be going with 2 (nuxt-source and slot) 🙈

Read more comments on GitHub >

github_iconTop Results From Across the Web

The Picture element - HTML: HyperText Markup Language
These examples demonstrate how different attributes of the <source> element change the selection of the image inside <picture> .
Read more >
HTML picture tag - W3Schools
The <picture> element contains two tags: one or more <source> tags and one <img> tag. ... The <picture> tag also supports the Global...
Read more >
How does <picture> tag work with two sources? - Stack Overflow
The element holds two different tags: one or more tags and one tag. The element has the following attributes: srcset (required) - defines...
Read more >
The picture element - web.dev
You can specify multiple source elements inside a picture element, each one with its own srcset attribute. The browser then executes the first...
Read more >
Picture element | Can I use... Support tables for HTML5, CSS3 ...
A responsive images method to control which image resource a user agent ... media query and/or support for a particular image format ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found