- From: Boris Zbarsky <bzbarsky@MIT.EDU>
- Date: Sun, 21 Oct 2012 20:47:25 -0400
- To: www-style list <www-style@w3.org>
Problem description: Media queries provide the equivalent of an "if" statement, but not an equivalent of "else". While "else" is generally syntactic sugar (in the sense that you can always replace "if (x) {} else {}" with "if (x) {} if (not x) {}", it's very useful syntactic sugar, especially in cases that involve an if cascade. Specifically, consider how one would express "Use rule set A if width is 500px or less, use rule set B if width is more than 500px but no more than 1000px, use rule set C if width is more than 1000px". As far as I can tell, this cannot be done, because max-width and min-width describe closed ranges, there is no "or", and "not" can only appear at the start of a query. As a result, I believe there is no way to express "500px < width <= 1000px" as a media query. That leaves web developers with two options: either doing hacks to account for the case when both A and B are applied or doing things like: @media (max-width: 500px) { A } @media (max-width: 1000px) and (min-width: 500.000001px) { B } @media not (max-width: 1000px) { C } For this specific case we can ameliorate things a bit by adding "or" or allowing "not" in the middle somewhere, but the result will still be a bit painful to author. And should an author have the misfortune to want a more complicated set of constraints (e.g. something on width, height _and_ aspect ratio), I think the author is in trouble. Proposed solutions: With that in mind, I would like to propose that we introduce an effective equivalent of C's switch() or Python's if/elif/else, as follows: Define a new @-rule (names welcome; for now let's call it @pickone, because I haven't thought of a good name) which can contain 0 or more @media rules followed by 0 or more rulesets. This is processed by applying only the rulesets within the first @media child whose media query matches. If none of them match, the ruleset children are applied. Using this construct, the use case I describe above would be handled like so: @pickone { @media (max-width: 500px) { A } @media (max-width: 1000px) { B } C } Additional notes: 1) We could also address this by simply adding a way to do "else" to @media, but that would require if/else cascades that are harder to read than what I propose, I think. 2) One issue with the above proposal is that degradation in a browser that does not support @pickone is not great. I don't see a great way around that, though if @supports could test for support for @-rules at least something could be hacked together. If people have ideas for making this better, I'm all ears. 3) This obviously doesn't help other consumers of media queries, like @import and <link>. To address those we'd need to add more options for boolean operations to media queries (e.g. "or" and/or allowing "not" on individual expressions) and let authors deal with the resulting boolean logic hell. My suggestion for doing @import sanely is to simply allow @import inside @media, for what it's worth. I don't have a good suggestion for <link> Thoughts? -Boris
Received on Monday, 22 October 2012 00:47:54 UTC