Improve carousel accessibility: pause control, reduced motion, and focus-safe navigation - #287
Open
Castellon-ACM wants to merge 11 commits into
Open
Improve carousel accessibility: pause control, reduced motion, and focus-safe navigation#287Castellon-ACM wants to merge 11 commits into
Castellon-ACM wants to merge 11 commits into
Conversation
Framework-free, unit-testable functions for the checks needed by issue #261: WCAG contrast ratio calculation, non-text contrast (1.4.11), autoplay pause-control and timing safety (2.2.2), and missing image label detection. Exposed as window.FrontBlocksA11y so any block's InspectorControls can reuse them without a build step.
Registers frontblocks-a11y-utils globally and loads it as a dependency of both the Carousel and Before/After block editor scripts, so their InspectorControls can use window.FrontBlocksA11y.
The block's images are always rendered with alt="" (decorative); the before/after label is the only accessible text describing what each image shows. Flags it, advisory-only, when an image is set but its label is empty or whitespace.
Adds a real "Pause on hover/focus" toggle (frblPauseOnHover, default true) so autoplaying carousels have an actual way to be paused, including via keyboard/assistive-tech focus (Glide's own hoverpause only reacts to mouse hover). Surfaces three advisory, non-blocking inspector warnings using the shared accessibility utils: - autoplay enabled with no pause control (WCAG 2.2.2) - autoplay interval under the 5-second safety minimum - button color vs. background color below the 3:1 non-text contrast minimum (WCAG 1.4.11), only when both colors are set
Covers the frblPauseOnHover default (true) in both attribute registration filters, and its data-pause-on-hover output in the grid block content filter, including when explicitly disabled.
The JavaScript tests job only ran test:cookie-notice, so the new accessibility-utils test suite added in this branch wasn't actually enforced by CI.
- Never auto-start autoplay for visitors matching prefers-reduced-motion: reduce, regardless of the configured value. - Render an always-present, accessible pause/resume button whenever autoplay is actually running (WCAG 2.2.2), independent of the optional "pause on hover/focus" setting — visitors need a guaranteed way to stop auto-advancing content, not just a convenience tied to their input method. - Replace Glide's built-in hoverpause (mouse-only) with a manual pause-reason coordinator (hover, keyboard/AT focus, and the pause button) so none of them fight over Glide's play/pause state — e.g. a manual pause now survives the mouse leaving the carousel.
- Arrows no longer set outline: none on :focus with no replacement — they now get a real visible focus indicator (WCAG 2.4.7), suppressed only for mouse clicks via :focus-visible. - Bullets grow their actual clickable/tappable button box to the WCAG 2.5.8 minimum of 24x24 CSS px via a centered pseudo-element, while keeping the visible dot itself at its original 10px so the design doesn't change. - Styles the new accessible pause/resume button (28x28, visible focus indicator).
Covers: reduced-motion forcing autoplay off, the pause button only rendering when autoplay actually runs, click toggling pause/play and its own label/aria-pressed state, focus pausing/resuming, the pause-on-hover opt-out, and that a manual pause survives the mouse leaving the carousel.
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
Contributor
|
Reviewed the current diff. I did not find a blocking issue in this PR. Published CI checks are green. |
10 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #259.
Makes FrontBlocks carousels safe and usable by default for keyboard, screen-reader, and motion-sensitive visitors, without changing the block's existing layout/options UI or saved attributes.
prefers-reduced-motion: reduce, regardless of the configured autoplay value.<button class="glide__pause">is rendered whenever autoplay is actually running — independent of the optional "pause on hover/focus" setting, since visitors need a guaranteed way to stop auto-advancing content (WCAG 2.2.2), not just a convenience tied to their input method. Itsaria-label/aria-pressedupdate correctly on click ("Pause automatic slideshow" ⇄ "Play automatic slideshow").hoverpauseand a naive focus handler would have fought each other)..glide__arrowpreviously hadoutline: noneon:focuswith nothing replacing it — a real WCAG 2.4.7 violation. Now shows a visible outline for keyboard focus (suppressed only for mouse clicks via:focus-visible).display:none/aria-hidden), so no change was needed there.Test plan
npm run test:carousel-accessibility, 9 tests): reduced-motion forcing autoplay off, the pause button only rendering when autoplay actually runs, click toggling pause/play and its own label/aria-pressedstate, focus pausing/resuming, the pause-on-hover opt-out, and that a manual pause survives the mouse leaving the carousel.prefers-reduced-motionemulation; pause button click actually froze/resumed slide advancement (transformtracked over multiple seconds); real keyboardTabnavigation paused/resumed autoplay on focus/blur; a manual pause survived focus leaving the carousel; arrow focus outline confirmed via computed styles (outline-style: solid,2px, visible); bullet hit target confirmed viagetBoundingClientRect()(24×24) vs. the visible dot's computed size (10×10). No JS console/page errors in any scenario.php -l/node -cclean on all touched files.