Skip to content

[theme] Add HighContrast theme enhancer #48319

Merged
silviuaavram merged 33 commits into
mui:masterfrom
silviuaavram:feat/high-contrast-theme
May 22, 2026
Merged

[theme] Add HighContrast theme enhancer #48319
silviuaavram merged 33 commits into
mui:masterfrom
silviuaavram:feat/high-contrast-theme

Conversation

@silviuaavram

@silviuaavram silviuaavram commented Apr 17, 2026

Copy link
Copy Markdown
Member

Added the changes (excluding the slider borders) to a separate theme object.

To be used like so:

enhanceHighContrast(createTheme(...), {})

Closes #48334
Closes #13174

Preview: https://deploy-preview-48319--material-ui.netlify.app/material-ui/customization/palette/#windows-high-contrast-mode

Improves support for Dark High Contrast by adding a new theme support. The theme support will merge HCL styles on top of an existing theme.

  • For disabled, use GrayText for border, placeholder and text.
  • For error, use mark for border and text.
  • For selected, use Highlight for border, HighlightText for text, and none for forcedColorAdjust.
  • When both error and disabled are true, disabled wins, since there's no point in showing an error control if we can't do anything about it.
  • Some docs examples needed style changes since they did not support high contrast.

Colors were chosen based on this doc page.

Use Case Before After
Disabled Checkbox Screenshot 2026-04-14 at 15 53 03 Screenshot 2026-04-14 at 15 53 09
Disabled Radio Screenshot 2026-04-14 at 15 53 57 Screenshot 2026-04-14 at 15 53 53
Error Radio / FormLabel / FormHelperText Screenshot 2026-04-15 at 20 50 15 Screenshot 2026-04-15 at 20 50 07
Rating (ButtonBase focus outline / FormControlLabel) Screenshot 2026-04-15 at 20 45 40 Screenshot 2026-04-15 at 20 45 20
Disabled Inputs — FilledInput, Input, OutlinedInput Screenshot 2026-04-15 at 21 02 31 Screenshot 2026-04-15 at 21 02 39
Error Inputs — FilledInput, Input, OutlinedInput Screenshot 2026-04-15 at 21 03 59 Screenshot 2026-04-15 at 21 04 02
Input Placeholder Screenshot 2026-04-14 at 15 57 49 Screenshot 2026-04-14 at 15 57 54
Disabled Select (NativeSelect icon) Screenshot 2026-04-15 at 21 11 27 Screenshot 2026-04-15 at 21 10 45
Autocomplete Disabled Options Screenshot 2026-04-14 at 16 01 44 Screenshot 2026-04-14 at 16 01 28
Autocomplete focused / selected option Screenshot 2026-05-06 at 12 04 13 image
Selected MenuItem (also Select and Autocomplete) image image
ListItemButton hovered / focused / selected + ListItemIcon color Screenshot 2026-05-06 at 12 36 23 Screenshot 2026-05-06 at 12 36 17
LinearProgress Screenshot 2026-05-06 at 12 38 25 Screenshot 2026-05-06 at 12 38 21
Disabled Slider Screenshot 2026-04-16 at 16 13 46 image
Disabled Switch Screenshot 2026-05-06 at 12 39 55 Screenshot 2026-05-06 at 12 39 51
Toggle Button Selected Screenshot 2026-04-16 at 16 45 42 Screenshot 2026-04-16 at 16 45 52
Toggle Button Selected + Hovered Screenshot 2026-04-16 at 16 46 02 Screenshot 2026-04-16 at 16 45 57
Disabled MenuItem Screenshot 2026-05-11 at 15 13 51 Screenshot 2026-05-11 at 15 14 12
Tooltip Screenshot 2026-05-08 at 17 30 34 Screenshot 2026-05-08 at 17 29 59
Disabled Accordion Summary Screenshot 2026-05-11 at 15 14 53 Screenshot 2026-05-11 at 15 14 57

@code-infra-dashboard

code-infra-dashboard Bot commented Apr 17, 2026

Copy link
Copy Markdown

Deploy preview

Bundle size

Bundle Parsed size Gzip size
@mui/material 🔺+7.02KB(+1.38%) 🔺+1.61KB(+1.10%)
@mui/lab 0B(0.00%) 0B(0.00%)
@mui/private-theming 0B(0.00%) 0B(0.00%)
@mui/system 0B(0.00%) 0B(0.00%)
@mui/utils 0B(0.00%) 0B(0.00%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@silviuaavram silviuaavram added accessibility a11y customization: theme Higher level theming customizability. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature. labels Apr 17, 2026
@silviuaavram silviuaavram self-assigned this Apr 17, 2026
@silviuaavram silviuaavram force-pushed the feat/high-contrast-theme branch from 7f8ca62 to 27ef658 Compare April 21, 2026 12:40
Comment thread packages/mui-material/src/styles/createHighContrastTheme.ts Outdated
Comment thread packages/mui-material/src/styles/enhanceHighContrast.ts
Comment thread packages/mui-material/src/styles/enhanceHighContrast.ts

@siriwatknp siriwatknp left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

👍

@mnajdova mnajdova left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please add documentation page for it? It will help with the discoverability.

@silviuaavram silviuaavram force-pushed the feat/high-contrast-theme branch from b3d5287 to 8f1ea64 Compare May 8, 2026 08:17
@silviuaavram silviuaavram marked this pull request as ready for review May 11, 2026 05:28
Copilot AI review requested due to automatic review settings May 11, 2026 05:28

Copilot AI 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.

Pull request overview

Adds a new Material UI theme enhancer (enhanceHighContrast) that layers Windows High Contrast / forced-colors component overrides on top of an existing theme, and wires it into the docs demo theming plus documentation.

Changes:

  • Export enhanceHighContrast from @mui/material/styles (JS + TS entrypoints).
  • Introduce enhanceHighContrast implementation that injects @media (forced-colors: active) overrides for multiple components with configurable system-color tokens.
  • Update docs demos to apply the enhancer and add documentation describing usage and token customization.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/mui-material/src/styles/index.js Re-exports the new enhanceHighContrast API from the styles entrypoint.
packages/mui-material/src/styles/index.d.ts Adds TypeScript exports for enhanceHighContrast and HighContrastTokens.
packages/mui-material/src/styles/enhanceHighContrast.ts Implements the theme enhancer and token interface; injects forced-colors overrides for multiple components.
packages-internal/core-docs/src/Demo/DemoThemeProviders.tsx Applies enhanceHighContrast to the docs demo theme setup.
docs/data/material/customization/palette/palette.md Documents Windows High Contrast Mode usage and available tokens.
Comments suppressed due to low confidence (1)

packages-internal/core-docs/src/Demo/DemoThemeProviders.tsx:56

  • The enhancer is applied before runtimeTheme is deep-merged. This means any demo-provided runtimeTheme overrides can overwrite/remove the forced-colors component overrides, which is the opposite of the stated goal of layering high-contrast styles on top of an existing theme. Consider deep-merging runtimeTheme first and then running enhanceHighContrast(...) last so HCM overrides reliably win.
    const resultTheme = enhanceHighContrast(
      createTheme(
        {
          cssVariables: {
            colorSchemeSelector: 'data-mui-color-scheme',
          },
          colorSchemes: {
            light: true,
            dark: true,
          },
          direction: direction as 'ltr' | 'rtl',
        },
        dense ? highDensity : {},
      ),
    );
    if (upperMode) {
      Object.assign(resultTheme, resultTheme.colorSchemes[upperMode]);
    }
    if (runtimeTheme && Object.prototype.toString.call(runtimeTheme) === '[object Object]') {
      try {
        return deepmerge(resultTheme, runtimeTheme);
      } catch {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/data/material/customization/palette/palette.md Outdated
Comment thread packages/mui-material/src/styles/enhanceHighContrast.ts Outdated
Comment thread packages/mui-material/src/styles/enhanceHighContrast.ts
@silviuaavram silviuaavram force-pushed the feat/high-contrast-theme branch from 23fcc50 to a67759e Compare May 11, 2026 12:11
Comment thread docs/data/material/customization/palette/palette.md Outdated

@mj12albert mj12albert left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Implementation looks good ~ commented on a few docs-related things, additionally enhanceHighContrast could be documented here as well: https://master--material-ui.netlify.app/material-ui/customization/theming/#api

Comment thread docs/data/material/customization/palette/palette.md Outdated
Comment thread docs/data/material/customization/palette/palette.md Outdated
import { Theme } from './createTheme';

export interface HighContrastTokens {
/** Color for disabled elements. Default: `'GrayText'` */

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
/** Color for disabled elements. Default: `'GrayText'` */
/**
* Color for disabled elements.
* @default 'GrayText'
*/

We use the JSDOM default tag for default values. Please update everywhere.

Comment on lines +57 to +59
* Follows the same signature as `responsiveFontSizes`: accepts a fully-created
* theme, merges in HCM component overrides using arrays so that Emotion emits
* each entry as a separate CSS rule and the browser cascade (rather than JS

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
* Follows the same signature as `responsiveFontSizes`: accepts a fully-created
* theme, merges in HCM component overrides using arrays so that Emotion emits
* each entry as a separate CSS rule and the browser cascade (rather than JS
* Accepts a fully-created theme, merges in HCM component overrides using arrays so that Emotion emits
* each entry as a separate CSS rule and the browser cascade (rather than JS

No need to reference other utils here. We'll need to remember to update this comment if that other util changes in the future.

Comment thread packages/mui-material/src/styles/enhanceHighContrast.ts

The following tokens are available:

| Token | Default | Description |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we use the theme here and show the values for each color? We are already doing it for the regular palette. This table will need to be extracted in a Demo tough, so you can get access to the theme.

@silviuaavram silviuaavram force-pushed the feat/high-contrast-theme branch from 200607f to 44cdadd Compare May 15, 2026 15:18
import Typography from '@mui/material/Typography';
import { styled } from '@mui/material/styles';

const tokens = [

@mnajdova mnajdova May 21, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ideally we should have extracted this out of API generated code. @dav-is it may be interesting to have a JSON generated for the theme (or parts of it) that we need to document. We could extract this object out of the theme object, but we would miss the description & the default values.

@mnajdova mnajdova changed the title [theme] HighContrast theme [theme] Add HighContrast theme enhancer May 22, 2026

@mnajdova mnajdova left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

🚢 it

@silviuaavram silviuaavram merged commit d69827f into mui:master May 22, 2026
22 checks passed
@silviuaavram silviuaavram deleted the feat/high-contrast-theme branch May 22, 2026 12:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

accessibility a11y customization: theme Higher level theming customizability. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature.

Projects

None yet

6 participants