Color inversion
Joy UI components can invert their colors to match with the parent's variant.
Motivation
Global variants provide a consistent variant
prop that lets you control the hierarchy of importance within a group of Joy UI components. However, they are not working as expected when global variants are used in multiple layers.
The example below (on your right-hand side) shows the problem when the interface has more than one layer that applies the global variants:
Learn how to build super fast websites.
One layer
global variants are applied only to the children.
Learn how to build super fast websites.
Two layers
global variants are applied to the card and children.
On the left, the Button
's variant is solid
which is the highest emphasis level compared to other components. This conforms to the visual appearance on the screen.
On the right, the problem arises when the container's variant becomes solid
. The button is no longer the highest emphasis element because the it has the same background as the container. Also, the text and the icon button don't have enough contrast to the parent's background.
The color inversion is implemented to solves this issue, keeping the global variants meaningful when multiple layers of global variants are composed together.
Overview
When color inversion is enabled on the parent component, the children with implicit color will invert their styles to match the parent's background by keeping the same hierarchy of importance based on their variants.
Learn how to build super fast website.
Benefits
- Color inversion reduces a significant amount of styling effort. It handles all of the visual states (hover, active, and focus) on all the children.
- It makes your interface scalable. New components added to the area will just work.
- It works for both client-side and server-side rendering.
- It works for both light and dark mode.
- It can be disabled at any time without impacting the structure of the components.
- It is an opt-in feature. If you don't use it, the extra CSS variables won't be included in the production style sheet.
- It doesn't alter the styles of the children if you explicitly specify the
color
prop on them.
Trade-offs
- If the surface component contains just a few components, the style sheet size of the CSS variables might be bigger than customizing the styles of each individual child.
- It doesn't work with browsers that don't support CSS variables.
Usage
To enable the feature set invertedColors
to true on the surface components:
<Card variant="solid" color="primary" invertedColors>…</Card>
<Sheet variant="soft" color="info" invertedColors>…</Sheet>
Portal popup
By default, color inversion has no effect on the popup slot of Autocomplete
, Menu
, and Tooltip
.
To enable color inversion for those slots, set disablePortal
to true.
Intro to the MUI ecosystem
MUI blog
- Sitemap
- Services
- Blog
- Contact us
- Product
- MUI Core
- MUI X
- MUI ToolpadBETA
- Design kits
- Templates
byMUI
Copyright 2022
- ShortcutsTasksReportsSettings
Last update: 22/12/22
Jerry Wilson
Get started
Instant access to the power of the React UI library
How it works
Parent component
When invertedColors
is set to true on the surface component, a set of CSS variables are applied to it. The values of those variables comes from theme.colorInversion[variant][color]
where variant
and color
are the component's props. The surface component also creates a React context to tell the children to update their styles.
<Sheet invertedColors variant="solid" color="neutral">
// The component style sheet
{
// the values of these variables depends on the parent's variant and color.
--variant-softColor: …;
--variant-softBg: …;
--variant-softHoverColor: …;
--variant-softHoverBg: …;
--variant-softActiveBg: …;
… // other variants
}
Child component
All Joy UI components that support global variants check the React context that contains the color inversion flag. If the flag is true and the child has an implicit color, the internal color
value will switch to context
and apply the styles from theme.variants[variant].context
.
The styles will match the --variant-*
variables that the parent has.
<Chip variant="soft">
// Component style sheet
{
background-color: var(--variant-softBg);
color: var(--variant-softColor);
}
In summary, the parent creates a React context to tell the children that the feature is enabled, and generates CSS variables that will be used by the children. The children with an implicit color switch their default color value to context
to get the styles from the theme.