Skip to content

Responsive images ​

Available from v6.0.0

Images from the File Manager get everything a browser needs to load the right size, without changes to your templates. It uses the image manipulations of the upload directory (Files → upload directory → Image Manipulations), the same ones you can pick with Image size in the editor.

What happens on your site ​

When a Wyvern field is shown in a template, every image from the File Manager gets:

AttributeValue
srcsetthe image manipulations of its upload directory, plus the original, each with its width (400w)
sizeshow wide the image is shown, see sizes
width and heightwhen they are missing, so the browser keeps the room free while loading (no layout shift)
loading="lazy"the image loads when it comes into view
decoding="async"the image does not hold up the rest of the page

For example, an image with the manipulations small (400 px wide) and medium (800 px wide), resized to 50% in the editor. Stored:

html
<figure class="image image_resized" style="width:50%;">
    <img src="{file:12:url}" width="1600" height="800" alt="Trail 500">
</figure>

On the site:

html
<figure class="image image_resized" style="width:50%;">
    <img src="https://example.com/images/uploads/trail-500.jpg" width="1600" height="800" alt="Trail 500"
         srcset="https://example.com/images/uploads/_small/trail-500.jpg 400w,
                 https://example.com/images/uploads/_medium/trail-500.jpg 800w,
                 https://example.com/images/uploads/trail-500.jpg 1600w"
         sizes="(max-width: 3200px) 50vw, 1600px" loading="lazy" decoding="async">
</figure>

A phone downloads the 400 px version, a large screen the original.

Which manipulations ​

Only manipulations that show the same picture, smaller:

  • Constrain manipulations that are smaller than the original;
  • Crop manipulations with exactly the same aspect ratio as the original (a crop to another ratio shows another picture);
  • that exist on disk: manipulations made after the upload need a Sync of the upload directory.

SVG and GIF images are left out: they have no manipulations, and a resized GIF loses its animation. Images from other websites only get loading and decoding.

Which manipulations exist is remembered for a day per image (an hour when there were none), so a page with many images stays fast, also with files on S3 and the like. Clear the cache of ExpressionEngine after a Sync to see the new sizes right away.

sizes ​

sizes tells the browser how wide the image is shown, so it picks the smallest file that is sharp enough. Wyvern takes it from the editor:

The image in the editorsizes
resized to a percentage, e.g. 50% (of a 1600 px image)(max-width: 3200px) 50vw, 1600px
resized to pixels, e.g. 300px(max-width: 300px) 100vw, 300px
not resized, width="1600"(max-width: 1600px) 100vw, 1600px
no width known100vw

In the editor ​

Image size in the image toolbar switches an image between the manipulations of its upload directory; the chosen one is the src, the srcset still offers all sizes.

Image size

Image options (the cog) sets per image:

  • Load right away (no lazy loading): stores loading="eager", for an image at the top of the page that should not wait;
  • Responsive sizes (srcset): unchecked it stores data-wyvern-responsive="no": the image gets no srcset and sizes (Wyvern removes that attribute from the output).

Image options

Turn it off ​

  • For the whole site: the setting Responsive images (on by default).
  • For a field in a template: {field_name responsive="no"}, or {field_name loading="eager"} to load its images right away.
  • For one image: Image options in the editor.

Setting, tag and image together ​

The broader level decides first, the finer level only adjusts within it:

  1. The setting is the main switch for the site. Off: Wyvern adds nothing to images (it only removes data-wyvern-responsive).
  2. The tag parameters override it per field: responsive="yes" or responsive="no" both ways; loading="eager" leaves out loading="lazy" but still adds srcset and sizes.
  3. Image options adjust one image, when responsive images are on for the field.
SettingTag responsiveImage optionsResult
on–defaultsrcset, sizes, width/height, loading="lazy", decoding="async"
on–Load right away ✓the same, with loading="eager"
on–Responsive sizes ✗only loading="lazy" and decoding="async"
on"no"anynothing added
off–anynothing added (a stored loading="eager" stays)
off"yes"defaultsrcset, sizes, ... as with the setting on
on– (tag loading="eager")defaultsrcset, sizes, ... without loading="lazy"

What you set yourself on an <img> (for example in Source) always wins: an existing srcset, sizes, width, height or loading is kept.

No srcset? ​

Set Logging to Everything in the settings: Wyvern then logs why an image gets no srcset, for example

Responsive images: no srcset for "trail-500.jpg" (file #12, 1600 × 800): medium (not found: /var/www/images/uploads/_medium/trail-500.jpg)
  • its upload directory has no image manipulations: add them to the upload directory;
  • not found: the manipulation was added after the upload, run a Sync of the upload directory;
  • not smaller or another aspect ratio: the manipulation is left out on purpose;
  • the size of the image is not known: run a Sync of the upload directory.