Visitar URL original
Compatibility with the proposed CSS if function · Issue #3886 · sass/sass · GitHub
Skip to content

Compatibility with the proposed CSS if function #3886

Open

Description

@stof

The CSSWG has resolved working on inline conditionals for CSS. For now, the proposed syntax uses a if() function.
See https://lea.verou.me/blog/2024/css-conditionals/ and w3c/csswg-drafts#10064

Even though the syntax is not yet final (the proposal has just started), the current syntax will require adjustments in Sass:

The work on this proposal should be tracked to figure out how the compatibility layer should look like.

Activity

  1. nex3 commented on Feb 25, 2025

    @nex3
    Contributor

    This is going to be a tricky one to handle. Although the CSS syntax is in and of itself strictly distinct from valid Sass, users may expect to be able to use SassScript expressions in it directly, at which point you have an ambiguity: if($condition: a, $if-true: b, $if-false: c) is currently valid Sass, but could also be parsed as an invocation of the CSS function with variables being used as the conditions.

    I think probably the correct solution here is to treat this as a special function and fall back on parsing it as a declaration value if the SassScript parse fails. This would mean that, when writing it as a CSS function, interpolation must be used to inject Sass variables, but that's probably for the best anyway so we don't have to keep up with the precise internal syntax. But it does also mean that if a user writes slightly-invalid Sass code in if(), it'll produce invalid CSS instead of eagerly emitting an error.

    It's possible we should find another way to handle ternary expressions in Sass. I see a few options:

    1. Put it in sass:meta. Historically we haven't done this in part because it feels like a "language feature" in the same way ternary operators are in other languages, and in part because we parsed it as its own syntax which is very difficult to do with functions in modules. However, the latter at least is mitigated by the technology we developed for interpreting ASTs differently when a function is determined to be a math function, so it's probably feasible to put it in sass:meta now.

    2. Add something syntactically unambiguous to mark it as a Sass function, such as requiring the $condition argument to be passed by name. This seems needlessly verbose, but it is an option.

    3. Parse the full CSS syntax and integrate Sass behavior into it. For example, we could do something like if(sass($var): a, else: b). This has the significant downside of requiring us to stay abreast of compatibility changes in the function syntax, though.

    All told, I think the sass:meta option is probably the best.

  2. stof commented on Jun 13, 2025

    @stof
    ContributorAuthor

    Chrome 137 has now shipped support for the if function.

  3. nex3 commented on Aug 29, 2025

    @nex3
    Contributor

    Thinking about this more, I think I'm coming around to option 3: supporting Sass in the context of the CSS syntax. This is undoubtedly more complex, but it avoids making Sass conditionals substantially more cumbersome to use than CSS conditionals while also ensuring that CSS conditionals are handled gracefully. To mitigate the cost of supporting future syntactic innovations in CSS, we'll treat all functional syntax in the <if-test> production that doesn't start with sass( as having an opaque value that requires interpolation to inject SassScript into, and similarly we will not allow raw variables on the left-hand side of the : because it doesn't generally follow value syntax (and in particular, it allows <boolean-expr> logic which would be evaluated substantially differently as SassScript).

    The right-hand side will allow full SassScript expressions, since it's expected to be injected into a declaration. (This is narrower than CSS, which allows any <declaration-value>?; however, in practice these values will produce compute-time invalid results unless they're normal property values. As usual, we'll treat if()s in custom property values as opaque token sequences rather than resolving them as SassScript.)

  4. self-assigned this
    on Aug 29, 2025
  5. added and removed
    awaiting browser supportBlocked on at least one browser implementing something
    on Aug 29, 2025
  6. nex3 commented on Sep 2, 2025

    @nex3
    Contributor

    Since this is a substantial change and involves backwards-incompatibility, I'll give it a month for public comment (more if there's substantial discussion).

  7. brandonmcconnell commented on Sep 2, 2025

    @brandonmcconnell

    @nex3 I considered the unambiguous route as well with scoped functions like sass:if() or a shorthand like $if() or $$if() and making $/$$-prefixed functions and variables reserved, like Svelte does.

    That aside, I think the "option 3" you mentioned sounds fine as well.

  8. nex3 commented on Nov 5, 2025

    @nex3
    Contributor

    @brandonmcconnell Sorry for the late response. The problem with shorthands like that is that there's no guarantee that CSS doesn't start using something that's ambiguous with the shorthand syntax as well. The only truly safe thing to do would be to prefix every Sass feature with -sass-, since that's explicitly reserved for vendor-specific behavior, but doing so is as cumbersome (if not more) than needing to @use a core library.

  9. mirisuzanne commented on Dec 16, 2025

    @mirisuzanne
    Contributor

    There's an additional regression here. I'm not sure if it was intended? Previously, the arguments would only evaluate if they were used. The following works with the original syntax, but fails with the updated syntax:

    @use 'sass:meta';
    @use 'sass:string';
    
    .test {
      // works, but deprecated
      old: if(
        meta.type-of($test) == 'string',
        string.index($test, 'a'),
        'no $test'
      );
      // $string: null is not a string.
      new: if(
        sass(meta.type-of($test) == 'string'): string.index($test, 'a'); 
        else: 'no $test'
      );
    }
  10. mirisuzanne commented on Dec 16, 2025

    @mirisuzanne
    Contributor

    Even if it's intended, this should be documented in the breaking change info. The migrator currently isn't helpful here, and it has to be handled manually.

  11. nex3 commented on Dec 17, 2025

    @nex3
    Contributor

    That's definitely not intended, and I would have sworn we had a test for it. I'll check it out.

  12. omidantilong commented on Dec 18, 2025

    @omidantilong

    Hello 👋 Long time sass-user here. Let me preface this by saying thanks for all the love that goes into maintaining this project.

    We've just started getting the deprecation warnings in one of our projects. However, it seems like vscode doesn't know what to do with the native if() syntax yet? Using the example from this page, I'm getting the following issues:

    $hungry: true;
    
    @debug if(sass($hungry): breakfast burrito; else: cereal);
    
    ) expected scss(css-rparentexpected) [Col 24] (the first colon)
    { expected scss(css-lcurlyexpected) [Col 43] (the first semi-colon)
    { expected scss(css-lcurlyexpected) [Col 49] (the second colon)
    

    However, just using an example off the MDN if() docs page, it's also not happy:

    if(supports(color: green): red;)
    
    at-rule or selector expected scss(css-ruleorselectorexpected) [Col 1]
    { expected scss(css-lcurlyexpected) [Col 18] (the first colon)
    at-rule or selector expected scss(css-ruleorselectorexpected) [Col 80]
    

    So this doesn't appear to be entirely sass-related. I think VSCode has built-in support for the deprecated syntax, but with sass now pushing the warnings out, I expect folks might start running into the same problem until the new syntax is supported in vscode?

    (It's entirely possible I'm doing something daft. If you've encountered this yourself any tips would be appreciated!)

    Thanks ❤️

  13. stof commented on Dec 18, 2025

    @stof
    ContributorAuthor

    @omidantilong this should be reported to VSCode (or to the VSCode extension adding Sass support if this is not from core). The Sass team is not the one maintained the support of Sass in VSCode (and even less the support for CSS)

  14. omidantilong commented on Dec 18, 2025

    @omidantilong

    @stof oh for sure, it is almost definitely a VSCode issue. I was highlighting it here because I think people who have only ever used the old Sass if syntax and not the native css if (such as myself!) will now start getting this error when using the "Suggested" fix in the console output, because Sass has started pushing those warnings and suggested fixes.

    I agree it's not Sass's responsibility to fix the editor issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions