Re: @else in Media Queries

On 13 June 2016 at 21:12, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
>
> On Sat, Jun 11, 2016 at 12:34 AM, Sebastian Zartner
> <sebastianzartner@gmail.com> wrote:
> > On 9 June 2016 at 22:58, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
> >> On Thu, Jun 9, 2016 at 3:34 AM, Daniel Glazman
> >> <daniel.glazman@disruptive-innovations.com> wrote:
> >>> If @else if added, it adds another major layer of complexity:
> >>> we can only negate a whole MQ right now and not a single component
> >>> inside a MQ so expressing the "compound" MQ relevant to an arbitrary
> >>> style rule could be very painful is not impossible. In short it means
> >>> that copy/paste of a given element with its stylistic information
> >>> between two different documents could lead to MQ of that form:
> >>>
> >>>   @media ...a media query... {
> >>>     /* nothing here */
> >>>     @else {
> >>>       p { color: red }
> >>>     )
> >>>   }
> >>>
> >>> Sorry, but that's ugly and that clearly sucks. From a UI perspective,
> >>> wow.
> >>
> >> I don't know what you're trying to say here. Can you flesh out the
> >> example with more detail?
> >
> > Coming back to this option, why is nesting the @else rule that bad? Sure, in
> > other languages you have it outside of the first block, but it clearly
> > connects both visually and avoids the problems of a dangling @else
> > block.
>
> I purposely rejected nesting for several reasons:
>
> * It becomes less clear what precisely is being negated when a nesting
> relationship is used rather than a sibling relationship.  In
> particular, if you have "@media ... { @supports { ...  @else {...} }
> }", it doesn't (to me) look immediately clear that the @else is only
> negating the @supports.  Sibling relationships make it immediately
> obvious.

I'd say in both cases it's more or less equally clear. When choosing
nasting syntax, it's the parent rule, when doing sibling syntax, it's
the previous sibling. But regarding other languages you're right,
people normally know else blocks as siblings.

> * It doesn't lend itself naturally to 3+ exclusive rules.  How would
> you write the spec's example using nesting?  If you nest further the
> semantics become *really* muddy, imo.  But if you don't nest, then
> what? If you rely on sibling rules, then it's inconsistent between
> levels.

3+ exclusive rules are indeed a problem, which is better solved by
sibling rules.

> * It changes the meaning of conditional rule bodies in an (imo) weird
> way.  Currently, if the condition is false, you can just ignore
> everything inside the rule.  With nesting, tho, there might be a block
> that *is* activated, which makes the mental model more difficult.

Though the @else belongs to the conditional rule, which is emphasized
by nesting it.

> * Semi-related, you can't take proper advantage of most editor's
> block-folding tools to hide the contents of media blocks.  If you do,
> you'll be hiding the @else conditions as well. Siblings rules instead
> work with the existing folding techniques very well.

It would mean editors may need to be adjusted for that. Though, as
said above, the @else block belongs to the media block. So, there is
no strong reason to keep the @else block visible when the related
block is folded. And even if there is one, editors may be adjusted
accordingly.

> * With nesting, there's no ordering requirement beyond just "must be
> inside the rule it's chaining against".  This means you can have style
> rules that apply when the parent rule is true both before and after
> the @else, which is harder to read and understand. Sibling rules
> enforce an easy-to-read sequencing.

It may require a syntax change, so @else blocks may only appear as the
last block to avoid this issue.

> * As a general principle, we also tend to try and minimize required
> nesting when designing syntax.  Tracking nesting is more difficult for
> humans to do, and invites errors more readily from having too many or
> too few closing-tokens.

There are ways to detect nesting like curly brace highlighting or
folding in editors or simply by proper indentation.

> * Sibling rules more closely match how conditionals look in other
> languages.  From the example in the spec:
>
> ```
> @when ... {
>   /* A */
> } @else ... {
>   /* B */
> } @else {
>   /* C */
> }
> ```
>
> Looks a lot like the similar construction in JS:
>
> ```
> if( ... ) {
>   /* A */
> } else if( ... ) {
>   /* B */
> } else {
>   /* C */
> }
> ```
>
> This isn't a requirement, but it's nice to have things transfer over like that.

Yes, that's what I wrote earlier. Having them as sibling blocks is
what other languages do.

Having said the points above, note that I'm not advocating for a
nested @else syntax, I just wanted to point it out again as another
solution and get a clarification on why you think it's worse than
having the sibling @else syntax.

One question to the presented syntax. You came up with an @when rule
additionally to the @else rule. Should these rules directly take a
condition? If so, they would need to cover media queries and support
queries (and maybe other conditional types in the future). Or should
they support @media and @supports rules inside their condition,
somehow?

Sebastian

Received on Tuesday, 14 June 2016 10:29:26 UTC