Skip to content

Commit

Permalink
images: wrap images in a lightbox (#63)
Browse files Browse the repository at this point in the history
* images: wrap images in a lightbox

Wrap images in a lightbox, increasing them to full-screen size when
clicked. There are JavaScript solutions available (e.g. lightbox2)[^0],
though I opted for a purely CSS-based approach.[^1]

[^0]: https://lokeshdhakar.com/projects/lightbox2/
[^1]: https://codesalad.dev/blog/how-to-create-an-image-lightbox-in-pure-css-25

Signed-off-by: Luca Zeuch <l-zeuch@email.de>

* perf: lazy-load lightbox duplicate

The implementation of a lightbox requires that the image in question is
rendered twice, once in the actual content and a second time as an
off-screen image. Defer loading of that off-screen duplicate until it is
needed.

Signed-off-by: Luca Zeuch <l-zeuch@email.de>

* layouts/images: allow opt-out from lightbox

Authors can now pass `lightbox=false` as a query parameter with their
image URL to disable the lightbox effect; this is especially useful for
smaller images that do not have a lot of detail.

Signed-off-by: Luca Zeuch <l-zeuch@email.de>

* images: center lightbox on both axes when shown

Signed-off-by: Luca Zeuch <l-zeuch@email.de>

---------

Signed-off-by: Luca Zeuch <l-zeuch@email.de>
  • Loading branch information
l-zeuch authored Jan 13, 2025
1 parent 4da89cb commit 2017ab4
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
39 changes: 39 additions & 0 deletions assets/scss/components/_images.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,42 @@ figcaption {
margin-top: 0.5rem;
font-style: italic;
}

/* CSS-only lightbox. See https://codesalad.dev/blog/how-to-create-an-image-lightbox-in-pure-css-25 */
.lightbox {
display: none;

position: fixed;
z-index: 99999;
top: 0;
left: 0;
right: 0;
bottom: 0;

padding: 1em;

background: rgba(0, 0, 0, 0.85);

/* center that thang, ya get me? */
justify-content: center;
align-items: center;
text-align: center;
white-space: nowrap;
}

/* Unhide the lightbox when it's the target */
.lightbox:target {
display: flex;
}

.lightbox span {
/* Full width and height */
display: block;
width: 100%;
height: 100%;

/* Size and position background image */
background-position: center;
background-repeat: no-repeat;
background-size: contain;
}
22 changes: 22 additions & 0 deletions layouts/_default/_markup/render-image.html
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,33 @@
{{- end }}
{{- end }}

{{- $lightbox := true }}
{{- if $u.RawQuery }}
{{- if $u.Query.Has "lightbox" }}
{{- $lightbox = ne ($u.Query.Get "lightbox") "false" }}
{{- end }}
{{- end }}

{{- /* Render image element. */ -}}
{{- if $lightbox -}}
<a href="#{{ print $id "-lightbox" }}">
{{- end }}
<img
{{- range $k, $v := $attrs }}
{{- if or $v (eq $k "alt") }}
{{- printf " %s=%q" $k $v | safeHTMLAttr }}
{{- end }}
{{- end -}}
>
{{- if $lightbox -}}
</a>
<a href="javascript:history.back();" class="lightbox" id="{{ print $id "-lightbox" }}">
<img loading="lazy"
{{- range $k, $v := $attrs }}
{{- if or $v (eq $k "alt") }}
{{- printf " %s=%q" $k $v | safeHTMLAttr }}
{{- end }}
{{- end -}}
>
</a>
{{- end }}

0 comments on commit 2017ab4

Please sign in to comment.