How I Made A Pure-CSS Image Gallery

I recently added a custom pure-CSS gallery based on this post here, which I adadpted slightly to my needs, adding a description and adding a plus sign hovering over the thumbnail. I also added image processing in hugo based on this post here.

Here is the hugo shortcode for the CSS image modal and thumbnail. It resizes the image to within 1200x1200 pixels and crop-fills the thumbnail to 400x300 pixels. Here are the hugo docs on the topic of image processing, in case you wish to edit the values–you probably will. I initially had trouble getting the filename to be anything but a hideous mess of hash+quality+settings.jpg which resulted in a very, very long filename,

{{- /* look for filename passed in first field */ -}}
{{- $src := $.Page.Resources.GetMatch (printf "*%s*" (.Get 0)) -}}
{{- if $src -}}

{{- /* add edited images to scratchpad */ -}}
{{- /* with the default image settings */ -}}
{{- $.Scratch.Set "thumb" ($src.Fill "q70 600x400") -}}
{{- $.Scratch.Set "large" ($src.Fit "q85 1200x1200") -}}
{{- $th := .Scratch.Get "thumb" -}}
{{- $lg := .Scratch.Get "large" -}}

{{- $ext := "jpg" -}}
{{- if (strings.HasSuffix $src ".png") -}}
  {{- $ext := "png" -}}
{{- else if (strings.HasSuffix $src ".gif") -}}
  {{- $ext := "gif" -}}
{{- /* add edited images to scratchpad */ -}}
{{- /* with the default image settings */ -}}
{{- $.Scratch.Set "thumb" ($src.Fill "q70 600x400") -}}
{{- $.Scratch.Set "large" ($src.Fit "q85 1200x1200") -}}
{{- $th := .Scratch.Get "thumb" -}}
{{- $lg := .Scratch.Get "large" -}}

{{- /* rename files to original basename  */ -}}
{{- /* and rename extension and thumbnail */ -}}
{{- $a := path.BaseName $src | anchorize -}}
{{- $ext := "jpg" -}}
{{- if (strings.HasSuffix $src ".png") -}}
  {{- $ext := "png" -}}
{{- else if (strings.HasSuffix $src ".gif") -}}
  {{- $ext := "gif" -}}
{{- end -}}

{{- /* generate filenames */ -}}
{{- $thname := printf "%s%s_th.jpg" $.Page.RelPermalink $a -}}
{{- $name := printf "%s%s.%s" $.Page.RelPermalink $a $ext -}}

{{- /* finally, copy the files into place */ -}}
{{- $th := resources.Copy $thname $th -}}
{{- $lg := resources.Copy $name $lg -}}

{{- /* here is the template HTML code */ -}}
<div class="thumb"><a href="#{{ $a }}"><div></div><img src="{{ $th.RelPermalink | safeURL }}" alt="thumbnail. {{ .Get 1 | plainify }}" /></a></div>
<a href="#_" class="overlay" id="{{ $a }}"><div>
    <img src="{{ $lg.RelPermalink | safeURL }}" alt="{{ .Get 1 | plainify }}" />
  {{- /* if description is present, then display it */ -}}
  {{- with or (.Get 2) (.Get 1) }}
    <p>{{ markdownify . }}</p>
  {{- end }}
</div></a>
{{- end -}}

This renders the following HTML:

<div class="thumb"><a href="#filename"><div></div><img src="filename_th.jpg" alt="thumbnail. alt text" /></a></div>
<a href="#_" class="overlay" id="filename"><div>
    <img src="filename.jpg" alt="alt text" />
    <p>Image caption/description or
      alt text which displays below
      the image in the modal.</p>
</div></a>

That image shortcode goes into your themes folder, under layouts/shortcodes/img.html.

Here is the thumbnail CSS, including the floating ‘+’ above it:

.thumb {
  z-index: 1;
  display: block;
  width: fit-content!important;
  text-align: center;
  margin: 0 auto;
  padding: 0;
}

/* this is the '+' */
.thumb a div::before {
  content: "+";
}

.thumb a div {
  background: rgba(27,10,25,.7);
  width: 52px;
  height: 52px;
  line-height: 52px;
  margin: .1em 0 0 .1em;
  padding: 0;
  vertical-align: top;
  text-decoration: none!important;
  font-size: 52px;
  position: absolute;
}

/* the thumbnail image */
.thumb img {
  max-width: 100%;
}

Here is the CSS for the overlay/floating image:

/* container and background */
;.overlay {
  z-index: 3;
  position: fixed;
  top: 0; left: 0;
  width: 100vw; height: 100vh;
  background: rgba(25,25,25,.7);
  text-align: center;
  visibility: hidden;
  text-decoration: none!important;
}

/* toggles visibility when clicking anchor */
.overlay:target {
  visibility: visible;
  outline: none;
  cursor: default;
}

/* container to center image and description */
.overlay div {
  position: relative; top: 50%;
  -webkit-transform: translateY(-50%);
  -ms-transform: translateY(-50%);
  transform: translateY(-50%);
  width: fit-content;
  margin: auto;
}

/* full-size image */
.overlay img {
  max-width: 90vw;
 ; max-height: 80vh;
  width: auto;
  height: auto;
  margin: auto;
}

/* optional image description */
.overlay p {
  max-width: 100%;
  margin: 0 auto;
  padding: .5em .8em;
  font-size: .9em;
  overflow-y: scroll;
  width: fit-content;
}

/* fixes links inside image description */
.overlay p a {text-decoration: underline !important;}

Once the shortcode and the CSS is added, to call it up is simple enough (removing the spaces between the brackets):

I hope this helps someone make a CSS-only image modal/gallery, maybe also helps someone with hugo shortcodes…