Skip to content

fix(icons): fix icons invisible in high contrast mode #19352

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
May 26, 2025

Conversation

wkeese
Copy link
Contributor

@wkeese wkeese commented May 8, 2025

Closes #17147, #18830, #19015, #19023, and partially fixes #19140.
Also fixes problems like showing the selected tab in UIShell / SidePanel.
Likely also fixes similar problems in @carbon/ibm-products.
Refs #8489.

If the system has a dark high-contrast theme, then icons need to be displayed in white (or a light color), and vice-versa. Otherwise, icons become invisible (black on black or white on white). Importantly, the icon color needs to be set relative to the system's high contrast theme regardless of which Carbon theme is selected.

Although Carbon already has a mixin for this, it is not used consistently, and it would be labor-intensive, bloat the code, and error-prone to do so. Because you basically would need to call the mixin every time you set a fill, which is done hundreds of times. For example:

.#{$prefix}--accordion__arrow,
.#{$prefix}--accordion__item--active .#{$prefix}--accordion__arrow {
  fill: $icon-primary;
  @include high-contrast-mode('icon-fill');
}

And as I wrote in #19015, you also need to worry about CSS precedence, so you might think you've fixed a bug, but it isn't fixed in all cases.

So instead, this PR goes to the root of the issue by just overriding the value of --cds-icon-primary CSS property referenced by the $icon-primary SCSS variable. Likewise for similar CSS properties. For example, consider this story, in the G100 theme. There's this existing CSS:

[data-carbon-theme=g100] {
  --cds-icon-primary: #f4f4f4;
  --cds-icon-secondary: ...
  ...
}

But in high contrast mode, it's now overridden by:

@media screen and (-ms-high-contrast: active), (forced-colors: active) {
    [data-carbon-theme=g100] {
        --cds-icon-primary: ButtonText;
        --cds-icon-secondary: ButtonText;
        --cds-icon-disabled: GrayText;
        --cds-icon-on-color-disabled: GrayText;
        --cds-icon-inverse: SelectedItemText;
        --cds-icon-on-color: SelectedItemText;
        ...
    }
}

I also removed the current 27 calls to:

@include high-contrast-mode('icon-fill');

Plus a few other places that were manually setting fill to ButtonText, but now no longer need to do so.

Changelog

New

  • Added CSS to override the values of icon CSS properties (ex: --cds-icon-primary) when the system is in high contrast mode.

Testing / Reviewing

Tested in Storybook on Windows 11, using the Aquatic and Desert themes.

Note that you can emulate forced-mode on Mac in Chrome (see https://cssence.com/2024/forced-colors-mode-strategies/), which is useful if you don't have a PC handy. Just open Chrome DevTools, hit Ctrl/Cmd+Shift+P, type “forced”, and you’ll find the option to "Emulate CSS forced-colors: active".

PR Checklist

As the author of this PR, before marking ready for review, confirm you:

  • Reviewed every line of the diff
  • Updated documentation and storybook examples
  • [N/A] Wrote passing tests that cover this change
  • Addressed any impact on accessibility (a11y)
  • Tested for cross-browser consistency
  • Validated that this code is ready for review and status checks should pass

More details can be found in the pull request guide

If the system has a dark high-contrast theme, then icons need to be displayed
in white (or a light color), and vice-versa.  Otherwise, icons become invisible.
Importantly, this must happen regardless of the Carbon theme setting.

Fixes carbon-design-system#17147, carbon-design-system#18830, carbon-design-system#19015, carbon-design-system#19023, carbon-design-system#19140.
Copy link

netlify bot commented May 8, 2025

Deploy Preview for v11-carbon-web-components ready!

Name Link
🔨 Latest commit 62f6215
🔍 Latest deploy log https://app.netlify.com/projects/v11-carbon-web-components/deploys/6830f2ba1520fc00083c9680
😎 Deploy Preview https://deploy-preview-19352--v11-carbon-web-components.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.

Copy link

netlify bot commented May 8, 2025

Deploy Preview for v11-carbon-react ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit 62f6215
🔍 Latest deploy log https://app.netlify.com/projects/v11-carbon-react/deploys/6830f2ba4451b2000892c92a
😎 Deploy Preview https://deploy-preview-19352--v11-carbon-react.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.

Copy link

codecov bot commented May 9, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 84.91%. Comparing base (781e9d0) to head (62f6215).
Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #19352   +/-   ##
=======================================
  Coverage   84.91%   84.91%           
=======================================
  Files         373      373           
  Lines       14504    14504           
  Branches     4794     4792    -2     
=======================================
  Hits        12316    12316           
- Misses       2040     2041    +1     
+ Partials      148      147    -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Use proper color for icon, not background color.
@wkeese wkeese marked this pull request as ready for review May 9, 2025 01:21
@wkeese wkeese requested review from a team as code owners May 9, 2025 01:21
@wkeese wkeese requested review from heloiselui and annawen1 May 9, 2025 01:21
@heloiselui heloiselui added the a11y: high contrast mode Issues in Windows high contrast mode label May 9, 2025
Copy link
Contributor

@heloiselui heloiselui left a comment

Choose a reason for hiding this comment

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

Great, thank you so much for working on this!

I've been reviewing all the issues and your updates:

For @include high-contrast-mode('icon-fill') - try removing it in this PR if possible, so I can review it here.

I tested #17147, #18830, #19015, and #19023 - they all look good, thanks 🎉

I tested #19140 and it still shows the same behavior as the issue. I recorded a quick video so you can take a look. I also saw that @mariyageorge01 made some changes in her PR, I tested it and it works as expected. Maybe we can wait for your PR to be merged first, and then she can continue with her updates? What do you think?

ContentSwitcher.mp4

wkeese added 2 commits May 10, 2025 09:39
When you use standard tokens like $icon-primary you don't
need it anymore.

Note: I didn't convert $support-error and $support-warning usages
to a system color. Previously the inline notification icon 🚫 was converted
from red to ButtonText.  Also $support-error and $support-warning usages in
_list-box.scss.

Also, inline-notification has a dodgy use of $black-100 that I didn't change.
Replace $text-primary with $icon-primary as they are the same.

Likewise $tab-text-disabled --> $icon-disabled.

Updated _theme.scss to handle the other weird fill settings.
@wkeese
Copy link
Contributor Author

wkeese commented May 10, 2025

For @include high-contrast-mode('icon-fill') - try removing it in this PR if possible, so I can review it here.

OK, great, done.

Note: I didn't convert $support-error and $support-warning usages
to a system color. Previously the inline notification icon 🚫 was converted
from red to ButtonText. Likewise for $support-error and $support-warning usages in
_list-box.scss.

I tested #19140 and it still shows the same behavior as the issue. I recorded a quick video so you can take a look. I also saw that @mariyageorge01 made some changes in her PR, I tested it and it works as expected.

Right, I only addressed the fill color for icons, so @mariyageorge01's PR to adjust borders is still valid.

Maybe we can wait for your PR to be merged first, and then she can continue with her updates? What do you think?

I think that makes sense.

@heloiselui
Copy link
Contributor

Hey @wkeese,

I did some new tests, and with your changes we were able to fix not only the issues you were working on, but also other issues that weren’t even on our radar. Thanks for that!

Just one detail: the Checkbox component is now a bit hard to see the check mark ☑️, including in all components that use checkboxes.

Checkbox in DataTable:
image

Also, the Grid is not visible anymore. Although, I might need to open a new issue to check the Grid, because even without your changes it was already not showing what it should.

Grid:

Grid.mp4

@wkeese
Copy link
Contributor Author

wkeese commented May 11, 2025

Just one detail: the Checkbox component is now a bit hard to see the check mark ☑️, including in all components that use checkboxes.

Good catch.

This is complicated because Carbon has the idea of inverted colors, but that's not a thing in high-contrast mode. MDN (https://developer.mozilla.org/en-US/docs/Web/CSS/system-color) suggests that checkmarks should use SelectedItem and SelectedItemText, so I pushed a change to do that. It looks like this in Chrome's forced-color emulation:

Screenshot 2025-05-11 at 9 27 32

I could get the white-on-black inverted color effect by (for example) setting the foreground-color to Canvas and the background-color to ButtonText... but that seems counter to how high-contrast mode is supposed to work.

Also, the Grid is not visible anymore. Although, I might need to open a new issue to check the Grid, because even without your changes it was already not showing what it should.

Yah, I think that was broken before my changes. The problem is that the grid columns in the story are suddenly missing the cds--css-grid-column class, which sets the height to 80px... thus their height is now 0px.

PS: I also found the cause of that Grid story failure, it started with #19189 (unrelated to my PR).

heloiselui and others added 5 commits May 13, 2025 20:43
…19228 (carbon-design-system#19231)

* fix: controlled tag component for selected prop carbon-design-system#19228

* fix: fix tests for tag

* fix: controlled tag component for selected prop carbon-design-system#19228

* fix: controlled tag added a default selected prop and tests carbon-design-system#19228

* fix: controlled tag added a default selected prop and tests carbon-design-system#19228

* fix: controlled tag added a default selected prop and tests carbon-design-system#19228

* fix: controlled tag fix tests carbon-design-system#19228

* fix: add profile

* fix: add profile
…stem#19239)

* fix(date-picker): clear flatpickr instance on reset

* fix(date-picker): clear flatpickr instance on reset

* fix(date-picker): update comments and storybook docs to clarify changes

* fix(date-picker): update comments and storybook docs to clarify changes

* Update packages/react/src/components/DatePicker/DatePicker.tsx

Co-authored-by: kennylam <[email protected]>

---------

Co-authored-by: kennylam <[email protected]>
…on-design-system#19288)

* fix: modal footer buttons were not fully visible in zoom to 400

* fix: added test story

* fix: remove test story

---------

Co-authored-by: Heloise Lui <[email protected]>
@wkeese wkeese requested a review from a team as a code owner May 13, 2025 11:43
@wkeese wkeese requested a review from tay1orjones May 13, 2025 11:43
@wkeese
Copy link
Contributor Author

wkeese commented May 13, 2025

BTW @tay1orjones, do you know why [at least in some settings], background-color: SelectedItem doesn't work for where there's text, but it works in other places?

Screenshot 2025-05-13 at 20 46 18

Regardless, I think this PR is ready to merge. If we find any other issues we can fix them incrementally.

Copy link
Contributor

@heloiselui heloiselui left a comment

Choose a reason for hiding this comment

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

I tested this again and everything works as expected. Thanks again @wkeese! 🚀

Copy link
Member

@annawen1 annawen1 left a comment

Choose a reason for hiding this comment

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

tested and LGTM as well!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
6 participants