Responsive Tiled Image Gallery

I was converting a website from WordPress to Hugo and needed an equivalent to the Tiled Image Gallery from Wordpress. I wanted the Tiled Mosaic style, but that was a little to complex, as it also contains colspans. I came up with this as an alternative.

Demo and code can be found on Codepen

It has a WTFPL license and is almost fully ‘vibe coded’. It is Javascript-heavy and requires no CSS. It uses a simple HTML structure, as illustrated below:

<div class="gallery">
   <a href="full_img_src">
      <img ratio="0.666" src="thumb_img_src" />
   </a>
   ...
</div>

The hardest part of using this code is determining the image ratio before rendering. Any server side language (like PHP) can generate these image ratios though, as can Hugo (which I have built this for). Knowing the image ratio before loading the images prevents layout shifts and ensures a smooth loading experience.

This whole javascript is only a few kilobytes large, so it loads relatively quickly. It is fully responsive and has a debounce function that limits the redraws to 50ms, preventing it from being CPU-heavy.

Aestheticly, it aims for about 1 image every 700px of width. The images always fill out nicely and the code prevents subpixel issues. Images have a minimum size, which turns the gallery into a list of images on mobile. The margin between the images is 4px.

I did not take the time to fully understand the code, but it works pretty nice. The Hugo code I used is:

{{- if in .Params.thumbnail_image “/uploads/gallery” -}}
  {{- $dir := (path.Dir .Params.thumbnail_image) -}}
  {{- range (readDir (print "/static" $dir)) -}}
    {{- $resource := resources.Get (printf "%s/%s" $dir .Name) -}}
    {{- $thumb := $resource.Resize "600x" -}}
    {{- $thumburl := $thumb.RelPermalink -}}
    {{- $imageurl := printf "%s/%s" $dir .Name -}}
    {{- $imagetitle := index (split .Name ".") 0 -}}
    {{- $ratio := div (float $thumb.Width) (float $thumb.Height) -}}
    <a href="{{ $imageurl }}">
      <img data-ratio="{{ $ratio }}" src="{{ $thumburl }}" alt="{{ $imagetitle }}" loading="lazy">
    </a>
  {{- end -}}
{{- end -}}

Note that this code plays well with the Lightbox on Hugo Codex:

Enjoy!

Give this a look

Great, but the bottom line is not justified and it requires Go. That is why I created this one.