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

      Can Good UX Protect Older Users From Digital Scams?

      June 25, 2025

      Warp 2.0 evolves terminal experience into an Agentic Development Environment

      June 25, 2025

      Qodo launches CLI agent framework

      June 25, 2025

      Overture Maps launches GERS, a system of unique IDs for global geospatial entities

      June 25, 2025

      Microsoft Copilot is “pretty important” but customers still prefer ChatGPT — “OpenAI has done a tremendous job”

      June 25, 2025

      Will you sync your Windows 10 PC data to the cloud for free access to security updates beyond 2025?

      June 25, 2025

      Red Hat Enterprise Linux (RHEL) quietly released an official image for WSL — but most of us won’t be able to use it

      June 25, 2025

      Sam Altman says ChatGPT has evolved beyond a mere “Google replacement” — with ads potentially coming to users

      June 25, 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

      What Are the PHP Trends in 2025

      June 25, 2025
      Recent

      What Are the PHP Trends in 2025

      June 25, 2025

      Real-Time Observability for Node.js – Without Code Changes

      June 25, 2025

      Elevating API Automation: Exploring Karate as an Alternative to Rest-Assured

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

      Microsoft Copilot is “pretty important” but customers still prefer ChatGPT — “OpenAI has done a tremendous job”

      June 25, 2025
      Recent

      Microsoft Copilot is “pretty important” but customers still prefer ChatGPT — “OpenAI has done a tremendous job”

      June 25, 2025

      Will you sync your Windows 10 PC data to the cloud for free access to security updates beyond 2025?

      June 25, 2025

      Red Hat Enterprise Linux (RHEL) quietly released an official image for WSL — but most of us won’t be able to use it

      June 25, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»News & Updates»Poking at the CSS if() Function a Little More: Conditional Color Theming

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

    June 25, 2025

    Chrome 137 shipped the if() CSS function, so it’s totally possible we’ll see other browsers implement it, though it’s tough to know exactly when. Whatever the case, if() enables us to use values conditionally, which we can already do with queries and other functions (e.g., media queries and the light-dark() function), so I’m sure you’re wondering: What exactly does if() do?

    Sunkanmi gave us a nice overview of the function yesterday, poking at the syntax at a high level. I’d like to poke at it a little harder in this article, getting into some possible real-world usage.

    To recap, if() conditionally assigns a value to a property based on the value of a CSS variable. For example, we could assign different values to the color and background properties based on the value of --theme:

    • --theme: "Shamrock"
      • color: ‌hsl(146 50% 3%)
      • background: hsl(146 50% 40%)
    • --theme: Anything else
      • color: hsl(43 74% 3%)
      • background: hsl(43 74% 64%)
    :root {
      /* Change to fall back to the ‘else’ values */
      --theme: "Shamrock";
    
      body {
        color: if(style(--theme: "Shamrock"): hsl(146 50% 3%); else: hsl(43 74% 3%));
        background: if(style(--theme: "Shamrock"): hsl(146 50% 40%); else: hsl(43 74% 64%));
      }
    }
    CodePen Embed Fallback

    I don’t love the syntax (too many colons, brackets, and so on), but we can format it like this (which I think is a bit clearer):

    color: if(
      style(--theme: "Shamrock"): hsl(146 50% 3%);
      else: hsl(43 74% 3%)
    );

    We should be able to do a crazy number of things with if(), and I hope that becomes the case eventually, but I did some testing and learned that the syntax above is the only one that works. We can’t base the condition on the value of an ordinary CSS property (instead of a custom property), HTML attribute (using attr()), or any other value. For now, at least, the condition must be based on the value of a custom property (CSS variable).

    Exploring what we can do with if()

    Judging from that first example, it’s clear that we can use if() for theming (and design systems overall). While we could utilize the light-dark() function for this, what if the themes aren’t strictly light and dark, or what if we want to have more than two themes or light and dark modes for each theme? Well, that’s what if() can be used for.

    First, let’s create more themes/more conditions:

    :root {
      /* Shamrock | Saffron | Amethyst */
      --theme: "Saffron"; /* ...I choose you! */
    
      body {
        color: if(
          style(--theme: "Shamrock"): hsl(146 50% 3%);
          style(--theme: "Saffron"): hsl(43 74% 3%);
          style(--theme: "Amethyst"): hsl(282 47% 3%)
        );
        background: if(
          style(--theme: "Shamrock"): hsl(146 50% 40%);
          style(--theme: "Saffron"): hsl(43 74% 64%);
          style(--theme: "Amethyst"): hsl(282 47% 56%)
        );
        transition: 300ms;
      }
    }

    Pretty simple really, but there are a few easy-to-miss things. Firstly, there’s no “else condition” this time, which means that if the theme isn’t Shamrock, Saffron, or Amethyst, the default browser styles are used. Otherwise, the if() function resolves to the value of the first true statement, which is the Saffron theme in this case. Secondly, transitions work right out of the box; in the demo below, I’ve added a user interface for toggling the --theme, and for the transition, literally just transition: 300ms alongside the if() functions:

    CodePen Embed Fallback

    Note: if theme-swapping is user-controlled, such as selecting an option, you don’t actually need if() at all. You can just use the logic that I’ve used at the beginning of the demo (:root:has(#shamrock:checked) { /* Styles */ }). Amit Sheen has an excellent demonstration over at Smashing Magazine.

    To make the code more maintainable though, we can slide the colors into CSS variables as well, then use them in the if() functions, then slide the if() functions themselves into CSS variables:

    /* Setup */
    :root {
      /* Shamrock | Saffron | Amethyst */
      --theme: "Shamrock"; /* ...I choose you! */
    
      /* Base colors */
      --shamrock: hsl(146 50% 40%);
      --saffron: hsl(43 74% 64%);
      --amethyst: hsl(282 47% 56%);
    
      /* Base colors, but at 3% lightness */
      --shamrock-complementary: hsl(from var(--shamrock) h s 3%);
      --saffron-complementary: hsl(from var(--saffron) h s 3%);
      --amethyst-complementary: hsl(from var(--amethyst) h s 3%);
    
      --background: if(
        style(--theme: "Shamrock"): var(--shamrock);
        style(--theme: "Saffron"): var(--saffron);
        style(--theme: "Amethyst"): var(--amethyst)
      );
    
      --color: if(
        style(--theme: "Shamrock"): var(--shamrock-complementary);
        style(--theme: "Saffron"): var(--saffron-complementary);
        style(--theme: "Amethyst"): var(--amethyst-complementary)
      );
    
      /* Usage */
      body {
        /* One variable, all ifs! */
        background: var(--background);
        color: var(--color);
        accent-color: var(--color);
    
        /* Can’t forget this! */
        transition: 300ms;
      }
    }
    CodePen Embed Fallback

    As well as using CSS variables within the if() function, we can also nest other functions. In the example below, I’ve thrown light-dark() in there, which basically inverts the colors for dark mode:

    --background: if(
      style(--theme: "Shamrock"): light-dark(var(--shamrock), var(--shamrock-complementary));
      style(--theme: "Saffron"): light-dark(var(--saffron), var(--saffron-complementary));
      style(--theme: "Amethyst"): light-dark(var(--amethyst), var(--amethyst-complementary))
    );
    CodePen Embed Fallback

    if() vs. Container style queries

    If you haven’t used container style queries before, they basically check if a container has a certain CSS variable (much like the if() function). Here’s the exact same example/demo but with container style queries instead of the if() function:

    :root {
      /* Shamrock | Saffron | Amethyst */
      --theme: "Shamrock"; /* ...I choose you! */
    
      --shamrock: hsl(146 50% 40%);
      --saffron: hsl(43 74% 64%);
      --amethyst: hsl(282 47% 56%);
    
      --shamrock-complementary: hsl(from var(--shamrock) h s 3%);
      --saffron-complementary: hsl(from var(--saffron) h s 3%);
      --amethyst-complementary: hsl(from var(--amethyst) h s 3%);
    
      body {
        /* Container has chosen Shamrock! */
        @container style(--theme: "Shamrock") {
          --background: light-dark(var(--shamrock), var(--shamrock-complementary));
          --color: light-dark(var(--shamrock-complementary), var(--shamrock));
        }
    
        @container style(--theme: "Saffron") {
          --background: light-dark(var(--saffron), var(--saffron-complementary));
          --color: light-dark(var(--saffron-complementary), var(--saffron));
        }
    
        @container style(--theme: "Amethyst") {
          --background: light-dark(var(--amethyst), var(--amethyst-complementary));
          --color: light-dark(var(--amethyst-complementary), var(--amethyst));
        }
    
        background: var(--background);
        color: var(--color);
        accent-color: var(--color);
        transition: 300ms;
      }
    }
    CodePen Embed Fallback

    As you can see, where if() facilitates conditional values, container style queries facilitate conditional properties and values. Other than that, it really is just a different syntax.

    Additional things you can do with if() (but might not realize)

    Check if a CSS variable exists:

    /* Hide icons if variable isn’t set */
    .icon {
      display: if(
        style(--icon-family): inline-block;
        else: none
      );
    }

    Create more-complex conditional statements:

    h1 {
      font-size: if(
        style(--largerHeadings: true): xxx-large;
        style(--theme: "themeWithLargerHeadings"): xxx-large
      );
    }

    Check if two CSS variables match:

    /* If #s2 has the same background as #s1, add a border */
    #s2 {
      border-top: if(
        style(--s2-background: var(--s1-background)): thin solid red
      );
    }

    if() and calc(): When the math isn’t mathing

    This won’t work (maybe someone can help me pinpoint why):

    div {
      /* 3/3 = 1 */
      --calc: calc(3/3);
      /* Blue, because if() won’t calculate --calc */
      background: if(style(--calc: 1): red; else: blue);
    }

    To make if() calculate --calc, we’ll need to register the CSS variable using @property first, like this:

    @property --calc {
      syntax: "<number>";
      initial-value: 0;
      inherits: false;
    }

    Closing thoughts

    Although I’m not keen on the syntax and how unreadable it can sometimes look (especially if it’s formatted on one line), I’m mega excited to see how if() evolves. I’d love to be able to use it with ordinary properties (e.g., color: if(style(background: white): black; style(background: black): white);) to avoid having to set CSS variables where possible.

    It’d also be awesome if calc() calculations could be calculated on the fly without having to register the variable.

    That being said, I’m still super happy with what if() does currently, and can’t wait to build even simpler design systems.


    Poking at the CSS if() Function a Little More: Conditional Color Theming 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 ArticleIntehill 16″ 3K Touchscreen U16ZT Portable Monitor Review
    Next Article CVE-2025-48954 – Discourse is an open-source discussion platform. V

    Related Posts

    News & Updates

    Microsoft Copilot is “pretty important” but customers still prefer ChatGPT — “OpenAI has done a tremendous job”

    June 25, 2025
    News & Updates

    Will you sync your Windows 10 PC data to the cloud for free access to security updates beyond 2025?

    June 25, 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-50201 – WeGIA Web Manager OS Command Injection Vulnerability

    Common Vulnerabilities and Exposures (CVEs)

    CVE-2025-49445 – WP Map Plugins Interactive UK Regional Map CSRF Vulnerability

    Common Vulnerabilities and Exposures (CVEs)

    Europol Issues Public Alert: ‘We Will Never Call You’ as Phone and App Scams Surge

    Development

    SyncSDE: A Probabilistic Framework for Task-Adaptive Diffusion Synchronization in Collaborative Generation

    Machine Learning

    Highlights

    CVE-2025-6293 – Code-projects Hostel Management System SQL Injection

    June 19, 2025

    CVE ID : CVE-2025-6293

    Published : June 20, 2025, 1:15 a.m. | 1 hour, 25 minutes ago

    Description : A vulnerability was found in code-projects Hostel Management System 1.0 and classified as critical. This issue affects some unknown processing of the file /contact_manager.php. The manipulation of the argument student_roll_no leads to sql injection. The attack may be initiated remotely. The exploit has been disclosed to the public and may be used.

    Severity: 7.3 | HIGH

    Visit the link for more details, such as CVSS details, affected products, timeline, and more…

    This Spotlight alternative for Mac is my secret weapon for AI-powered search

    June 4, 2025

    CVE-2025-48236 – Bunny.net Cross-site Scripting (XSS)

    May 19, 2025

    CVE-2025-5272 – Firefox Memory Corruption Vulnerability

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

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