Re: @else in Media Queries

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.

* 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.

* 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.

* 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.

* 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.

* 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.

* 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.

~TJ

Received on Monday, 13 June 2016 19:13:12 UTC