In this blog post we will look into how we can add a Zoom-In effect for better visibility.
We will be using Markdown Render Hooks from Hugo with HTML & CSS, implementing a non-javascript solution.
About Markdown Render Hooks
Hugo offers really handy Markdown Render Hooks. These allow custom templates to override markdown rendering functionality.
We will be using render-image hook to process out the images in the post as per our needs.
The render-image
hook stays in the location shown below.
* (site root)
โโโ layouts
โ โโโ _default
โ โโโ _markup
โ โโโ render-image.html
โโโ themes
The code snippet </>
For adding a Zoom-in effect we will be using a combination of input
and label
field inside which we will place our image.
Basic Idea:
- We have in
input
field of type checkbox. - We link the checkbox and label with an Unique Id generated for each image. In short we have a checkbox with a clickable label
- Inside the
label
we have our image placed. - Whenever the user clicks on image, it activates the checkbox and its value is set as checked.
- To make it look nicer, we hide the checkbox, using
hidden
attribute. - In CSS rules we add a
transform
property to image when the checkbox is checked.
Note: We are only enabling this on displays with width >=769px
. Smaller displays target touch sceen devices such as phones, where image zooming in is not effective as width is quite less.
Contents of
render-image.html
Put these into
(.)/layouts/_default/_markup/render-image.html
<!-- Checks if page is part of section and page is not section itself -->
{{- if and (ne .Page.Kind "section") (.Page.Section ) }}
<!-- Generate a unique id for each image -->
{{- $random := (substr (md5 .Destination) 0 5) }}
<input type="checkbox" id="zoomCheck-{{$random}}" hidden>
<label for="zoomCheck-{{$random}}">
<img class="zoomCheck" loading="lazy" decoding="async"
src="{{ .Destination | safeURL }}" alt="{{ .Text }}"
{{ with.Title}} title="{{ . }}" {{ end }} />
</label>
{{- else }}
<img loading="lazy" decoding="async" src="{{ .Destination | safeURL }}"
alt="{{ .Text }}" {{ with .Title}} title="{{ . }}" {{ end }} />
{{- end }}
Corresponding styling in
css
Put these into
(.)/layouts/<theme specific extend_head.html>
<style>
@media screen and (min-width: 769px) {
/* .post-content is a class which will be present only on single pages
and not lists and section pages in Hugo */
.post-content input[type="checkbox"]:checked ~ label > img {
transform: scale(1.6);
cursor: zoom-out;
position: relative;
z-index: 999;
}
.post-content img.zoomCheck {
transition: transform 0.15s ease;
z-index: 999;
cursor: zoom-in;
}
}
</style>
Sample Image with Zoom-In effect
Click on the below image to Zoom-In and Zoom-Out.
(Works with displays having width >=769px)