What Is CSS color-scheme? How to Support Light and Dark Modes

TIPS

When a website begins supporting dark mode, its date input or selection menu may still look unexpectedly light. The CSS color-scheme property tells the browser which color modes a page or element can support, including its browser-provided controls. But it does not automatically redesign images, headings, or custom buttons. This guide explains the distinction and shows how to support both modes in a small event-date search form.

color-scheme declares which modes an element supports

CSS (Cascading Style Sheets) describes how a webpage is displayed. Its color-scheme property tells the browser whether an element is designed to support light mode, dark mode, or both. The declaration color-scheme: light dark; indicates support for both; the mode actually used depends on factors such as the visitor’s operating system or browser preferences. It does not create a manual theme-switching button.

The property affects browser-provided appearance, including default form controls, scrollbars, and system colors. A native date picker or selection menu may therefore follow the chosen scheme. The exact appearance of calendars and menus varies among browsers and devices; color-scheme does not make them visually identical everywhere.

It is equally important to understand what the property does not do. Custom colors defined by an author through background-color or color are not automatically converted into a suitable dark palette. Provide light and dark colors separately using the CSS light-dark() function or a @media (prefers-color-scheme: dark) query. The expression light-dark(lightColor, darkColor) selects the color appropriate to the used scheme for that element.

Example: make an event-date form work in light and dark modes

Imagine an event page with a form for searching available dates. To keep this example self-contained, set color-scheme: light dark; on the wrapper around the form rather than on the entire site. The browser can use the chosen scheme for the native date input and selection menu, while light-dark() controls the background, text, input borders, and action button designed by the page author.

For light mode, choose pale blue-gray #F3F6FB for the outer area, white #FFFFFF for the form, and dark blue-gray #233247 for the text. Set the input outlines to gray #64748B, and pair a blue #1C5A91 search button with white #FFFFFF text.

For dark mode, use deep navy #101827 outside the form and muted dark blue #1C2B3F inside it. Text becomes very pale blue #F3F7FD. The input border changes to a lighter blue-gray #B0C0D7, and the button uses light blue #A9D2FF with deep-navy #142238 text. Each mode has its own foreground and background pairing.

<div class="booking-demo">
  <form class="booking-form" action="/event-search/" method="get">
    <h2>Find an event date</h2>
    <label for="event-date">Preferred date</label>
    <input id="event-date" name="date" type="date" required>
    <label for="event-style">Attendance format</label>
    <select id="event-style" name="style">
      <option value="online">Online</option>
      <option value="venue">In person</option>
    </select>
    <button type="submit">Search event dates</button>
  </form>
</div>
.booking-demo {
  color-scheme: light dark;
  padding: 24px;
  background-color: light-dark(
    rgb(243 246 251), rgb(16 24 39));
}
.booking-form {
  max-width: 34rem;
  padding: 24px;
  border-radius: 12px;
  background-color: light-dark(
    rgb(255 255 255), rgb(28 43 63));
  color: light-dark(
    rgb(35 50 71), rgb(243 247 253));
}
.booking-form label {
  display: block;
  margin: 12px 0 6px;
}
.booking-form input,
.booking-form select {
  display: block;
  box-sizing: border-box;
  width: 100%;
  padding: 10px;
  border: 2px solid light-dark(
    rgb(100 116 139), rgb(176 192 215));
  background-color: light-dark(
    rgb(255 255 255), rgb(28 43 63));
  color: inherit;
}
.booking-form button {
  margin-top: 16px;
  padding: 12px 18px;
  border: 0;
  border-radius: 8px;
  background-color: light-dark(
    rgb(28 90 145), rgb(169 210 255));
  color: light-dark(
    rgb(255 255 255), rgb(20 34 56));
}
.booking-form :is(input, select, button):focus-visible {
  outline: 3px solid light-dark(
    rgb(28 90 145), rgb(169 210 255));
  outline-offset: 3px;
}

In the CSS example, rgb() represents a color using red, green, and blue numeric components. Inside light-dark(), the first value is used in light mode and the second in dark mode. The :focus-visible rule adds a visible outline when a field or button receives keyboard focus. The sample form’s /event-search/ action is a placeholder; replace it with a working endpoint before using the form on a real site.

Check contrast and avoid declaring support for unfinished modes

For the specific pairs in this example, text against the form background has a contrast ratio of about 12.97:1 in light mode and 13.32:1 in dark mode. Button text against its background measures approximately 7.19:1 and 10.15:1 respectively. These exceed the 4.5:1 minimum for normal-sized text in the Web Content Accessibility Guidelines (WCAG) 2.2. Input borders against the form background measure about 4.76:1 in light mode and 7.75:1 in dark mode. Focus outlines against that background measure about 7.19:1 and 9.10:1, exceeding the 3:1 non-text contrast threshold relevant to necessary interface indicators.

These figures apply to the specified colors. Check the browser’s own calendar icons, selection menus, and the surroundings of the focus indicator on actual devices as well. If other parts of your site are not ready for dark mode, do not put color-scheme: light dark; on the entire :root yet. Changing browser-provided defaults while keeping custom page backgrounds fixed can create combinations that are difficult to read.

Once the whole page supports both schemes, you can declare the property at :root and optionally place <meta name="color-scheme" content="light dark"> in the HTML <head> before the styles, allowing browsers to learn the supported modes early. The newer light-dark() function may not work in older browsers, so consider fixed-color fallbacks or prefers-color-scheme rules when those browsers matter. HueRoll does not set a site’s light/dark behavior; it is useful for exploring candidate colors for each mode and checking a selected color against white or black.