Skip to content

feat(image): add reduced-motion still variant - #2285

Merged
markdumay merged 1 commit into
mainfrom
feat/image-reduced-motion
Oct 28, 2026
Merged

markdumay merged 1 commit into
mainfrom
feat/image-reduced-motion

Conversation

@markdumay

@markdumay markdumay commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

An image can now carry a still variant for readers who prefer reduced motion. When a file with the same base name plus a -static suffix exists, assets/helpers/image-definition.html wraps the <img> in a <picture> whose <source> applies under (prefers-reduced-motion: reduce):

<picture>
  <source media="(prefers-reduced-motion: reduce)" srcset="/img/hero-static-light.svg">
  <img class="img-fluid …" src="/img/hero-light.svg" …>
</picture>
  • Naming. hero.svg pairs with hero-static.svg. For a color-mode image, the suffix goes before the mode, so hero-dark.svg pairs with hero-static-dark.svg. Modes come from main.modes.
  • Lookup. The new assets/helpers/still-sibling.html follows raster-sibling.html: page resource, then global asset, then static/. Remote URLs and #anchor sprites are skipped, and a missing sibling logs nothing.
  • Scope. This applies to every <img> the image pipeline renders, including hero, card and the image shortcode, so no new argument or mod-blocks change is needed. Inline SVGs and sprites render unchanged, and so do images without a sibling.
  • No script, CSP-neutral. The browser selects the source, so the animation never starts. The still image is fetched under img-src exactly like the original, with no inline script or style.

Verification

  • pnpm test passes: lint, color-mode tests, all five template builds, and test-strict-images.
  • New assertion table tests/templates/layouts/_partials/tests/still-sibling.html covers 9 lookup cases and 4 rendered-markup cases. It renders on the thumbnails page, so the strict-images build also shows that a missing sibling logs no warning.
  • Validated locally in a downstream site via HUGO_MODULE_REPLACEMENTS + --ignoreVendorPaths. Only the page with -static siblings changed. Headless Chrome with --force-prefers-reduced-motion showed the still image in light and dark mode, and logged no CSP violations under the site's default-src 'none' policy.
  • Manually reviewed on a local preview with reduced motion emulated, in both color modes.

🤖 Generated with Claude Code

When an image has a sibling with a `-static` suffix, such as
hero-static.svg next to hero.svg, render it inside a <picture> whose
source applies under `prefers-reduced-motion: reduce`. For a
color-mode image the suffix goes before the mode, so
hero-static-dark.svg pairs with hero-dark.svg.

The browser selects the source, so no script runs and the animation
never starts. Images without a sibling, inline SVGs and sprites
render unchanged. The still image loads under img-src like the
original, so strict CSP settings need no change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@netlify

netlify Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for gethinode-demo ready!

Name Link
🔨 Latest commit 8053858
🔍 Latest deploy log https://app.netlify.com/projects/gethinode-demo/deploys/6ae1f445af0eea158ebef28d
😎 Deploy Preview https://deploy-preview-2285--gethinode-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@markdumay
markdumay merged commit d27fab9 into main Oct 28, 2026
17 checks passed
@markdumay
markdumay deleted the feat/image-reduced-motion branch October 28, 2026 13:26
@markdumay

Copy link
Copy Markdown
Collaborator Author

🎉 This PR is included in version 3.46.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant