nuxt / nuxt/image

Support `<picture>` with multiple sources

Open
#309 23 comments 62 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
TypeScript
Stars
1.5k
Forks
331
Avg merge
19h 52m
Merged PRs (30d)
9

Description

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read src/runtime/components/nuxt-picture.vue and trace how the current single source is generated. The work is done when the Nuxt picture component can generate multiple sources, each supporting srcset and sizes plus a media attribute for art-direction use cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
nuxt, typescript
Domain
frontend
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.