GithubHelp home page GithubHelp logo

Comments (70)

LeaVerou avatar LeaVerou commented on September 17, 2024 9

I'd like to express my strong agreement with @upsuper, @Marat-Tanalin and @bradkemper above in favor of @if over @when.

  1. Consistency with every other language authors may have used
  2. As has been repeatedly mentioned, we should not be designing CSS, a language that needs to last decades and for which the burden of changes is incredibly high, based on conflicts with a preprocessor that happens to be in use today (and is already giving way to others, e.g. PostCSS). Preprocessors can adapt far more easily than CSS, and any third-party project ultimately has far fewer users than CSS. Many solutions for Sass have been suggested in this very thread.
  3. Preprocessors are not executed on every page load, so it's far easier for Sass authors to migrate to a new syntax at their own time. This is not like the issue TC39 faced with array.contains() at all.

Note: @if is used quite heavily: about 63% of Sass stylesheets use it. But even if it was used in 100% of them we should not design CSS around Sass.

from csswg-drafts.

bradkemper avatar bradkemper commented on September 17, 2024 8

I strongly prefer @if, @else, and @else-if. It would be clear and obvious for most authors, and SASS could easily adapt.

Level 5 at this point.

from csswg-drafts.

tabatkins avatar tabatkins commented on September 17, 2024 6

If we're wanting to start doing this kind of thing, people will want to do things like, say, test for both an @media and an @supports, and then have a block of code for when they're both true and both false. This means we'll want to make them combinable in a reasonable way.

Maybe instead, we just explicitly create an @if block, which can take media() and supports() conditions (like what we have for @import statements). @media/@supports would then just be special-case versions that let you write slightly shorter blocks when you only need one or the other type. Then @else (and @else-if) can be blocks that have to follow an @if or equivalent.

That is, you can start an if-chain with an @if, @media, or @supports block, then continue it with zero or more @else-if blocks (with grammar identical to @if), then an optional final @else block with no condition. You can be guaranteed that exactly one of the blocks in the chain will be evaluated.

from csswg-drafts.

tabatkins avatar tabatkins commented on September 17, 2024 6

The reason I didn't like @switch equivalents is that it still only lets you test on a single type of conditional at a time. If you want to test for a MQ and an SQ, or else do something else, you can't write that reasonably in @switch.

That is:

@switch {
  @media A {
    @supports B {
      /* code intended for (A && B) */
    }
  }
  @media not A {
    /* code intended for (!A) 
       aka (!A && B) or (!A && !B) */
  }
  @default {
    /* code intended for (A && !B),
       the leftover case */
  }
}

will never run the @default block (because the two top-level rules fully cover A and not A), even if the intention is to have it contain code for when A is true but B is false.

Versus when/else, which would handle it well:

@when media(A) and supports(B) {
  /* (A && B) */
}
@else media(not A) {
  /* (!A), which is (!A && B) || (!A && !B) */
}
@else {
  /* (A && !B) */
}

I don't think it's possible to mod @switch into doing this, because the top-level rules aren't constrained to contain only a single child conditional; it could have several, so you can't easily tell what cases it's supposed to cover (and thus what "default" should cover).

from csswg-drafts.

frivoal avatar frivoal commented on September 17, 2024 5

@Marat-Tanalin, I take it to mean something like this:

@if media((width >= 400px) and (pointer: fine)) and supports(display: flex) {
   ...
}
@else-if supports((caret-color: pink) or (background: double-rainbow()){
  ...
}
@else {
  ...
}

from csswg-drafts.

svgeesus avatar svgeesus commented on September 17, 2024 5

Adding my agreement to call this @if not @when.

I recall that the Sass maintainers have explicitly stated that CSS should not avoid a good syntax just because Sass uses it; they are very willing to change so that CSS can get better.

from csswg-drafts.

svgeesus avatar svgeesus commented on September 17, 2024 5

The CSS Working Group just discussed Nesting @supports inside @font-face / font tech queries, and agreed to the following:

  • RESOLVED: Adopt if/else as next level of css-conditional
  • RESOLVED: Accept the PR
The full IRC log of that discussion <fantasai> Topic: Nesting @supports inside @font-face / font tech queries
<fantasai> github: https://github.com//issues/6520
<fantasai> chris: Basic problem is that we need a way to ensure that only one of the possible options works
<fantasai> chris: if you have unicode-range and a character outside that range, all the others will be loaded to see if it has that char
<fantasai> chris: so this has been paired with another issue
<fantasai> chris: It seems we need to discuss together
<fantasai> lea: Looks like primary problem with using @supports is that pattern
<fantasai> lea: of older code being unwrapped, but wrapping new code in @supports
<fantasai> lea: but that doesn't work well with @font-face
<fantasai> lea: because the second rule doesn't override the first rule
<fantasai> lea: they combine to form a single family
<fantasai> lea: although normally only second font is used
<chris> q+ to add that the existing format overload does have the "only one wins" characteristic
<fantasai> lea: if browser encounters character not in the second, it will download the first to check if it is there
<fantasai> lea: so for this we would need an else condition
<fantasai> lea: so that we never have both @font-face rules in effect at the same time
<fantasai> lea: There's a proposal from Tab to combine feature queries and media queries, and has else
<drott> q+
<fantasai> lea: Tab suspects it's easy to implement
<fantasai> lea: if this can be implemented together with font-technology(), that would be nice
<fantasai> lea: concern that if implement without it, we'll have this problematic pattern
<astearns> ack chris
<Zakim> chris, you wanted to add that the existing format overload does have the "only one wins" characteristic
<fantasai> chris: Overloading the format string does have this benefit of combining the conditionals properly
<lea> q?
<fantasai> chris: if we don't rapidly converge, we'll be stuck with that
<fantasai> astearns: So you're concerned to get if/else quickly so that practice doesn't ossify into bad syntax
<fantasai> chris: people will just ship what's in the spec now
<fantasai> myles: I thought we would remove the complicated resource grammar
<astearns> ack drott
<fantasai> drott: I spoke to implementers, to Anders and Rune who are familiar with our CSS code
<fantasai> drott: They have no immediate concerns with the when/else proposal
<fantasai> drott: Which brings my question of timing
<chris> \0/ to no concerns!
<fantasai> drott: I'm also supportive of removing the syntax in the spec now
<fantasai> drott: but eager to have something to enable font tech feature testing atm
<fantasai> drott: We're supportive of the when/else proposal, but it would be better to have font tech queries soon and maybe when/else as an upgrade path
<fantasai> astearns: Is it possible to have a font-tech syntax in the @font-face that would handle the conditional?
<fantasai> drott: Current feature in spec is encapsulated in src descriptor
<fantasai> drott: in the format() function
<fantasai> drott: Authors can order it by most advanced tech, and then the UA will pick the one that it supports
<fantasai> drott: In current proposal, without @else we have an accumulation of fonts into the family
<lea> astearns: https://drafts.csswg.org/css-fonts-4/#font-face-src-parsing
<lea> ^ that is the current syntax
<fantasai> astearns: Would it be possible to have a limited state for this font technology where you could put it into your @font-face and have a font face exist if the font technology was supported, but have it not exist if it wasn't
<fantasai> astearns: no fallback, just make this font face if the tech is supported
<fantasai> drott: You could use different families
<fantasai> lea: If you don't want fallback, that's fine. You just make an @font-face
<fantasai> astearns: so wanted to remove things from spec, remove the current syntax
<fantasai> astearns: in favor of clearer if/else
<fantasai> astearns: but people still want conditional on font
<fantasai> astearns: and it would be nice to have that font tech
<fantasai> chris: we need to do both
<fantasai> chris: for a solution
<drott> fantasai: I think we had previous notes on this, can't find it
<drott> fantasai: it was basically: we should have both, the font-technology function in @supports, and the ability to query the tech in the format function, and they should share the syntax. And the syntax should be simpler.
<astearns> s/would handle the conditional/would not handle the conditional with fallback/
<chris> q+
<drott> fantasai: for @supports, you might want to query not only if it's color, but you might want to query for format
<drott> fantasai: I would simplify the syntax of the font-technology function.
<drott> q+
<drott> fantasai: In a way to remove the sub functions, and just have a list of keywords, for example font-format-...
<fantasai> fantasai: ....
<fantasai> drott: I think you did post it somewhere, I had updated my pull request to flatten it...
<fantasai> chris: ...
<drott> q-
<lea> q?
<lea> q+
<fantasai> chris: The format shouldn't be the orphan that gets left behind that you have to do in src, it should be same conditional thing that we do in font-technology
<fantasai> chris: so if woff5 comes along, we can also put that in this new shiny syntax
<astearns> ack chris
<drott> fantasai: it should be the same function, for format and font technology
<chris> I don't really like calling it font-format
<fantasai> lea: If I understand correctly, a format should also have been a condition in @supports
<chris> yes exactly lea
<fantasai> lea: if designing today that's how we would do that
<fantasai> lea: only reason we have format function is that it's legacy
<chris> we can't get *rid* of the format legacy though, so it has to remain in the spec
<fantasai> lea: so I think what Chris is saying is that we also need to be adding a font-format() function into @supports so that authors can combine @font-technology queries
<fantasai> lea: whereas what fantasai is saying is to have only format() function, and have it allowed both in src and @supports
<fantasai> s/chris: .../lea: I think that was my proposal to flatten from color() to color-/
<fantasai> astearns: So we're looking for a way to express simper supports queries in @font-face rules
<fantasai> astearns: and remove fallback ability
<drott> fantasai: I think we're not aiming to remove fallback
<fantasai> chris: The things that drott proposed, it would be helpful to allow that as a direct query in @supports conditions
<fantasai> myles: I think adding that should be blocked on having some way of solving the problem that jfkthame described
<drott> q+
<astearns> ack lea
<fantasai> astearns: ?
<fantasai> lea: No way to do else, so authors will need to negate their queries
<fantasai> lea: and it would get very verbose and complicated
<fantasai> myles: not even sure if it's possible
<fantasai> myles: because there's a third value here, not just supported or not supported, but also case of "browser doesn't know what you're talking about"
<fantasai> chris: So need a resolution on proposal, but also how do we move forward on Tab's draft
<fantasai> chris: Can we adopt it as an ED?
<fantasai> myles: We should split this font-specific issue
<fantasai> myles: one piece blocked on else rule and one that isn't
<drott> q?
<fantasai> myles: and discuss else rule in its own CSSWG issue
<astearns> ack drott
<fantasai> drott: I discussed this issue with jfkthame offline. I think he's here?
<chris> this is its issue: https://github.com//issues/112
<fantasai> drott: In our question, jfkthame expressed some flexibility regarding timing
<fantasai> drott: I'd like to emphasize what chris was saying earlier, if we move the supports syntax from CSS as it is now, then we don't have anything to do feature testing
<fantasai> drott: I consider @supports an upgrade path
<fantasai> myles: I've heard some people say they want to remove unimplemented flexbility in the spec now, and others don't want to remove it but to reformulate to make it simpler
<fantasai> myles: either one is reasonable to me
<fantasai> lea: which part is blocked on what?
<fantasai> myles: If we want to keep the unimplemented features of the format() in src, we wouldn't need to be blocked on else
<TabAtkins> It is true that `@supports unknown-font-thing() {...} @support not (unknown-font-thing()) {...}` will fail to match both of them (the first is unknown, treated as false; the second is negated unknown, which is still unknown and thus treated as false)
<fantasai> lea: the problem with that is that we don't want microsyntaxes
<TabAtkins> whereas `@support unknown-font-thing() {...} @else {...}` would match one or the other, guaranteed.
<lea> q+
<astearns> ack lea
<fantasai> lea: Important point from the issue drott raised hasn't be raised yet
<fantasai> lea: else is syntactic sugar for negation
<fantasai> lea: but another way to work around is to use unicode-range
<fantasai> lea: drott mentioned that most font-face rules are generated, and have unicode-range alreay
<fantasai> lea: which means this isn't a problem
<fantasai> myles: unicode-range is an orthogonal feature
<TabAtkins> Oh wait, sorry, I was wrong - @supports doesn't use the unknown value.
<fantasai> myles: if author is trying to use fancy syntax that is / isn't supported
<TabAtkins> We resolved on that a bit ago.
<fantasai> myles: both @font-face rule and fallback will have the same unicode-range
<TabAtkins> Unknown things are just false in @supports.
<fantasai> myles: so the problem still applies
<fantasai> lea: Problem is if the character is not included in the range
<fantasai> myles: problem that I'm concerned about is that character is inside the unicode-range block, but not supported by the font's CMAP table
<fantasai> myles: in that case the browser will download both fonts serially
<fantasai> drott: Should have unicode-range identical to CMAP
<TabAtkins> So my statement above was wrong - both are equivalent, and you'll definitely select one or the other. (We use unknown for @media, where the browser very well *might* match an unknown query once it starts supporting it; a browser that doesn't understand a feature, by definition, doesn't support it, so that's a safe `false`.)
<drott> fantasai: Lea was concerned about multiple different microsyntaxes. My proposal doesn't do that. Format function, should have identical syntax, whether it's in src: or in @supports.
<lea> q+
<astearns> ack fantasai
<drott> fantasai: If that's the case, we can ship src: first - ship @supports version later.
<drott> q+
<astearns> ack lea
<fantasai> lea: There's another unexplored option
<fantasai> lea: what if we had an inline conditional function that does supports queries
<fantasai> lea: A supports() or supports-if() function to put inside any value
<fantasai> astearns: I think it would be a good idea to write down what you're suggesting, Lea
<fantasai> astearns: but getting a proliferation of options, unsure we can get to resolution on anything specific today
<astearns> ack drott
<fantasai> astearns: I think we can resolve at least that we would like to work on the if/else syntax
<fantasai> TabAtkins: Adopt as an ED in the WG? Currently draft in my personal repo
<lea> +1 to working on @else proposal
<jfkthame> +1
<fantasai> astearns: resolution would be to adopt, yes
<fantasai> fantasai: so that would be css-conditional-3?
<fantasai> TabAtkins: sure
<drott> q+
<astearns> ack drott
<fantasai> drott: potentially add any resolution, then idea would be to have a font-tech function to combine with that?
<TabAtkins> I also was udner the impression that Conditional started with 1.
<fantasai> dbaron[m]: I think conditional-3 is already advanced
<drott> +1 to that.
<fantasai> fantasai: oh, I meant whatever's next
<drott> sorry, fantasai, I did not capture what you said.
<fantasai> RESOLVED: Adopt if/else as next level of css-conditional
<fantasai> astearns: So question of current font-technology draft and reworking them with existence of if/else in mind
<fantasai> astearns: so take back to issue to determine what changes, if any, need to be made
<fantasai> chris: I don't see a dependency there
<fantasai> chris: I think we can adopt PR as-is
<drott> +1 as well
<fantasai> lea: +1
<fantasai> lea: this is something useful immediately
<TabAtkins> +1
<drott> zes
<fantasai> astearns: Adopting PR will resolve the issue?
<drott> s/zes/yes
<fantasai> lea: the bulk of it
<fantasai> astearns: And we can open new more tightly constrianed issues
<fantasai> astearns: So proposed resolution?
<fantasai> drott: Adds font-technology() function to @supports, which has a flat list of font technologies and options, which can be used inside an @supports rule
<drott> https://github.com/drott/csswg-drafts/commit/62cfd95a5f52604c952e4aa37be6e4d6386f88f5
<fantasai> myles: the @else rule should make it clear that it works with this new query inside @supports
<fantasai> myles: either explicitly or implicitly
<fantasai> myles: And i'd ask implementers not to implement font-technology() without @else
<fantasai> myles: because if you oonly give ability to do it wrong, people will do it wrong
<fantasai> lea: why?
<dbaron[m]> That request to implementers should be �in the spec�.
<fantasai> myles: because @else is the solution to this problem, so one depends on the other
<jensimmons> +1 to myles
<lea> s/lea: why?/lea: they can still do it right, it's just tedious/
<drott> fantasai: I am not sure, I agree with this particular PR.
<dbaron[m]> s/sure,/sure/
<drott> fantasai: I think the function should have identical syntax to what we should have in src:.
<drott> q+
<drott> fantasai: one question I have: font-technology - would this be allowed to be queries in src:?
<drott> s/queried/queries
<drott> s/queried/queries/
<fantasai> astearns: I think we should merge it in and take separate issues
<fantasai> chris: I edit both specs anyway
<drott> +1 to that, if we can have the font-technology PR
<fantasai> myles: but if we're making src less flexible than it is to day (in ths spec)
<astearns> ack drott
<fantasai> fantasai: happy to do so, as long as we can work on it and not just ship what's in the PR
<chris> @drott I see the PR on your fork repo but not the one on the csswg repo
<fantasai> myles: I think it's OK to resolve this, I think fantasai's idea about making them match makes sense to me
<fantasai> myles: I think making them match gives drott a path to implementing that doesn't rely on us standadizing a big new feature
<fantasai> myles: so I think that's the best path forward
<fantasai> astearns: we're not got to solve everything today
<fantasai> astearns: so let's merge the PR and file more issues
<drott> +1
<lea> +1
<chris> +1
<fantasai> astearns: any objections?
<fantasai> RESOLVED: Accept the PR
<chris> :)
<fantasai> myles: Can we add a note to the PR to say "don't implement this yet, implement this other thing first"
<fantasai> astearns: open an issue

from csswg-drafts.

Marat-Tanalin avatar Marat-Tanalin commented on September 17, 2024 4

Yeah, Sass usage does not trump CSS. But there's also no reason to be hostile to the developer community when we can easily avoid such.

Replacing the clear straightforward keyword widely used in almost all languages with an invented more-or-less similar one is actually probably not that easy.

At the same time, SASS (as well as any other preprocessor) could really easily rename its @if or just transparently convert something like @css-if or @native-if to native CSS @if. That’s not a CSS problem at all.

CSSWG decisions should probably not be based on the goal of avoiding preprocessor conflicts. CSS is a much more fundamental thing that require carefully weighed decisions reasonable and usable in the long term. Preprocessors can be changed at any time, CSS cannot at all.

Or are you asking why we don't just extend @media to have the full value set that I've defined @when to have?

This one.

it would be weird; there's nothing media-like about supports queries

We already have not quite media-related things like scripting in media queries. After all, extending @media is (except for placing @else as a subrule) what Florian has initially proposed.

It also would make the grammar very complicated.

I’m not sure why this:

@media ((width >= 400px) and (pointer: fine)) and supports(display: flex) {}

would be more complicated than this (at least from author’s [not spec writer’s] perspective):

@if media((width >= 400px) and (pointer: fine)) and supports(display: flex) {}

The media code could even be simpler without redundant parens:

@media (width >= 400px) and (pointer: fine) and supports(display: flex) {}

from csswg-drafts.

heycam avatar heycam commented on September 17, 2024 4

Another option if we want to avoid the awkwardness of where the @else or @not would go is to have an at rule that contains all of the conditions to check. Strawperson:

@switch media {
  (min-width: 800px) { /* rules */ }
  (min-width: 600px) { /* rules */ }
  default { /* rules */ }
}

@switch supports {
  (color: rainbow) { /* rules */ }
  default { /* rules */ }
}

Not sure how well that works for backwards compat.

from csswg-drafts.

upsuper avatar upsuper commented on September 17, 2024 3

As a web developer, I'd prefer not putting it inside, which looks weird, and doesn't match the intuition from any other programming language.

As a browser developer, though, I'm concerned about how CSSOM should handle this.

Also I guess it makes sense to allow @else to precede another @media or @support, like a if-elseif structure. But that would likely make story of CSSOM more complicated.

from csswg-drafts.

Marat-Tanalin avatar Marat-Tanalin commented on September 17, 2024 3

Fwiw, in the past, a SASS developer said at www-style that existing features of SASS should not be considered as limitations for new CSS features in any way:

if a potential new CSS feature is conflicting with an existing SASS feature, then the latter could just be changed.

By the way, why not just extend @media to use it itself as @if?

from csswg-drafts.

heycam avatar heycam commented on September 17, 2024 3

(And maybe you'd want to just have a single @switch with both MQs and supports conditions inside it.)

from csswg-drafts.

xfq avatar xfq commented on September 17, 2024 3

Since @frivoal mentioned Lisp in #112 (comment) , as a developer who has written a lot of Lisp, I would like to mention that if and when are obviously different for many Lisp developers and the difference may cause some misunderstandings.

For example, in Common Lisp, if chooses between the then-form and the else-form based on the value of the test-form, while when is a variant of if where there are no else-form, and possibly several then-forms. (Other dialects like Racket and Clojure are the same.)

from csswg-drafts.

tabatkins avatar tabatkins commented on September 17, 2024 2

@fantasai I'd love to see an example of that - you're talking about mixing selectors and MQs, which isn't even on the table yet.


I've produced a draft spec for this at https://tabatkins.github.io/specs/css-when-else/. If we accept this, I intend it to be merged into Conditional.

from csswg-drafts.

upsuper avatar upsuper commented on September 17, 2024 2

I'd prefer @if... not very strongly, though.

I agree with @Marat-Tanalin that we should not pick a weird syntax just to avoid conflicting with a preprocessor, and preprocessors can always work around that easily, either via a breaking change stated in the release note or introducing a new keyword.

I can imagine that if we choose @when and @else-when, more developers would tend to critize that CSSWG is making their life harder via adding some syntax different than what they are familiar with, rather than appreciating the work of avoiding the imaginary breakage.

I think the criteria is, is there more web developers use SASS's @if than those who do not use SASS's @if (or do not use SASS at all) but familiar with the general if-else structure? What's the percentage?

from csswg-drafts.

upsuper avatar upsuper commented on September 17, 2024 2

This issue ring similar to the array.contains issue faced by TC39.

This isn't. The original Sass file before preprocessing is not processed directly by browsers.

However in the CSS of adopting an existing syntax there is no good work around for preprocessor authors. Best case they release a new major with a new syntax.

Workaround shouldn't be too hard. As @Marat-Tanalin mentioned, they can keep their existing @if and introduce a new keyword like @css-if which is converted to the CSS's @if during preprocessing. What's the problem with this workaround?

from csswg-drafts.

frivoal avatar frivoal commented on September 17, 2024 2

@glazou, yes, it sort of works, except that:

  1. when your MQ is long and complicated, that ends up being a lot of stuff to repeat, which is tedious at best, and a source of bugs when you make a mistake somewhere. You may get it right on the first pass, but it is decently likely that you'll make a mistake during maintenance by forgetting to update the second half.
  2. explicit negation works OKish for if/else, but it is even more tedious when you try to do some if / elseif / else.
  3. both branches are ignored if you do
@media screen and (unsupported-thing) { }
@media not screen and (unsupported-thing) { }

from csswg-drafts.

ExE-Boss avatar ExE-Boss commented on September 17, 2024 2

@upsuper #112 (comment)

As a web developer, I'd prefer not putting it inside, which looks weird, and doesn't match the intuition from any other programming language.

As a browser developer, though, I'm concerned about how CSSOM should handle this.

Also I guess it makes sense to allow @else to precede another @media or @support, like a if-elseif structure. But that would likely make story of CSSOM more complicated.

Well, an else-if statement is just:

if (a) {

} else {
  if (b) {

  }
}

from csswg-drafts.

frivoal avatar frivoal commented on September 17, 2024 2

It feels like @heycam's suggestion would also be gentler on the OM than an @if {} @else {}
Converting my earlier example:

@if media((width >= 400px) and (pointer: fine)) and supports(display: flex) {
   ...
}
@else-if supports((caret-color: pink) or (background: double-rainbow()){
  ...
}
@else {
  ...
}

becomes

@switch {
  media((width >= 400px) and (pointer: fine)) and supports(display: flex) {
     ...
  }
  supports((caret-color: pink) or (background: double-rainbow()){
    ...
  }
  default {
    ...
  }
}

This seems quite workable to me.

from csswg-drafts.

tabatkins avatar tabatkins commented on September 17, 2024 2

Yeah, @when is purely a way to combine an @supports and @media query together in a single conditional; without this, you have to nest and repeat yourself in a way that's both hard to write and hard to read.

from csswg-drafts.

frivoal avatar frivoal commented on September 17, 2024 1

Would @else have to come immediately after an @if or @else-if block

Yes, the alternative is too error prone and non obvious.

from csswg-drafts.

fantasai avatar fantasai commented on September 17, 2024 1

Combinable queries seem pretty useful. The current W3C style sheet is doing a conditional against both selectors and @media, which is involving a fair bit of code duplication atm...

from csswg-drafts.

tabatkins avatar tabatkins commented on September 17, 2024 1

@fantasai So if we pretend there's a selector() function that is true if something on the page matches that selector, I think you'd write:

@when selector(body.toc-inline) or (media(width < 28em) and not selector(body.toc-sidebar)) {
  /* inline ToC styling */
} @else {
  /* sidebar ToC styling */
}

from csswg-drafts.

upsuper avatar upsuper commented on September 17, 2024 1

Actually it seems to me it is even possible for preprocessors to integrate the new CSS @if with their existing one, so that authors wouldn't need to distinguish between the two @ifs, and CSS's @if would be generated when the preprocessor thinks it should do.

Since CSS's @if is somehow a syntax sugar of existing syntax, the preprocessors can generate the old syntax if requested before all browsers ship the support of the new syntax.

from csswg-drafts.

heycam avatar heycam commented on September 17, 2024 1

I don't think it's possible to mod @switch into doing this, because the top-level rules aren't constrained to contain only a single child conditional; it could have several, so you can't easily tell what cases it's supposed to cover (and thus what "default" should cover).

Do I remember correctly that we've previously discussed having a supports() function that can be used in media queries? I couldn't find the discussion after a brief search. With it, you could make @switch always take media query expressions:

@switch {
    (max-width: 400px) and supports(abc: def) { ... }
    not (max-width: 400px) { ... }
    default { ... }
}

from csswg-drafts.

matthew-dean avatar matthew-dean commented on September 17, 2024 1

I think it's implied in the top comment, but would this be valid?

@media (min-width: 640px) {
 // stuff
}
@else {
  // other stuff
}

@supports (display: grid) {
 // stuff
}
@else {
  // other stuff
}

from csswg-drafts.

LeaVerou avatar LeaVerou commented on September 17, 2024 1

@matthew-dean Yes. Which actually brings up an interesting point: Browsers could implement this now and CSS authors would get a lot of value, without waiting for the WG to resolve on the very divisive #6684 .

from csswg-drafts.

tabatkins avatar tabatkins commented on September 17, 2024 1

I guess I'm trying to think of a use case where one would combine @media and @supports, and then would need to exclude those criteria in an @else.

Say you wanted to use Grid to layout the page when the viewport is wide enough. If you're being extra-careful, you may want to test for grid support as well; if either grid isn't supported or the viewport is narrow, you default to a simple block-based layout.

from csswg-drafts.

tabatkins avatar tabatkins commented on September 17, 2024

I don't think there's a problem with linking an @else to an immediately preceding conditional rule. It's new, but eh.

Problem with nesting, to me, is that it makes it feel like it might negate everything? Like, if you have @media ➀ { @supports ➁ { @else { ➂ } } }, it's not super clear whether the @else stuff applies solely when ➀ and !➁ (just negates the closest condition), or when !(➀ and ➁) (negates the current condition stack).

from csswg-drafts.

Marat-Tanalin avatar Marat-Tanalin commented on September 17, 2024

@tabatkins While your @if/@else idea sounds good, it would probably be more clear and unambiguous if you’ve provided a code example besides just a description.

from csswg-drafts.

bradkemper avatar bradkemper commented on September 17, 2024

I do think "else-if" is almost as important as "else", whatever the syntax.

Would @else have to come immediately after an @if or @else-if block, or could there be rules in between? I would think the former. The latter could be useful for organizing code, but would probably lead to mistakes.

from csswg-drafts.

tabatkins avatar tabatkins commented on September 17, 2024

Sorry for the delay - Florian's example is indeed exactly what I intend.

@bradkemper Yeah, definitely immediately after. A "dangling @else" (an @else or @else-if whose preceding rule was not a conditional or @else-if) would be invalid. It's technically non-ambiguous to allow interleaved rules, but it would be terrible for readability.

from csswg-drafts.

frivoal avatar frivoal commented on September 17, 2024

@tabatkins I've skimmed your suggested spec, and modulo some fleshing out of details (particularly the parsing and evaluation of <boolean-condition>), I approve.

from csswg-drafts.

fantasai avatar fantasai commented on September 17, 2024

See https://www.w3.org/StyleSheets/TR/2016/base.css section marked "ToC Sidebar".

from csswg-drafts.

tabatkins avatar tabatkins commented on September 17, 2024

@fantasai Looks like it's where you want "if the screen is narrow or body has .toc-inline, use the inline styling; if screen is wide or body has .toc-sidebar, use the sidebar styling"?

from csswg-drafts.

fantasai avatar fantasai commented on September 17, 2024

Right

from csswg-drafts.

tabatkins avatar tabatkins commented on September 17, 2024

So I discussed this with the Sass folks today, and @if clashes with their existing rule. @else-if and @else are fine. We did some brainstorming, and I think @when works pretty well.

So we'd have @when as the combined conditional rule, @else-when for extending, and @else for finishing.

from csswg-drafts.

tabatkins avatar tabatkins commented on September 17, 2024

Other possibilities brought up were @test, @cond, @where.

from csswg-drafts.

tabatkins avatar tabatkins commented on September 17, 2024

Yeah, Sass usage does not trump CSS. But there's also no reason to be hostile to the developer community when we can easily avoid such. In this case, I think there are several names that work just fine in place of @if.

By the way, why not just extend @media to use it itself as @if?

Are you asking why @media can't be used at the start of a conditional chain? It can be - the conditional chain just needs to be started by any conditional group rule other than @else-when or @else.

Or are you asking why we don't just extend @media to have the full value set that I've defined @when to have? That's because it would be weird; there's nothing media-like about supports queries, or about other kinds of queries we might do in the future (like the @url rule). It also would make the grammar very complicated.

from csswg-drafts.

tabatkins avatar tabatkins commented on September 17, 2024

If we were, today, trying to invent supports queries, and someone suggested just putting them into our sole existing conditional rule (@media), I'd be receptive. But we aren't - we already have two specialized conditional rules that handle different kinds of things (and a third that was proposed and exists in Firefox user-level stylesheets), so it's weird to privilege one of them.

Also, media queries have a weird legacy syntax with their media types that makes this a little stranger. Overall not that great. Starting fresh and putting all the types of queries on an equal footing is simple and easy.

from csswg-drafts.

frivoal avatar frivoal commented on September 17, 2024

@tabatkins between the alternative you proposed, I like @when best. @cond is nice for people who know lisp, but that's not a whole lot of people, and everyone else is going to find it obscure. @test or @where aren't necessarily that bad, but I like them less.

I'm also in favor of allowing @else after any kind of conditional rule (@media, @supports, @when, @document if we ever get it...)

from csswg-drafts.

xzyfer avatar xzyfer commented on September 17, 2024

IMHO Sass is an incumbent technology, so purposely colliding with it is akin to "breaking the web". This issue ring similar to the array.contains issue faced by TC39.

Sass will get out of the way as much as possible, but an @if like this could potentially force a python 3 style split that community.

What's the percentage?

Hard to say for sure. A couple recent developer surveys put Sass usage at about 60%-70% of respondents.

preprocessors can always work around that easily

This is generally true for when CSS does something new that preprocessors didn't previously do, like custom properties for example.

However in the CSS of adopting an existing syntax there is no good work around for preprocessor authors. Best case they release a new major with a new syntax. Doing so breaks the existing community of packages.

Even if all package were updated, there is always a significant percentage of people who cannot update for reasons like internal processes, or software. These users are affected the worse because they are left completely unable to use this feature.

from csswg-drafts.

xzyfer avatar xzyfer commented on September 17, 2024

The original Sass file before preprocessing is not processed directly by browsers.

True, but it leaves the author unable to use the CSS @if syntax.

new keyword like @css-if which is converted to the CSS's @if

Also true. This shifts the burden off from the existing ecosystem and onto the everyday developers.


Aside from technology I think there are real concerns regarding the effects on the wider CSS and Sass communities, some potential examples:

Raising the barrier to entry by negatively affecting google search results for the correct syntax for a given context i.e. authoring in CSS or Sass.

Causing confusion where-in blog authors would need to explicitly declare CSS @if or Sass @if in their content.

from csswg-drafts.

xzyfer avatar xzyfer commented on September 17, 2024

it is even possible for preprocessors to integrate the new CSS @if with their existing one

I don't believe this is possible. Just about every part of the proposed syntax collides with Sass.

The breakpoint and supports functions are common user defined functions in all major preprocessors. Given that I'm not sure if it's possible disambiguate between the Sass and CSS @if.

Where as the earlier @media (..) { } @else { }, and by extension the suggested @when (...) { } @else { } is unambiguous.

when the preprocessor thinks it should do

This comes off a bit hand-wavey, although I'd be curious to hear how you think the preprocessor would know. This is something Sass has talked about doing for @extends -> matches() some day.

from csswg-drafts.

xzyfer avatar xzyfer commented on September 17, 2024

For the sake of transparency I should note I work on the LibSass and Node Sass projects. However my concerns are largely for the community impacts. I don't have a dog in the race with regards to technology.

from csswg-drafts.

Marat-Tanalin avatar Marat-Tanalin commented on September 17, 2024

is there more web developers use SASS's @if than those who do not use SASS's @if (or do not use SASS at all) but familiar with the general if-else structure?

Even more, it’s probably a matter of how many users not just use SASS/SCSS, but also strongly depend on third-party libraries of SASS mixins that are using if, and cannot stick with the current SASS implementation until having time/desire to update their outdated SASS style code with a newer one.

Fwiw, as a web developer, I use the @if feature of SCSS (via scssphp) very rarely, as well as I don’t use libraries of SASS mixins (except for those written by me and thus available to be updated by myself at any moment).

from csswg-drafts.

upsuper avatar upsuper commented on September 17, 2024

Okay, it seems I misunderstood how that directive works, and I agree it looks hard to integrate them or distinguish between those two kinds of @if for preprocessors.

But it could still be solved by adding some new syntax to make it future-proof with changes in CSS. For example, say Sass can probably make @+something be converted to @something in CSS, so that Sass can use any name as the directive without concerning / affecting change in CSS's at-rules.

That still adds burden to everyday developers, but that only adds one extra character burden for people who use Sass, while @when brings two extra characters for everyone, plus the mental burden from unfamiliarity.

from csswg-drafts.

upsuper avatar upsuper commented on September 17, 2024

But I agree the raised barrier from search results could be a real concern. Not sure how bad that would be, though.

from csswg-drafts.

xzyfer avatar xzyfer commented on September 17, 2024

Sass can probably make @+something be converted to @something

I agree that some sort of escape hatch could be useful. I'd argue the number of keystrokes is a non-issue, the issue is the cognitive overhead. An escape hatch like this is nice because it's the same for all directives so it becomes just part of the language.

It's interesting to note Sass has previously relied on an escape hatch that CSS has provided with the - prefix. We were able to take advantage of this even recently with the extra - in the prefix for custom properties.

Funnily enough the technology aspect of this issue go away with @-if.

while @when [..] the mental burden from unfamiliarity.

Given that CSS devs have never had an if construct (outside of preprocessors) I'd argue that unfamiliarity is moot point, and any one who is familiar if constructs would easily grasp an alternative syntax.

Plus they get the added bonus but @when would be Googleable.

from csswg-drafts.

Marat-Tanalin avatar Marat-Tanalin commented on September 17, 2024

there's nothing media-like about supports queries

Think of non-media part of query as an extra condition instead of a part of the media query itself.

The @supports could also be extended based on the same paradigm. So the following:

@media (width >= 400px) and (pointer: fine) and supports(display: flex) {}
@supports (display: flex) and media((width >= 400px) and (pointer: fine)) {}

would be perfectly interchangeable equivalents (so we have media and supports in the former and supports and media in the latter, like 2+3 is the same as 3+2).

Along the advantages of this approach are that the redundant parens around the main part of query are avoided, as well as that the philosophical @when-or-@if question gets then irrelevant.

If needed, we could make the main part (related to the rule name) required to be the first part of the query, and require the optional extra condition to follow it.

from csswg-drafts.

tabatkins avatar tabatkins commented on September 17, 2024

Again, it's possible, but I don't like it very much. Particularly since you'd then have the same MQ bias for the @else rule, where it's much less obvious. This feels like the sort of "legacy things evolved into what we have today" awkwardness that infests much of the web platform.

An argument in favor is that this is the syntax we used for @import's condition, since it was specialized to be a naked MQ way back when. But again, that's "legacy awkwardness we evolved around" - if we'd designed @import conditions today, I'm pretty sure we'd have media() and supports() functions, or something similar.

from csswg-drafts.

Marat-Tanalin avatar Marat-Tanalin commented on September 17, 2024

Suppose an author wants to use a media query without nonmedia conditions. They use a @media rule since compared with @if or @when it is easier to write (less parens) and more readable. Then, after some time, the author needs to add an additional condition: they could just append it to the end of the existing @media preamble instead of rewriting it and wrapping the preamble in parens.

Btw, does GitHub have a poll feature?

from csswg-drafts.

tabatkins avatar tabatkins commented on September 17, 2024

(less parens)

Exactly the same number of parens. Extra 5 characters (the media at the start of each parenthesis set) per MQ, or a static 7 characters (media(...)) around the whole thing.


Alternate scenario: the author has written an @supports rule, and realizes they need an @else condition. They try to write @else (float: left) {...}, but it fails for no obvious reason, because the CSSWG decided that @media was the generic form and @else has to follow - they instead have to remember to write @else supports(float: left) {...}.

There are minor usability problems both ways. Designing toward explicitness makes it easier to learn and remember, tho. This is a lesson I've learned many times watching features get designed.

from csswg-drafts.

Marat-Tanalin avatar Marat-Tanalin commented on September 17, 2024

Exactly the same number of parens

Am I the only who sees a couple of extra parens in the first line compared with the second one?

@if media((width >= 400px) and (pointer: fine)) {}
@media (width >= 400px) and (pointer: fine) {}

They try to write @else (float: left) {...}, but it fails for no obvious reason

For @else, an exact explicit function like media() or supports() could probably be mandatory. The @when-or-@if issue would probably still be ruled out anyway.

from csswg-drafts.

tabatkins avatar tabatkins commented on September 17, 2024

The way I wrote that example includes one. It's not required. You can also write it as:

@if media(width >= 400px) and media(pointer: fine)) {}
@media (width >= 400px) and (pointer: fine) {}

For @else, an exact explicit function like media() or supports() could probably be mandatory. The @when-or-@if issue would probably still be ruled out anyway.

Then you have to recognize a third grammar, which is still awkward as heck.

Rather than "@media allows naked MQs and the supports() function, @supports allows naked support queries and the media() function, @else requires both media() and supports()", we can instead say @media allows MQs, @supports allows support queries, @when and @else require media() and supports() (because neither is clearly a particular type of conditional).

from csswg-drafts.

therealglazou avatar therealglazou commented on September 17, 2024

Just thinking out loud, we have not in MQs and it's doing precisely what you want, right?-)

@media screen and (color) { /* your @when statements */ }
@media not screen and (color) { /* your @else statements */ }

from csswg-drafts.

therealglazou avatar therealglazou commented on September 17, 2024

@frivoal I perfectly understand the readability issue, but I'm thinking of the editability issue in automated environements like a Wysiwyg editor. It's already INCREDIBLY painful to deal with arbitrary MQs and @else statements will make them even more complicated to deal with...

from csswg-drafts.

tabatkins avatar tabatkins commented on September 17, 2024

It also doesn't handle combined @media and @supports conditions.

from csswg-drafts.

inoas avatar inoas commented on September 17, 2024

Just on the issue of @when vs @if vs @cond:

In English as in German when does not necessarily introduce a timeless condition (Edit: and in CSS we should, IMHO).

So cond or if are better in terms of nomenclature compared to when which is a bit like using then instead of than. @where, @match, @case would all IMHO preferable to @when.

from csswg-drafts.

tabatkins avatar tabatkins commented on September 17, 2024

What do you mean by "does not necessarily introduce a timeless condition"? One reason I like "when" is that it explicitly invokes time, rather than looking like an imperative, once-and-done construct. "Whenever X is true, do Y.", to me, helps suggest that the condition will turn on and off over the lifetime of the page.

from csswg-drafts.

inoas avatar inoas commented on September 17, 2024

As I consider CSS to be more on the declarative than imperative side, if is timeless then IMHO.

<pattern> => application
@if(condition) { apply block }
selector_or_pattern { apply block }

In my book when is strictly imperative/process oriented, if/cond are more declarative/pattern-matching/timeless
When: "As soon as X, do Y"
If: "Whenever X is the case, Y is the case"
but... cond, match, where may also work and not clash with SCSS/SASS?!

Things turning on and off happens through user-interaction/behaviors/javascript/keyframes and those external processes simply set a different state (say window size or dom tree change) which "in theory" the css declarations that pattern match the conditions applies instantly without any delay (in theory!).

Anyway I'd 👍 by a big margin even using @when

from csswg-drafts.

Kinematics avatar Kinematics commented on September 17, 2024

@tabatkins -

Per my thoughts on scoping/namespace usage in issue #270 there's a potential reason to consider @if and @when separately.

inoas mentions 'timeless conditions'. @if could be considered an instantaneous decision. Once made, it leaves the table, and everything inside the block is evaluated without any further consideration of the initial condition. If changes are made, the entire ruleset gets re-evaluated, and the new @if check has the same instantaneous property.

@when, on the other hand, implies an ongoing decision, which has two implications: First, that the condition might regularly change state (as you imply in your response there), and second, where everything within the block is evaluated while keeping that ongoing decision in mind.

However, most of the context of that differentiation comes from my idea that namespaces can be implemented almost entirely with existing tools, without needing to introduce a ton of extra semantics. However I did realize by the end of it that it would require the @when condition be 'maintained' as a validity check for every selector within the conditional block (for conditionals which cannot be evaluated outside the context of a selector; namely, custom properties), and that's a subtle enough factor that it could impact the usability of the idea.

from csswg-drafts.

css-meeting-bot avatar css-meeting-bot commented on September 17, 2024

The CSS Working Group just discussed else conditional.

The full IRC log of that discussion <astearns> topic: else conditional
<jensimmons> people aren’t really using the media query. they will use thr property a lot
<astearns> github: https://github.com//issues/112
<fremy> TabAtkins: heycam wanted to put this on the agenda, and I'd be interested to know why he brought this up
<fremy> heycam: I made a proposal and it never got discussed further
<TabAtkins> http://tabatkins.github.io/specs/css-when-else/
<fremy> TabAtkins: yeah, I had limited time so I didn't push forward, but if there is interest I can reprioritize my work
<fremy> astearns: so, heycam, are you volounteering to implement that?
<fremy> heycam: no
<fremy> TabAtkins: in that case, I'd rather leave this in the status of proposal
<fremy> fantasai: could we maybe cross-link the issue in the draft, so this discussion is available to readers?
<fremy> TabAtkins: okay, sounds reasonable
<fremy> TabAtkins: it's not right now, but I can do this
<fremy> heycam: so, shall we table this discussion for now?
<fremy> florian: just wanted to note that also unless everybody is doing it, it's not useful
<fremy> myles_: sure, but if one does it and authors finds it useful, others will follow
<fremy> TabAtkins: but the point is that right now we don't even have one promise to implement
<fremy> astearns: okay, let's try to do easing timing functions, then take a break

from csswg-drafts.

ByteEater-pl avatar ByteEater-pl commented on September 17, 2024

@when is familiar to those who know SQL which has WHEN in both variants of its CASE expression and no IF.

from csswg-drafts.

astearns avatar astearns commented on September 17, 2024

In a discussion about @supports rules for @container we briefly discussed allowing @else after any at-rule

#6175 (comment)

from csswg-drafts.

matthew-dean avatar matthew-dean commented on September 17, 2024

@LeaVerou I agree. It actually feels less, er, scripty? Than @if / @when? And what I've seen so far just embeds new supports() or media() functions, so I'm not understanding why @if and @when are even needed. You can't define global variables in CSS yet, which is the typical use case for @if in Sass (and the same when guard construct in Less), so why not just do @supports / @else and @media / @else if that's all CSS wants to use an @if / @when for? 🤔 Are there really instances where CSS authors have been jonesing to put a media query and a supports test on one line?

Seems like there could be two proposals: one initial one just for @else. Then later, decide if anything else (ha) is needed (like if CSS adds global / stylesheet variables).

from csswg-drafts.

LeaVerou avatar LeaVerou commented on September 17, 2024

@matthew-dean @if allows combining these two criteria with arbitrary boolean operators, and is also an extensibility point for future conditionals as well.

from csswg-drafts.

inoas avatar inoas commented on September 17, 2024

Generally speaking I'd prefer something that is more like switch/case with guards than if/else to exist in css.

Example without guards:

@case (@supports(display: grid), @supports(display: flex)) {
 (TRUE, TRUE) -> {
   body { display: grid }
 },
 (_, TRUE) {
   body { display: flex }
 },
},

Long nested chains of if/else without exhaustiveness, feel generally bad to me.

from csswg-drafts.

matthew-dean avatar matthew-dean commented on September 17, 2024

@tabatkins

Yeah, https://github.com/when is purely a way to combine an https://github.com/supports and https://github.com/media query together in a single conditional; without this, you have to nest and repeat yourself in a way that's both hard to write and hard to read.

I guess I'm trying to think of a use case where one would combine @media and @supports, and then would need to exclude those criteria in an @else. I get these are both types of queries but I guess I've never seen an intersection or a coupling of the two ideas, where the media properties were linked to the supports test in some way. 🤔

The spec example says:

For example, here’s a (somewhat silly) conditional chain

But are there non-silly, logical connections between @media and @supports? Commonly enough that there's been a need to combine these into single-line queries? Any real-world examples? I'm not saying there aren't--I'm legitimately curious because I haven't encountered this.

@LeaVerou

is also an extensibility point for future conditionals as well.

Yeah, I get this, and it makes sense to some degree. I do wish we could already define / test stylesheet vars, like:

@var {
   --theme: 'dark';
}

/** extend var() to look at globals first, not just cascade :root props, so that could use var() in queries **/
@when (var(--theme) = 'dark') {
  .box {
    background: black;
    color: white;
  }
} @else {
  .box {
    background: white;
    color: black;
  }
}

Or, the inline form, I guess:

  .box {
    background: if(var(--theme) = 'dark', black, white);
    color: if(var(--theme) = 'dark', white, black);
  }

from csswg-drafts.

CharfeddineMohamedAli avatar CharfeddineMohamedAli commented on September 17, 2024

Sass developers have stated that CSS should not avoid a good syntax just because Sass uses it, they are very willing to change so that CSS can get better.
But what about introducing new syntax ?
@if can be changed to @whether or @either and@else can be changed to @or

from csswg-drafts.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.