Skip to content

fix(link): keep external-link arrow visible in forced-colors - #234

Merged
abbybowman merged 3 commits into
nasa:mainfrom
nulluid:fix/external-link-forced-colors-229
Oct 7, 2026
Merged

abbybowman merged 3 commits into
nasa:mainfrom
nulluid:fix/external-link-forced-colors-229

Conversation

@nulluid

@nulluid nulluid commented Sep 14, 2026 •

Copy link
Copy Markdown

What this PR does

Keeps the external-link diagonal arrow visible in forced-colors mode (Windows High Contrast) by opting the icon out of forced colors and repainting it with the system CanvasText color.

Closes #229 (external-link item only)

Type of change

  • Bug fix (patch)
  • New feature or component (minor)
  • Breaking change (see Public API note below)
  • Documentation only
  • Tooling or CI (no effect on published CSS)

How to review

Open the Link stories with forced-colors: active enabled (DevTools > Rendering, or a Windows contrast theme) and check an external link. The diagonal arrow should stay visible, painted in black (CanvasText) against the Canvas background. Default rendering is unchanged.

Before requesting review

  • npm run lint, npm run format, and npm test pass locally

If your change affects how anything renders (styles, tokens, story markup, icons, or fonts):

  • Checked across all 6 palettes in Storybook
  • Checked across mobile, tablet, and desktop viewports
  • Did a manual a11y pass (keyboard, focus, screen-reader labels)

If your change ships in the package (styles, tokens, or src/assets/**):

  • Added a changeset (npx changeset) at the semver rubric level
  • Ran npm run check:api-snapshot; no drift was reported

Notes for reviewers

Root cause: the arrow is painted with mask-image + background-color. Forced-colors mode drops mask-image painting outright, independent of the color value, so setting background-color alone is not enough (confirmed by rendering in a real browser with forced-colors emulated, not just by reading the compiled CSS). The fix adds forced-color-adjust: none alongside the CanvasText background, matching the existing .usa-social-link precedent in this codebase for the same problem.

Regression test compiles the Sass and asserts both background-color: CanvasText and forced-color-adjust: none on .usa-link--external::after inside the forced-colors media block, following the pattern from #232.

The arrow is drawn with mask-image plus background-color. Forced-colors
mode drops mask-image painting outright, independent of the
background-color value, so the masked arrow disappears no matter what
color it's given.

Opt the pseudo-element out of forced colors and repaint it manually in
CanvasText, matching the .usa-social-link precedent already in the
codebase. Default rendering is unchanged.

Refs nasa#229 (external-link item only).
The arrow paints in CanvasText without opting the pseudo-element out
of forced colors; verified on a native Windows contrast theme after
@suthat flagged it in nasa#259. Reword the comment and drop the matching
test assertion.

@abbybowman abbybowman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix @nulluid! I confirmed in native Windows that the externa link arrow still paints in CanvasText without the opt-out, so I pushed a commit removing it, rewording the comment, and dropping the matching test assertion. Credit to @suthat for flagging this in #259. Merging once CI is green, appreciate your help!

@abbybowman
abbybowman merged commit 9c17808 into nasa:main Oct 7, 2026
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Icons and form-control state indicators disappear in forced-colors mode (radio selection not perceivable)

2 participants