Dark Mode & color-scheme
Implement Dark Mode effortlessly using the color-scheme property and the new light-dark() CSS function.
The evolution of Dark Mode
In the early days of dark mode, developers had to write extensive @media (prefers-color-scheme: dark) blocks to manually override the colors of every single element.
Later, we moved to CSS Variables, swapping --bg-color: white to --bg-color: black inside a .dark-theme class.
Modern CSS introduces a native, streamlined approach using the color-scheme property and the light-dark() function, removing the need for media queries entirely.
Less code, native UI support
By simply adding color-scheme: light dark; to your :root, you immediately get dark mode support for native browser elements. Scrollbars, form inputs, checkboxes, and default backgrounds will automatically adapt to the user's OS preference.
For custom elements, the light-dark() function allows you to define both the light and dark colors inline. background-color: light-dark(white, black); is infinitely more readable than maintaining a separate stylesheet for dark overrides.
Implementing light-dark()
First, opt-in at the root level: :root { color-scheme: light dark; }.
Next, use the function for your colors: .card { background: light-dark(#ffffff, #1a1a1a); color: light-dark(#333333, #f5f5f5); }.
The browser will read the current color-scheme (which defaults to the OS preference) and automatically select the first color for light mode, or the second color for dark mode.
Try it
Toggle the color-scheme property of the container below. Watch the light-dark() functions and native UI elements instantly repaint.
light-dark() & color-scheme
Toggle Wrapper Theme
Account Settings
Notice how everything repaints instantly just by toggling the wrapper's color-scheme.
Native Elements
Check yourself
Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.
Remember this
- Add
color-scheme: light dark;to:rootto get free dark-themed scrollbars and form inputs. - Use
light-dark(light_value, dark_value)to define both themes inline without media queries. - Force a theme manually by overriding the
color-schemeproperty on a specific element.
Done with this concept?
Mark it complete to track your progress. No login needed.