diff --git a/assets/global.js b/assets/global.js index bde1d32..d4e6e35 100644 --- a/assets/global.js +++ b/assets/global.js @@ -749,6 +749,12 @@ class SliderComponent extends HTMLElement { if (!this.slider || !this.nextButton) return; + // The browser leaves a partly visible slide where it is when something inside it takes focus. + this.slider.addEventListener('focusin', (event) => { + const slide = event.target.closest('[id^="Slide-"]'); + if (slide) slide.scrollIntoView({ block: 'nearest', inline: 'nearest' }); + }); + this.initPages(); const resizeObserver = new ResizeObserver((entries) => this.initPages()); resizeObserver.observe(this.slider); diff --git a/assets/section-main-product.css b/assets/section-main-product.css index c9dfc58..db10754 100644 --- a/assets/section-main-product.css +++ b/assets/section-main-product.css @@ -553,8 +553,11 @@ a.product__text { position: relative; } +/* Sized like the image, so that focus scrolls the whole image into view. */ .product__media-toggle { display: flex; + position: absolute; + inset: 0; border: none; background-color: transparent; color: currentColor; @@ -1069,12 +1072,19 @@ a.product__text { } @media (hover: hover) { - .product__media-zoom-hover, .product__media-icon--hover { display: none; } } +/* Keep the button in the tab order so keyboard users can open the image dialog. + Pointer events pass through it, so hover zoom works as before. */ +@media (hover: hover) and (min-width: 750px) { + .product__media-zoom-hover:not(:focus-visible) { + pointer-events: none; + } +} + @media screen and (max-width: 749px) { .product__media-zoom-hover, .product__media-icon--hover {