fix(a11y): restore icon visibility in Windows High Contrast Mode#10846
Open
bmatar wants to merge 2 commits intoswagger-api:masterfrom
Open
fix(a11y): restore icon visibility in Windows High Contrast Mode#10846bmatar wants to merge 2 commits intoswagger-api:masterfrom
bmatar wants to merge 2 commits intoswagger-api:masterfrom
Conversation
Icon SVGs (chevrons, lock indicators, expand/collapse arrows, modal close, authorize button) disappear in Windows High Contrast Mode. Their paths have no fill attribute — SVG default is black — or an explicit author color, which Chromium's default forced-color-adjust: preserve-parent-color preserves against the HCM-substituted Canvas. In HCM dark, black-on-black sits at 1.00:1. Path fills now use fill="currentColor" so the inherited color (which IS HCM-substituted) cascades to the path. _buttons.scss sets color: $black on the icon-button parents so currentColor resolves to the prior effective black in normal light mode. _dark-mode.scss swaps fill: $color to color: $color on the same SVG selectors so the cascade carries in dark mode too. An @media (forced-colors: active) block in _buttons.scss pins the icon paths to ButtonText with forced-color-adjust: none — ButtonText is the system color paired with ButtonFace and guarantees contrast in any user HCM theme, independent of the cascade. The same block resets opacity on the .unlocked auth icon, since opacity composites multiplicatively with fill and would otherwise dim the system-color contrast guarantee. Refs swagger-api#7350
The model expand chevron, copy-to-clipboard button, and form checkmark all render as data-URL background-image SVGs with hardcoded fill colors. In Windows High Contrast Mode the system strips background-image, so these icons become invisible — the underlying button/checkbox still functions but loses its visual indicator. Added @media (forced-colors: active) blocks that re-render the same SVG shape as a mask-image filled by background-color: ButtonText (or CanvasText for the model toggle on a div pseudo-element). With forced-color-adjust: none the system color is honored as authored, so the icon shape stays visible against any HCM theme background. Light-mode and dark-mode variants of each rule both updated. Refs swagger-api#10699
17 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.
Description
In Windows High Contrast Mode (Edge / Chromium with
forced-colors: active), several icon SVGs disappear because their paths use hardcoded fills (or no fill, defaulting to black). Chromium's spec-correct defaultforced-color-adjust: preserve-parent-colorfor SVG preserves these author colors against the HCM-substituted Canvas, so a black-fill icon on HCM-dark Canvas sits at 1.00:1 contrast.Affected controls: operation expand chevrons, lock indicators (auth state), the modal close icon, the Authorize-button lock, JSON-schema accordion chevrons, the model expand toggle, copy-to-clipboard buttons, the dark-mode form checkmark.
In the released swagger-ui (no
dark-modeplugin), these icons render as black-on-black in HCM dark — completely invisible. With thedark-modeplugin active, the plugin's CSS coincidentally sets non-default colors on the SVG element, so they render at low contrast (gray-on-black) rather than full disappearance. The fix addresses both.Two layers: (1) inline icon SVG paths use
fill="currentColor"so the inherited (HCM-substituted) color cascades to the path, with a@media (forced-colors: active)block in_buttons.scsspinning the paths toButtonTextfor theme-independent contrast and resetting the unlocked-icon opacity dimming that would otherwise composite the system color back to ~40% alpha. (2) Data-URLbackground-imagechevrons get@mediablocks that re-render the same SVG shape as amask-imagefilled bybackground-color: ButtonText/CanvasText.Motivation and Context
Refs #7350 (the existing accessibility issue lists "Expand collapsed chevrons and Unlock controls present in the End Points tab section is not visible highcontrast black mode" as a HCM finding).
Detected by Tactual. WCAG 1.4.11 Non-text Contrast.
Screenshots
All captured under
forced-colors: active. Built from the same swagger-ui commit on both ports, only this patch differing.Operations list — page-light + HCM dark (no dark-mode plugin, what petstore.swagger.io ships):
Operations list — page-dark + HCM dark (with dark-mode plugin):
Models section — page-light + HCM dark:
Operations list — page-light + HCM light:
Out of scope
<select>chevron in HCM (the<select>background-image chevron, both released_topbar.scssHTTPS dropdown variant and the dark-mode rule at_dark-mode.scss:156):<select>is a replaced element with no usable pseudo-element, so themask-imageapproach used here can't apply without wrapping the<select>in a markup change. Followup PR.color-scheme: darktohtml.dark-modefor native scrollbars/inputs. Independent and non-conflicting; HCM substitutes system colors regardless ofcolor-scheme.Checklist
My PR contains...
src/is unmodified: changes to documentation, CI, metadata, etc.)package.json)My changes...
Documentation
Automated tests