CSS light-dark() Function
The CSS light-dark() function selects one of two colors based on the element's used color scheme.
It allows developers to define colors for light and dark appearances within a single CSS declaration. The function works with the color-scheme property, which tells the browser which color schemes an element supports.
Syntax
light-dark(light-color, dark-color)
The function requires two comma-separated color values. The first is used for a light color scheme, and the second is used for a dark color scheme.
For example:
:root {
color-scheme: light dark;
}
body {
color: light-dark(#222222, #eeeeee);
background-color: light-dark(#ffffff, #121212);
}
The browser selects the appropriate color based on the used color scheme.
Additional examples:
color: light-dark(black, white);
background-color: light-dark(white, black);
border-color: light-dark(#cccccc, #444444);
color: light-dark(rgb(20 20 20), rgb(240 240 240));
background-color: light-dark(hsl(210 50% 95%), hsl(210 30% 15%));
Both arguments must be valid CSS colors. The function returns a CSS <color> value.
Parameters
The light-dark() function requires two color arguments.
| Parameter | Description | Required |
|---|---|---|
light-color |
The color used when the element's used color scheme is light. | Yes |
dark-color |
The color used when the element's used color scheme is dark. | Yes |
For example:
light-dark(#0066cc, #80bfff)
The first color is selected for light mode, and the second is selected for dark mode.
Both arguments can use named colors, hexadecimal colors, RGB, HSL, Lab, LCH, OKLCH, and other supported CSS color expressions.
The arguments are separated by a comma, unlike the space-separated components used inside many modern CSS color functions.
How It Works
The light-dark() function evaluates the element's used color scheme and selects the corresponding color.
For example:
:root {
color-scheme: light dark;
}
.card {
background-color: light-dark(#f5f5f5, #252525);
color: light-dark(#222222, #ffffff);
}
When the used color scheme is light, the card receives a light background and dark text.
When the used color scheme is dark, the card receives a dark background and light text.
The browser determines the used color scheme from the color-scheme property, the user's preferences, and applicable browser behavior.
The function does not automatically enable dark mode. The element must permit a dark color scheme for the dark argument to be selected.
Unlike a media query, light-dark() chooses a color within an individual declaration rather than conditionally applying an entire group of CSS rules.
The color-scheme Property
The color-scheme property indicates which color schemes an element supports.
To allow both light and dark schemes throughout a document, declare:
:root {
color-scheme: light dark;
}
The browser can then select the appropriate scheme based on the user's preference.
Common values include:
| Value | Meaning |
|---|---|
normal |
Does not declare support for additional color schemes. |
light |
Supports the light color scheme. |
dark |
Supports the dark color scheme. |
light dark |
Supports both schemes, with light listed first. |
dark light |
Supports both schemes, with dark listed first. |
only light |
Supports only light and requests that the browser not override it with automatic darkening. |
The order of the listed schemes matters when the browser has no matching preference or must choose a default.
For example:
:root {
color-scheme: dark light;
}
This supports both schemes but prefers dark when the browser cannot determine a more appropriate choice from the user's preferences.
The color-scheme property also affects browser-rendered interface features such as form controls, scrollbars, and system colors.
Light and Dark Selection
The first argument of light-dark() is selected when the element uses a light color scheme. The second is selected when it uses a dark color scheme.
| Used Color Scheme | Selected Argument |
|---|---|
| Light | First argument |
| Dark | Second argument |
For example:
.message {
background-color: light-dark(#e8f4ff, #17324d);
color: light-dark(#17324d, #e8f4ff);
}
The two color pairs are designed to maintain readable contrast in their respective schemes.
If the element uses the light color scheme, the first values are selected even when the user's operating system prefers dark mode.
This distinction is important because the function follows the element's used color scheme, not simply the operating system setting.
User Color Scheme Preferences
Browsers can use the user's preferred color scheme when an element supports both light and dark appearances.
For example:
:root {
color-scheme: light dark;
}
body {
background-color: light-dark(white, #121212);
color: light-dark(#222222, #eeeeee);
}
When the user prefers a light appearance, the browser normally selects the light colors.
When the user prefers a dark appearance, the browser normally selects the dark colors.
The prefers-color-scheme media feature can detect the user's preference directly:
@media (prefers-color-scheme: dark) {
/* Styles for a dark preference */
}
However, light-dark() does not require this media query when the appropriate color-scheme values are already declared.
The user's preferred scheme and the element's used scheme can differ when a page or component explicitly restricts the supported schemes.
Selecting a Specific Scheme
Individual elements can use a specific color scheme even when the surrounding document supports both schemes.
For example:
:root {
color-scheme: light dark;
}
.light-panel {
color-scheme: light;
background-color: light-dark(#ffffff, #222222);
color: light-dark(#222222, #ffffff);
}
.dark-panel {
color-scheme: dark;
background-color: light-dark(#ffffff, #222222);
color: light-dark(#222222, #ffffff);
}
The .light-panel element selects the first colors, while .dark-panel selects the second colors.
These selections are independent of the operating system's current theme preference.
The color-scheme property is inherited, so descendants normally use the scheme established by their parent unless they specify their own.
This allows different sections of the same page to use different color schemes.
Using Color Properties
The light-dark() function can be used wherever a CSS <color> value is accepted.
For example:
:root {
color-scheme: light dark;
}
.card {
color: light-dark(#222222, #eeeeee);
background-color: light-dark(#ffffff, #242424);
border: 1px solid light-dark(#cccccc, #555555);
}
.card a {
color: light-dark(#0055aa, #80bfff);
}
Other properties that accept color values include:
outline-colortext-decoration-colorcaret-colorcolumn-rule-colorbox-shadowtext-shadowfillandstrokefor SVG graphics
For example:
.button {
box-shadow: 0 3px 8px light-dark(rgb(0 0 0 / 15%), rgb(0 0 0 / 50%));
}
The shadow color changes according to the used color scheme.
Using Custom Properties
CSS custom properties can store light-dark() expressions for reuse throughout a stylesheet.
For example:
:root {
color-scheme: light dark;
--page-background: light-dark(#ffffff, #121212);
--page-text: light-dark(#222222, #eeeeee);
--panel-background: light-dark(#f5f5f5, #242424);
--border-color: light-dark(#dddddd, #444444);
}
body {
background-color: var(--page-background);
color: var(--page-text);
}
.panel {
background-color: var(--panel-background);
border: 1px solid var(--border-color);
}
Each custom property stores a reusable color expression.
The final color is selected when the value is used by an element, according to that element's color scheme.
This makes it easier to maintain a consistent set of light and dark colors.
Custom properties can also supply individual arguments:
:root {
--light-accent: #0066cc;
--dark-accent: #80bfff;
}
.button {
background-color: light-dark(var(--light-accent), var(--dark-accent));
}
Both approaches can simplify theme management.
Nested Color Functions
The arguments of light-dark() can contain other CSS color functions.
For example:
.card {
background-color: light-dark(
hsl(210 40% 95%),
hsl(210 25% 15%)
);
}
Both arguments use the hsl() function.
Another example uses oklch():
.button {
background-color: light-dark(
oklch(55% 0.16 250),
oklch(75% 0.12 250)
);
}
The function can also contain color-mix() expressions:
.panel {
background-color: light-dark(
color-mix(in srgb, white 90%, blue),
color-mix(in srgb, black 85%, blue)
);
}
Each argument must ultimately produce a valid CSS color.
Nested functions allow light and dark color values to be calculated rather than written as fixed hexadecimal values.
light-dark() vs. Media Queries
The light-dark() function and the prefers-color-scheme media feature can both be used when creating light and dark designs, but they work differently.
| Feature | light-dark() | prefers-color-scheme |
|---|---|---|
| Type | CSS color function | Media feature |
| Purpose | Select one of two colors. | Apply styles based on a color scheme preference. |
| Selection basis | Element's used color scheme | User's preferred color scheme |
| Can change layout properties | No | Yes |
| Requires color-scheme support | Dark selection requires a dark used scheme. | No |
Using light-dark():
:root {
color-scheme: light dark;
}
body {
background-color: light-dark(white, #121212);
}
Using a media query:
body {
background-color: white;
}
@media (prefers-color-scheme: dark) {
body {
background-color: #121212;
}
}
The results can be similar when the used scheme matches the user's preference.
Use light-dark() for color selection and media queries when entire groups of properties need to change based on the user's preference.
Example
This example displays a light panel and a dark panel using the same light-dark() color declarations.
HTML:
<div class="light-dark-demo">
<div class="light-dark-demo-panel light-dark-demo-light">
<strong>Light Color Scheme</strong>
<p>The first color is selected.</p>
</div>
<div class="light-dark-demo-panel light-dark-demo-dark">
<strong>Dark Color Scheme</strong>
<p>The second color is selected.</p>
</div>
</div>
CSS:
.light-dark-demo {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 15px;
max-width: 540px;
margin: 0 auto;
}
.light-dark-demo-panel {
min-width: 0;
padding: 25px 15px;
border: 1px solid light-dark(#cccccc, #555555);
background-color: light-dark(#f5f5f5, #242424);
color: light-dark(#222222, #eeeeee);
text-align: center;
}
.light-dark-demo-panel p {
margin: 10px 0 0;
color: inherit;
font-size: 13px;
}
.light-dark-demo-light {
color-scheme: light;
}
.light-dark-demo-dark {
color-scheme: dark;
}
The first color is selected.
The second color is selected.
The two panels use identical color declarations. The color-scheme property determines which argument is selected for each panel.
Both panels retain their respective appearances regardless of the operating system's theme preference.
Theme Example
This example creates a component that automatically follows the browser's selected light or dark scheme.
HTML:
<div class="light-dark-theme-demo">
<h3>Adaptive Theme Card</h3>
<p>This card follows the active color scheme.</p>
<span>Change your system or browser theme to compare.</span>
</div>
CSS:
.light-dark-theme-demo {
color-scheme: light dark;
max-width: 460px;
margin: 0 auto;
padding: 25px;
border: 1px solid light-dark(#cccccc, #555555);
border-radius: 6px;
background-color: light-dark(#ffffff, #242424);
color: light-dark(#222222, #eeeeee);
}
.light-dark-theme-demo h3 {
margin: 0 0 10px;
color: light-dark(#0055aa, #80bfff);
font-size: 18px;
}
.light-dark-theme-demo p {
margin: 0 0 12px;
color: inherit;
}
.light-dark-theme-demo span {
color: light-dark(#666666, #bbbbbb);
font-size: 12px;
}
Adaptive Theme Card
This card follows the active color scheme.
Change your system or browser theme to compare.The card uses the light colors when its used scheme is light and the dark colors when its used scheme is dark.
The color-scheme: light dark declaration allows the browser to select either appearance.
Browser Fallbacks
Older browsers may not recognize the light-dark() function.
A basic fallback can be provided before the function:
.card {
background-color: #ffffff;
background-color: light-dark(#ffffff, #242424);
}
Browsers supporting light-dark() use the second declaration. Older browsers retain the first.
For a light and dark fallback, use a media query:
.card {
background-color: #ffffff;
color: #222222;
}
@media (prefers-color-scheme: dark) {
.card {
background-color: #242424;
color: #eeeeee;
}
}
@supports (color: light-dark(white, black)) {
.card {
color-scheme: light dark;
background-color: light-dark(#ffffff, #242424);
color: light-dark(#222222, #eeeeee);
}
}
This approach provides light and dark styles for browsers that support the media query but not the newer color function.
When supporting older browsers, test the fallback with the intended theme behavior.
Common Uses
The light-dark() function is useful for building interfaces that support both light and dark color schemes.
| Use | Description |
|---|---|
| Page backgrounds | Select appropriate background colors for each scheme. |
| Text colors | Maintain readable foreground colors in light and dark appearances. |
| Buttons | Define scheme-specific backgrounds, text, and borders. |
| Cards and panels | Create components that adapt to the used color scheme. |
| Form controls | Coordinate custom colors with browser-supported color schemes. |
| Theme variables | Store reusable light and dark color pairs. |
| Icons and SVG | Choose appropriate fill and stroke colors. |
For example:
:root {
color-scheme: light dark;
}
.notice {
background-color: light-dark(#fff3cd, #493c13);
color: light-dark(#664d03, #ffe69c);
border: 1px solid light-dark(#ffecb5, #806520);
}
The notice uses different color combinations to remain visually distinct in light and dark schemes.
Limitations
The light-dark() function has several important rules and limitations.
- It requires exactly two color arguments separated by a comma.
- Both arguments must be valid CSS color values.
- It returns a color, not a general CSS value such as a length or display mode.
- The dark argument is selected only when the element's used color scheme is dark.
- It does not automatically enable dark mode or declare support for dark color schemes.
- The
color-schemeproperty may need to be declared to permit dark selection. - The user's preferred color scheme and the element's used scheme are not always identical.
- It does not replace media queries for layout changes or non-color properties.
- It does not automatically guarantee accessible color contrast.
- Older browsers may require fallback declarations.
For example, this is valid:
color: light-dark(#222222, #eeeeee);
The following is invalid because only one color is supplied:
color: light-dark(#222222);
The following is invalid because the function requires a comma:
color: light-dark(#222222 #eeeeee);
The following is invalid because a length is not a color:
width: light-dark(200px, 300px);
Use light-dark() only where a CSS color value is accepted.
Browser Support
The CSS light-dark() function is Baseline Newly available. It became available across the latest major browser engines in May 2024.
Modern versions of Chrome, Edge, Firefox, Safari, and other major browsers support the function.
For example:
:root {
color-scheme: light dark;
}
body {
background-color: light-dark(white, #121212);
}
Browser support for the function is separate from support for the color-scheme property and the prefers-color-scheme media feature.
For current compatibility information, visit Can I Use? and search for CSS light-dark().
Specifications
The light-dark() function is defined in the CSS Color Module Level 5 .
The specification defines the two color arguments and how the selected color depends on the element's used color scheme.
Related CSS features include the color-scheme property, the prefers-color-scheme media feature, CSS custom properties, and other CSS color functions.
