Jan-Lukas Else

Thoughts of an IT expert

Pure CSS Lightbox in Hugo theme

Published on in 👨‍💻 Dev
Short link: https://b.jlel.se/s/90
⚠️ This entry is already over one year old. It may no longer be up to date. Opinions may have changed. When I wrote this post, I was only 20 years old!

Hugo themes have the option to override the default rendering of Markdown images by using “Markdown Render Hooks” since version 0.62.0. By creating a file in layouts/_default/_markup named render-image.html it is possible to use a custom template for rendered images. This gives a lot of flexibility. I just used that flexibility to create a lightbox with pure CSS (without using JavaScript, like many lightbox implementations do). After clicking (or tapping) on an content image, you will see it filling the browser view. Another click brings you back to the content.

I already used the render-image.html file to display the alternative text as a caption below the image, but now I added the lightbox. My current image template looks like this:

<figure>
    <a href="#{{ .Destination | md5 }}-lightbox"><img src="{{ .Destination | safeURL }}" alt="{{ .PlainText }}"></a>
    <figcaption>
        {{ if .Title }}
        <p>{{ .Title | markdownify }}</p>
        {{ else if .Text }}
        <p>{{ .Text | markdownify }}</p>
        {{ end }}
    </figcaption>
</figure>
<a href="#_" class="lightbox" id="{{ .Destination | md5 }}-lightbox">
    <img src="{{ .Destination | safeURL }}" alt="{{ .PlainText }}">
</a>

The img element inside the figure element is wrapped by an anchor element linking to another hidden (and wrapped) img by it’s id. The id is generated using the md5 hash of the image source location.

The stylesheet (in SCSS) for the lightbox looks like this:

.lightbox {
	display: none;
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 999;
	width: 100vw;
	height: 100vh;
	background: rgba(0,0,0,0.8);
	img {
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		margin: auto;
		max-width: 100%;
		max-height: 100%;
	}
	&:target {
		outline: none;
		display: block;
	}
}

The lightbox has a fixed position and covers the whole viewport by setting width and height to 100% of the viewport (100vw and 100vh). Inside that container the image is centered by using an absolute positition, setting the top, left, right and bottom positions to zero and setting automatic margin spacing.

Tags: , , ,

Jan-Lukas Else
Interactions & Comments