Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      Microsoft Graph CLI to be retired

      September 2, 2025

      The state of DevOps and AI: Not just hype

      September 1, 2025

      A Breeze Of Inspiration In September (2025 Wallpapers Edition)

      August 31, 2025

      10 Top Generative AI Development Companies for Enterprise Node.js Projects

      August 30, 2025

      I asked AI to modify mission-critical code, and what happened next haunts me

      September 3, 2025

      Why you should delete your browser extensions right now – or do this to stay safe

      September 3, 2025

      Dolby Vision 2 comes with big upgrades – here’s which TVs get them first

      September 3, 2025

      This one small feature makes this travel charger my favorite for business trips

      September 3, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      Laracon AU 2025 Talk Titles Revealed

      September 3, 2025
      Recent

      Laracon AU 2025 Talk Titles Revealed

      September 3, 2025

      Stop Writing Bad Controllers: Laravel Custom Collections Transform Your Code

      September 3, 2025

      Handle ownership relationships between Eloquent models with Laravel Ownable

      September 3, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      Lenovo Legion Go 2 confirmed with Ryzen Z2 Extreme, 1200p OLED 144Hz display & 74Wh battery

      September 2, 2025
      Recent

      Lenovo Legion Go 2 confirmed with Ryzen Z2 Extreme, 1200p OLED 144Hz display & 74Wh battery

      September 2, 2025

      How to Open Ports in Firewall on Windows Server

      September 2, 2025

      Google TV Remote Not Working? 5 Quick Fixes

      September 2, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»News & Updates»Should the CSS light-dark() Function Support More Than Light and Dark Values?

    Should the CSS light-dark() Function Support More Than Light and Dark Values?

    September 2, 2025

    One of the newer CSS features that has piqued my interest: the light-dark() function. And I’ve been closely following it ever since it became Baseline back in May 2024.

    The light-dark() function, briefly

    If you don’t know, the light-dark() function takes two color arguments: one for light mode and one for dark mode. Hence, the name light-dark(). It toggles between the two light and dark values based on a user’s preferences. Sara Joy has a wonderful article where you can get a much more detailed explanation.

    The key thing is that the function requires you to use the color-scheme property to activate those two color modes:

    :root {
      color-scheme: light dark;
    }
    
    .element {
      color: light-dark(brown, black);
    }

    And, depending on the user’s preference, one of those two modes is applied.

    Just two modes?

    That said, I’ve been wondering for a while now: Should the light-dark() function support more than light and dark color modes?

    I wrote about light-dark() for the CSS-Tricks Almanac. During my research, I found myself wishing the function could do more, specifically that it lacks support for other types of color schemes that a user might prefer, such as grayscale, high contrast, and low contrast.

    Does light-dark() even need a high-contrast mode?

    I’d say both yes and no. Let’s go back in time to when light-dark() was initially proposed somewhere around 2022. Emilio Cobos asked for a function to support light and dark mode changes, and it was added to the specifications.

    Done and handled, right? Not so fast. The ticket was indeed closed when Jacob Miller chimed in:

    Just saw this from @bramus‘s post, and I suspect that things are already closed / there’s no changing things now, but I see this as an approach that doesn’t actually solve for the issues people are facing with theming, and does so in a way that will create a trap for them when pursuing proper theming support.

    […]

    We shouldn’t ship single-purpose tools for the browser, but rather ones that scale and we can build upon.

    Good thing he chimed in, because that prompted Bramus to reopen the ticket:

    I think this was mistakingly done so. The end goal is to have something like schemed-value(), with light-dark() being an intermediary step towards the final solution.

    That’s a big deal! Bramus is saying that the light-dark() function is an intermediary solution on the way to a  schemed-value() function. In other words, shipping light-dark() was never the intended end goal. It’s a step along the way to this other more robust schemed-value() feature.

    Custom color schemes

    Bramus has already written a bunch about the schemed-value() concept. It could look something like this:

    :root {
      color-scheme: dark light custom;
    }
    
    body {
      color: schemed-value(
        light lightblue, /* Value used for light color-scheme */ 
        dark crimson, /* Value used for dark color-scheme */ 
        --custom green /* Value used for --custom color-scheme */
        );
    }

    This isn’t possible with light-dark(). In fact, before the function can support more than two modes, the color-scheme property has to be extended with more than the light and dark values. Only then can light-dark() be extended because, remember, light-dark() needs the color-scheme property in order to do its thing.

    Specifically, we’d need color-scheme to accept some sort of “custom” color scheme value. Tab Atkins provides a possible example in the ticket. The idea is to register a custom color scheme using a @color-scheme at-rule that defines the scheme’s properties, such as what particular color keywords are mapped to, and then use that color scheme’s ident on the color-scheme property that is declared on the root element:

    @color-scheme --high-contast {
      base-scheme: dark;
      canvascolor: black;
      canvastext: white;
      accentcolor: white;
      /* other properties set to specific colors */
    }
    
    html {
      color-scheme: --high-contrast;
    }

    With that in place, the custom color scheme can be used as its own standalone value in the forthcoming schemed-value() function:

    @color-scheme --high-contast {
      /* ... */
    }
    
    html {
      color-scheme: --high-contrast light dark;
    }
    
    body {
      color: schemed-value(--high-contrast, black, white);
    }

    Breaking it all down:

    • We register a custom color scheme (e.g. --high-contrast) in a @color-scheme at-rule.
    • We define the color scheme’s properties in the at-rule, such as whether its base theme is light or dark and what certain values color keywords map to.
    • We declare the custom color scheme on the color-scheme property at the root level (i.e., html { color-scheme: --high-contrast;}).
    • We apply the custom color scheme by declaring it on color-related properties by way of the schemed-value() function.

    So, not only will light-dark() change, the CSS color-scheme property will most likely have its own at-rule to allow for custom color-scheme values.

    We need more color theme support, but not in light-dark()

    This begs my earlier question: Does the light-dark() function really need to support more than two color scheme modes? Bramus has an answer:

    When schemed-value() ever becomes a thing, light-dark() would become syntactic sugar for it.

    A-ha! This means light-dark() doesn’t need to support multiple modes because schemed-value() has the power to extend light-dark() by its own virtue:

    light-dark(<color>, <color>); = schemed-value(light <color>, dark <color>);

    Is light-dark() an intermediary step? Yes, it is. And should it be extended to support multiple modes, including custom color schemes? It certainly could, but it doesn’t have to be. Instead, we can register and define a custom color scheme in an at-rule and make sure the color-scheme property can read it. That way, we get the simplicity of a two-mode function that can be further abstracted to support additional custom modes, if needed.

    In fact, it goes beyond color schemes. There is even an open ticket to extend light-dark() for images, and the discussions surrounding it seem to agree on a new function specifically designed for it.

    What about custom functions?

    But, wait! Doesn’t a lot of this sound a lot like what we’ve been hearing about the work happening with custom functions? Indeed, Tab came back with a possible approach using the if() function, and the Chris Lilley retagged the ticket as a result. That’s when Bramus demonstrated how we could reasonably replicate the light-dark() function with a custom CSS function:

    :root {
      /* ensures light mode comes first */
      --scheme: light;
    
      /* dark mode is set here */
      @media (prefers-color-scheme: dark) {
        --scheme: dark;
      }
    }
    
    /* custom function returns any two values depending on whether system is in light or dark mode */
    @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
      ); /* returns 2rem if system is in light mode and 2.5rem if system is in dark mode */
    }

    Nothing is set in stone! The only thing we know for sure is that we have a working light-dark() function and it’s Baseline widely available for use. Custom functions a work in progress and only available in Chromium-based browsers at the time I’m writing this.

    The path forward

    I’ve been exploring everything color-related for a while now, and I’d like to know your thoughts: Are you excited about the upcoming changes to light-dark()? Do you think light-dark() should support more color modes like high contrast?

    Let me know your thoughts in the comment section below. Feel free to also comment on any of the W3C GitHub comment threads linked in this post to share your thoughts and concerns for the coming new features.

    More on light-dark()

    Almanac

    on

    Jul 8, 2025


    light-dark()


    html { color: light-dark(#000, #fff); }

    accessibility color


    Sunkanmi Fafowora

    Article

    on

    Oct 29, 2024


    Come to the light-dark() Side

    dark mode functions UI/IX Design


    Sara Joy

    Article

    on

    Jun 5, 2025


    Exploring the CSS contrast-color() Function… a Second Time

    accessibility color CSS functions


    Daniel Schwarz

    Article

    on

    Jun 26, 2025


    Poking at the CSS if() Function a Little More: Conditional Color Theming

    CSS functions


    Daniel Schwarz


    Should the CSS light-dark() Function Support More Than Light and Dark Values? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    Source: Read More 

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleVolla Phone Quintus running Ubuntu Touch: Pre-installed apps
    Next Article Gyroflow – video stabilization using gyroscope data

    Related Posts

    News & Updates

    I asked AI to modify mission-critical code, and what happened next haunts me

    September 3, 2025
    News & Updates

    Why you should delete your browser extensions right now – or do this to stay safe

    September 3, 2025
    Leave A Reply Cancel Reply

    For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

    Continue Reading

    CVE-2025-37994 – “Linux Kernel USB TypeC UCSI NULL Pointer Access Vulnerability”

    Common Vulnerabilities and Exposures (CVEs)

    CVE-2010-20123 – Steinberg MyMP3Player Stack-Based Buffer Overflow Vulnerability

    Common Vulnerabilities and Exposures (CVEs)

    CVE-2025-5785 – Totolink X15 HTTP POST Request Handler Buffer Overflow Vulnerability

    Common Vulnerabilities and Exposures (CVEs)

    COD: Black Ops 7 also enforces TPM 2.0 & Secure Boot requirements on PC players

    Operating Systems

    Highlights

    15 Best Free and Open Source Test Automation Tools

    April 29, 2025

    Test automation frameworks are a set of best practices, common tools, and libraries that help…

    NetSPI Details Multiple Local Privilege Escalation Vulnerabilities in SonicWall NetExtender

    June 1, 2025

    CVE-2025-6134 – Projectworlds Life Insurance Management System SQL Injection

    June 16, 2025

    CVE-2025-25014 – Kibana Prototype Pollution Remote Code Execution

    May 6, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.