Should the CSS light-dark() Function Support Additional Values Beyond Light and Dark?

One of the newer CSS features that has caught my attention is the `light-dark()` function. I’ve been following it closely since it became Baseline in May 2024.

The `light-dark()` function takes two color arguments: one for light mode and one for dark mode. It toggles between these based on user preferences. Sara Joy has a detailed article on this.

To use the `light-dark()` function, you need the `color-scheme` property to activate the two color modes:

“`css
:root {
color-scheme: light dark;
}

.element {
color: light-dark(brown, black);
}
“`

Depending on user preference, one of these modes is applied.

Should the `light-dark()` function support more than light and dark color modes? I explored this in the CSS-Tricks Almanac and found it lacks support for other color schemes like grayscale or high contrast.

Does `light-dark()` need a high-contrast mode? Both yes and no. When `light-dark()` was proposed around 2022, Emilio Cobos requested support for light and dark mode changes, and it was added to the specifications. However, Jacob Miller pointed out that it doesn’t solve theming issues and could trap users pursuing proper theming support. This prompted Bramus to reopen the ticket, suggesting `light-dark()` is a step towards a `schemed-value()` function.

Bramus has written about the `schemed-value()` concept, which could look like this:

“`css
:root {
color-scheme: dark light custom;
}

body {
color: schemed-value(
light lightblue,
dark crimson,
–custom green
);
}
“`

This isn’t possible with `light-dark()`. Before supporting more modes, the `color-scheme` property needs to accept more than `light` and `dark` values. Tab Atkins provides an example of registering a custom color scheme using an `@color-scheme` at-rule:

“`css
@color-scheme –high-contast {
base-scheme: dark;
canvascolor: black;
canvastext: white;
accentcolor: white;
}

html {
color-scheme: –high-contrast;
}
“`

With this, the custom color scheme can be used in the `schemed-value()` function:

“`css
@color-scheme –high-contast {
/* … */
}

html {
color-scheme: –high-contrast light dark;
}

body {
color: schemed-value(–high-contrast, black, white);
}
“`

So, `light-dark()` doesn’t need to support multiple modes because `schemed-value()` can extend it:

“`css
light-dark(, ); = schemed-value(light , dark );
“`

`light-dark()` is an intermediary step, and it doesn’t need to support multiple modes. Instead, we can define a custom color scheme in an at-rule and ensure the `color-scheme` property can read it.

There is even an open ticket to extend `light-dark()` for images, with discussions agreeing on a new function for it.

Custom functions are also in progress, with Tab suggesting an approach using the `if()` function. Bramus demonstrated replicating the `light-dark()` function with a custom CSS function:

“`css
:root {
–scheme: light;

@media (prefers-color-scheme: dark) {
–scheme: dark;
}
}

@function –light-dark(–light-color, –dark-color) {
result: if(style(–scheme: dark): var(–dark-color) ; else: var(–light-color));
}

p {
font-size: –light-dark(
2rem,
2.5rem
);
}
“`

The `light-dark()` function is currently available for use, while custom functions are still a work in progress.

I’ve been exploring color-related topics, and I’d like to hear your thoughts: Are you excited about the changes to `light-dark()`? Should it support more modes like high contrast?

Share your thoughts in the comments below or on the W3C GitHub threads linked in this post.


Discover more from WIREDGORILLA

Subscribe to get the latest posts sent to your email.

Similar Posts