# Inverted themes with light-dark()

DevFeed: [Inverted themes with light-dark()](<https://devfeed.tech/articles/inverted-themes-with-light-dark-49205.md>)

Original publisher: [Read original article](<https://daverupert.com/2026/04/inverted-light-dark/>)

Author: Dave Rupert

Published: 2026-04-07T15:31:00Z

Content type: tutorial

Language: en

Sources: [daverupert.com](<https://devfeed.tech/sources/daverupert-com.md>)

Topics: [Dark Mode](<https://devfeed.tech/topics/dark-mode.md>), [CSS](<https://devfeed.tech/topics/css.md>), [Design system](<https://devfeed.tech/topics/design-system.md>), [modern web development](<https://devfeed.tech/topics/modern-web-development.md>), [browser](<https://devfeed.tech/topics/browser.md>)

Tags: [browser](<https://devfeed.tech/tags/browser.md>), [css](<https://devfeed.tech/tags/css.md>), [dark-mode](<https://devfeed.tech/tags/dark-mode.md>), [design-system](<https://devfeed.tech/tags/design-system.md>), [themes](<https://devfeed.tech/tags/themes.md>)

## AI overview

A practical guide to using CSS light-dark() with design-system themes. It explains how to support light and dark modes in one stylesheet, respect user preferences without JavaScript, switch themes within a page, and implement inverted themes with a polyfill.

## Source excerpt

We rolled out adaptive light-dark() support on our design system themes and it's been a delightful upgrade. Creating light and dark variable sets isn't difficult, but delivery has trade-offs. Most apps that do this probably ship both sets of token values in a single stylesheet. That's fine until you have multiple kilobytes of duplicate definitions. To get around the performance problems we built two separate stylesheets -which is also not great- but my coworker Zacky found a good trick with <link disabled> to make it tolerable. Ultimately, we wanted to offer a single stylesheet for our human (and agent) friends to control theming. Having light-dark() makes it trivial to support dual color modes in a single stylesheet and doesn't add too much weight (0.5kb gzip for ~500 variables). It also gives you the ability to switch themes mid-page. :root { color-scheme: light dark; --bg-color: light-dark(white, black); --text-color: light-dark(black: white); /* ...etc */ } /* Add hard-coded theme overrides */ [data-theme="light"] { color-scheme: light; } [data-theme="dark"] { color-scheme: dark; } Adding [data-theme="dark"] to the body, or any element with color tokens defined, will force that section to be dark mode. The difference here between hanging variable definitions off a class is that you can respect the user preference without using JS to toggle, light-dark() does all the work. Adding dark tier on a light theme is dramatic. Adding light tier on a dark theme sure would stand out. But when yielding light and dark modes over to the browser... something changes. In that situation hardcoding a theme mode into HTML loses a bit of meaning because I'm not controlling the theme anymore, the user is. What I actually want is the theme to be "opposite" the current theme. After a handful of attempts I think I came across a solution that's easy to understand, maintain, and I even wrote a polyfill for you. Automatic inversion with [data-theme="inverted] See the Pen [data-theme="invert