From 73478fbb995181c0fc15090d9abeabf7d4373f1c Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Thu, 12 Nov 2026 10:31:07 +0100 Subject: feat: enlarge article images on click A shared native shows the clicked image at up to 95% of the viewport. Esc or a click closes it and focus returns to the image. Images are keyboard-reachable (Enter/Space). Linked images are skipped. Loaded on single pages only, styled inline so no CSS rebuild is needed. Co-Authored-By: Claude Opus 5.5 --- assets/js/image-zoom.js | 43 +++++++++++++++++++++++++++++++++++++++++++ layouts/_default/baseof.html | 2 ++ 2 files changed, 45 insertions(+) create mode 100644 assets/js/image-zoom.js diff --git a/assets/js/image-zoom.js b/assets/js/image-zoom.js new file mode 100644 index 0000000..307c858 --- /dev/null +++ b/assets/js/image-zoom.js @@ -0,0 +1,43 @@ +// Click (or Enter/Space) on an article image to see it full screen. +// One native is shared by all images: Esc closes it natively, +// a click anywhere closes it too, and focus returns to the image. +(function () { + var imgs = Array.prototype.filter.call( + document.querySelectorAll('.prose img'), + function (img) { return !img.closest('a'); } + ); + if (!imgs.length) return; + + var dlg = document.createElement('dialog'); + dlg.setAttribute('aria-label', 'Enlarged image'); + dlg.style.cssText = 'padding:0;border:0;background:transparent;max-width:95vw;max-height:95vh;overflow:visible;cursor:zoom-out'; + var big = document.createElement('img'); + big.style.cssText = 'display:block;max-width:95vw;max-height:95vh;width:auto;height:auto;object-fit:contain;border-radius:0.5rem'; + dlg.appendChild(big); + document.body.appendChild(dlg); + + var style = document.createElement('style'); + style.textContent = 'dialog[aria-label="Enlarged image"]::backdrop{background:rgba(0,0,0,0.85)}'; + document.head.appendChild(style); + + var opener = null; + dlg.addEventListener('click', function () { dlg.close(); }); + dlg.addEventListener('close', function () { if (opener) opener.focus(); }); + + function open(img) { + opener = img; + big.src = img.currentSrc || img.src; + big.alt = img.alt; + dlg.showModal(); + } + + imgs.forEach(function (img) { + img.style.cursor = 'zoom-in'; + img.tabIndex = 0; + img.setAttribute('role', 'button'); + img.addEventListener('click', function () { open(img); }); + img.addEventListener('keydown', function (e) { + if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); open(img); } + }); + }); +})(); diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index 50bdf39..7aa13cc 100644 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html @@ -111,6 +111,8 @@ {{ if eq .Kind "page" }} {{ $codeScript := resources.Get "js/code-copy.js" | minify }} + {{ $zoomScript := resources.Get "js/image-zoom.js" | minify }} + {{ end }} -- cgit v1.2.3