Skip to content

stereobooster/hugo-ideal-image

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hugo ideal image

Used by

Introduction

I created image components a couple of times before:

But browsers keep improving - now almost all modern browsers support:

I checked existing solutions and they either don't do what I want or are complicated (to my taste):

Features

  • Basic
    • sets HTML attribute src (required)
    • sets HTML attributes alt, and class if they passed
  • Lazy-load
    • sets HTML attributes loading="lazy", decoding="async"
    • sets HTML attributes width, height to prevent reflow (LCP)
      • including for SVG
  • Responsive
    • sets HTML attribute srcset and resizes the image
      • but doesn't upscale image
    • adds source element for webp format
  • Modern LQIP
    • Can be disabled for transparent images (png, webp)
    • Another option would be dominant color (not implemented)
  • Portable markdown links
  • Dark mode (not implemented)
  • Maybe URL params for resize params (not implemented)

Implementation

There are different ways to implement image components in Hugo:

I think the most pragmatic way would be to implement partial which accepts an image as a resource. This way it can be reused in render hooks and shortcodes, and the resolution of the image would be the responsibility of the caller.

It can look something like this:

{{ partial "picture.html" (dict "img" $img "alt" $.Text) }}

Partial picture.html would be responsible for detecting width and height, resizing the image, and rendering HTML. There are no special requirements for HTML or CSS so it would be a pretty portable solution (just copy one file).

Source code

Notes

Image CSS

Partial sets width and height for the image, but this is done so that the browser would know the ratio and can calculate the area that the image would take. Probably you want to use CSS to set the desired size for the image, for example:

img {
  max-width: 100%;
  height: auto;
}

LQIP CSS

For LQIP to work picture needs to be the same size as the image. There can be different solutions, but one of the simplest is to make a picture block element - picture { display: block; }

Also possible to add blur to the background which would improve appearance:

picture > img {
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}

Note: LQIP doesn't work in Firefox because of this bug

Dark mode

I'm not sure yet how to implement "dark mode" for images. From an HTML point of view it is trivial to implement:

<picture>
  <source media="(prefers-color-scheme: dark)" srcset="..." />
  <source media="(prefers-color-scheme: light)" srcset="..." />
  <img src="..." />
</picture>

But how to do it from Markdown's point of view? Some options are: