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

      Designing With AI, Not Around It: Practical Advanced Techniques For Product Design Use Cases

      August 11, 2025

      Why Companies Are Investing in AI-Powered React.js Development Services in 2025

      August 11, 2025

      The coming AI smartphone: Redefining personal tech

      August 11, 2025

      Modern React animation libraries: Real examples for engaging UIs

      August 11, 2025

      How Debian 13’s little improvements add up to the distro’s surprisingly big leap forward

      August 11, 2025

      Why xAI is giving you ‘limited’ free access to Grok 4

      August 11, 2025

      How Apple may revamp Siri to a voice assistant I’d actually use (and ditch Gemini for)

      August 11, 2025

      I jump-started a bus from the 1930s with this power bank – here’s the verdict

      August 11, 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

      Laravel’s UsePolicy Attribute: Explicit Authorization Control

      August 11, 2025
      Recent

      Laravel’s UsePolicy Attribute: Explicit Authorization Control

      August 11, 2025

      The Laravel Way to Build AI Agents That Actually Work

      August 11, 2025

      The Laravel Way to Build AI Agents That Actually Work

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

      Microsoft sued over killing support for Windows 10

      August 11, 2025
      Recent

      Microsoft sued over killing support for Windows 10

      August 11, 2025

      Grok 4 rolled out for free-tier users worldwide, with some limits

      August 11, 2025

      Firefox AI slammed for hogging CPU and draining battery

      August 11, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»News & Updates»Lightly Poking at the CSS if() Function in Chrome 137

    Lightly Poking at the CSS if() Function in Chrome 137

    June 24, 2025

    We’ve known it for a few weeks now, but the CSS if() function officially shipped in Chrome 137 version. It’s really fast development for a feature that the CSSWG resolved to add less than a year ago. We can typically expect this sort of thing — especially one that is unlike anything we currently have in CSS — to develop over a number of years before we can get our dirty hands on it. But here we are!

    I’m not here to debate whether if() in CSS should exist, nor do I want to answer whether CSS is a programming language; Chris already did that and definitely explained how exhausting that fun little argument can be.

    What I am here to do is poke at if() in these early days of support and explore what we know about it today at a pretty high level to get a feel for its syntax. We’ll poke a little harder at it in another upcoming post where we’ll look at a more heady real-world example.

    Yes, it’s already here!

    Conditional statements exist everywhere in CSS. From at-rules to the parsing and matching of every statement to the DOM, CSS has always had conditionals. And, as Lea Verou put it, every selector is essentially a conditional! What we haven’t had, however, is a way to style an element against multiple conditions in one line, and then have it return a result conditionally.

    The if() function is a more advanced level of conditionals, where you can manipulate and have all your conditional statements assigned to a single property.

    .element {
      color: if(style(--theme: dark): oklch(52% 0.18 140); else: oklch(65% 0.05 220));
    }
    CodePen Embed Fallback

    How does if() work?

    Well before Chrome implemented the feature, back in 2021 when it was first proposed, the early syntax was like this:

    <if()> = if( <container-query>, [<declaration-value>]{1, 2} )

    Now we’re looking at this instead:

    <if()> = if(
      [<if-statement>: <result>]*;
      <if-statement>: <result> ;?
    )

    Where…

    • The first <if-statement> represents conditions inside either style(), media(), or supports() wrapper functions. This allows us to write multiple if statements, as many as we may desire. Yes, you read that right. As many as we want!
    • The final <if-statement> condition (else) is the default value when all other if statements fail.

    That’s the “easy” way to read the syntax. This is what’s in the spec:

    <if()> = if( [ <if-branch> ; ]* <if-branch> ;? )
    <if-branch> = <if-condition> : <declaration-value>?
    <if-condition> = <boolean-expr[ <if-test> ]> | else
    <if-test> =
      supports( [ <ident> : <declaration-value> ] | <supports-condition> )
      media( <media-feature> | <media-condition> ) |
      style( <style-query> )

    A little wordy, right? So, let’s look at an example to wrap our heads around it. Say we want to change an element’s padding depending on a given active color scheme. We would set an if() statement with a style() function inside, and that would compare a given value with something like a custom variable to output a result. All this talk sounds so complicated, so let’s jump into code:

    .element {
      padding: if(style(--theme: dark): 2rem; else: 3rem);
    }

    The example above sets the padding to 2rem… if the --theme variable is set to dark. If not, it defaults to 3rem. I know, not exactly the sort of thing you might actually use the function for, but it’s merely to illustrate the basic idea.

    Make the syntax clean!

    One thing I noticed, though, is that things can get convoluted very very fast. Imagine you have three if() statements like this:

    :root {
      --height: 12.5rem;
      --width: 4rem;
      --weight: 2rem;
    }
    
    .element {
      height: if(
        style(--height: 3rem): 14.5rem; style(--width: 7rem): 10rem; style(--weight: 100rem): 2rem; else: var(--height)
      );
    }

    We’re only working with three statements and, I’ll be honest, it makes my eyes hurt with complexity. So, I’m anticipating if() style patterns to be developed soon or prettier versions to adopt a formatting style for this.

    For example, if I were to break things out to be more readable, I would likely do something like this:

    :root {
      --height: 12.5rem;
      --width: 4rem;
      --weight: 2rem;
    }
    
    /* This is much cleaner, don't you think? */
    .element {
      height: if(
        style(--height: 3rem): 14.5rem; 
        style(--width: 7rem): 10rem; 
        style(--weight: 100rem): 2rem; 
        else: var(--height)
      );
    }

    Much better, right? Now, you can definitely understand what is going on at a glance. That’s just me, though. Maybe you have different ideas… and if you do, I’d love to see them in the comments.

    Here’s a quick demo showing multiple conditionals in CSS for this animated ball to work. The width of the ball changes based on some custom variable values set. Gentle reminder that this is only supported in Chrome 137+ at the time I’m writing this:

    CodePen Embed Fallback

    The supports() and media() statements

    Think of supports() the same way you would use the @supports at-rule. In fact, they work about the same, at least conceptually:

    /* formal syntax for @supports */
    @supports <supports-condition> {
      <rule-list>
    }
    
    /* formal syntax for supports() */
    supports( [ <ident> : <declaration-value> ] | <supports-condition> )

    The only difference here is that supports() returns a value instead of matching a block of code. But, how does this work in real code?

    The <ident>: <declaration-value> you see here is, in this case, the property name: property value e.g. display: flex.

    Let’s say you want to check for support for the backdrop-filter property, particularly the blur() function. Typically, you can do this with @supports:

    /* Fallback in case the browser doesn't support backdrop-filter */
    .card {
      backdrop-filter: unset;
      background-color: oklch(20% 50% 40% / 0.8);
    }
    
    @supports (backdrop-filter: blur(10px)) {
      .card {
        backdrop-filter: blur(10px);
        background-color: oklch(20% 50% 40% / 0.8);
      }
    }

    But, with CSS if(), we can also do this:

    .card {
      backdrop-filter: if(
        supports(backdrop-filter: blur(10px)): blur(10px);
        else: unset
      );
    }

    Note: Think of unset here as a possible fallback for graceful degradation.

    That looks awesome, right? Multiple conditions can be checked as well for supports() and any of the supported functions. For example:

    .card {
      backdrop-filter: if(
        supports(backdrop-filter: blur(10px)): blur(10px);
        supports(backdrop-filter: invert(50%)): invert(50%);
        supports(backdrop-filter: hue-rotate(230deg)): hue-rotate(230deg);;
        else: unset
      );
    }

    Now, take a look at the @media at-rule. You can compare and check for a bunch of stuff, but I’d like to keep it simple and check for whether or not a screen size is a certain width and apply styles based on that:

    h1 {
      font-size: 2rem;
    }
    
    @media (min-width: 768px) {
      h1 {
        font-size: 2.5rem;
      }
    }
    
    @media (min-width: 1200px) {
      h1 {
        font-size: 3rem;
      }
    }

    The media() wrapper works almost the same way as its at-rule counterpart. Note its syntax from the spec:

    /* formal syntax for @media */
    @media <media-query-list> {
      <rule-list>
    }
    
    /* formal syntax for media() */
    media( <media-feature> | <media-condition> )

    Notice how at the end of the day, the formal syntax (<media-query>) is the same as the syntax for the media() function. And instead of returning a block of code in @media, you’d have something like this in the CSS inline if():

    h1 {
      font-size: if(
        media(width >= 1200px): 3rem;
        media(width >= 768px): 2.5rem;
        else: 2rem
      );
    }

    Again, these are early days

    As of the time of this writing, only the latest update of Chrome supports if()). I’m guessing other browsers will follow suit once usage and interest come in. I have no idea when that will happen. Until then, I think it’s fun to experiment with this stuff, just as others have been doing:

    • The What If Machine: Bringing the “Iffy” Future of CSS into the Present (Lee Meyer)
    • How To Correctly Use if() In CSS (Temani Afif)
    • Future-Proofing Indirect Cyclical Conditions (Roma Komarov)
    • The new if() function in CSS has landed in the latest Chrome (Amit Merchant)

    Experimenting with early features is how we help CSS evolve. If you’re trying things out, consider adding your feedback to the CSSWG and Chromium. The more use cases, the better, and that will certain help make future implementations better as well.

    Now that we have a high-level feel for the if()syntax, we’ll poke a little harder at the function in another article where we put it up against a real-world use case. We’ll link that up when it publishes tomorrow.


    Lightly Poking at the CSS if() Function in Chrome 137 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 ArticleXiaomi’s Interoperability App Vulnerability Let Hackers Gain Unauthorized Access to the Victim’s Device
    Next Article MuseAmp is an audio normalizer for MP3/FLAC

    Related Posts

    News & Updates

    How Debian 13’s little improvements add up to the distro’s surprisingly big leap forward

    August 11, 2025
    News & Updates

    Why xAI is giving you ‘limited’ free access to Grok 4

    August 11, 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

    Scalable Reinforcement Learning with Verifiable Rewards: Generative Reward Modeling for Unstructured, Multi-Domain Tasks

    Machine Learning

    How to Optimize Sitecore Headless and Next.js on Vercel

    Development

    Community News: Latest PEAR Releases (04.07.2025)

    Development

    La Germania si impegna ad adottare l’Open Document Format

    Linux

    Highlights

    The Turing Test has a problem – and OpenAI’s GPT-4.5 just exposed it

    April 4, 2025

    GPT-4.5 just aced the Turing Test, but it’s still not AGI. Now what? Source: Latest…

    CVE-2025-3825 – SourceCodester Web-based Pharmacy Product Management System Cross-Site Scripting Vulnerability

    April 20, 2025

    CVE-2022-44618 – Apache HTTP Server Remote Code Execution Vulnerability

    May 28, 2025

    20+ Stylish Swedish Fonts With Scandinavian Simplicity

    August 4, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

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