- From: Kang-Hao (Kenny) Lu <kennyluck@csail.mit.edu>
- Date: Fri, 06 Jul 2012 19:36:08 +0800
- To: "Tab Atkins Jr." <jackalmage@gmail.com>
- CC: "L. David Baron" <dbaron@dbaron.org>, fantasai <fantasai.lists@inkedblade.net>, "www-style@w3.org" <www-style@w3.org>, 史绪胜 <xushengs@gmail.com>
(I am changing the subject and Cc- w3c-css-wg, sorry about discussing this with an irrelevant subject line for a while.) (12/07/06 15:42), Tab Atkins Jr. wrote: >>>>> * they'd prevent the working group from using parentheses in any >>>>> other contexts in CSS property syntax (though the first point is >>>>> also an argument against most other possible uses) >>>> >>>> My bet is that this is not likely to happen. It's not like CSS is a >>>> fast-changing language so worrying too much about "reserving for the >>>> future" doesn't make much sense to me, and if you want grouping >>>> constructs in the future, we still have [] and <>. >>> >>> One must always worry about being future-friendly, or else you'll make >>> mistakes that are really annoying later. (You'll probably make them >>> anyway, but hopefully less often if you're watching out for them.) >> >> I agree, but I'd be curious what we might want to use parentheses for. >> And, is it not possible to overload the meaning of parentheses just like >> how it is overloaded in other programming languages (e.g. in JS bare >> parenthesis is used after a control flow keyword and it is also used to >> mean a function call)? >> >> It seems that we have extensive experience about this in other languages >> so we can just learn from them. > > The main thing I expect to use parens for in the future is their > primary purpose - grouping things. For example, currently, if we want > a function to take a general selector as an argument, we have to make > it the last argument and have no optional args, because the comma in > selectors clashes with commas between arguments. Requiring people to > wrap the selector in parens if they use commas in it would help. I've been wondering why you think about the bare parenthesis syntax as "you can do math in here". To me, it's as you said, just a general grouping construct. It's the '+', '-', '*' or '/' that does the math. The parenthesis, as with any other programming language, is just there to make values parseable. Now I start to see some potential issues. Issue: '+' is overloaded to mean both "plus" and "next-sibling combinator". '/' is overloaded to mean both "divide" and "general value separator". But I need an example to illustrate that this is a real issue (see below). > Variables have a very similar problem in the default values of the > var() and parent-var() functions. If I ever convince the group to do > Mixins, we'll have the same problem there. Parens could be useful in > both of these circumstances for grouping values into a single > argument. Calculation is about grouping values into a single value too. So, to see if there are real problems I think it would be better to examine specific examples to see if there are real conflicts. Example 1a: border-radius: 1em (2em / 3em) 4em This is admittedly somewhat confusing, but I'd say it's fine to say it's invalid. Example 1b: font: (14px / 2) Similarly, this is equivalent to "font: 7px", not "font: 14px / 2" Example 2a: var(foo, (bar1, bar2)) There's no '+', '-', '/' or '*' here so you don't need to do calc() syntax checking here, and I also don't think the "bare parenthesis as calculation idea" asks you to do calc() syntax checking any time you see a bare parenthesis pair, or otherwise it just doesn't work with the Media Query syntax. Example 2b: var(foo, (bar1 + bar2, bar3)) So, even if there's a "+" here, as far as I can tell, the proposed behavior of the default value var() syntax with the bare parenthesis extension is to feed the token stream "bar + bar2, bar 3" to downstream. It's up to the the downstream to do any checking with the token stream. That is, width: (var(invalid-foo, (bar1 + bar2, bar3))) becomes width: (bar1 + bar2, bar3) . Now, the property value top level requires a calc() syntax checking for a bare parenthesis pair and it's invalid. Example 2c: width: (var(invalid-foo, (1em + 2em)) This would work, just like width: (1em + 2em) Example 2d: width: var(invalid-foo, (100% - 2em)) With the above definition, this is invalid because "width: 100% - 2em" is. So indeed this might confuse people if the "bare parenthesis as calculation" idea is accepted and we remove calc(). Some options: 1. Introduce arg() for an argument with ",". That is, give up the bare parenthesis extension to var(). 2. Keep calc() so it can be used for this purpose. 3. Ask people to do ((100% - 2em)) in this case. 4. Adopt XSL-FO-like behavior where "width: 100% - 2em" just works. I haven't studied how it works with 1a and 1b above, though. Likewise, attr()/toggle(). These are both var()-like functional notations anyway. The "bare parenthesis as calculation" proposal only asks bare parenthesis to mean calculations when it's at the top level of a property value, the behavior of it in the rest of the locations, is, admittedly, underspecified, and it needs to be investigated. So here it goes, Example 3: linear-gradient((10deg + 10deg), red (10% + 2em)) I don't think we'll introduce "fold multiple arguments into one" syntax in all functional notations in css3-images, so it's safe to introduce calc() syntax checking at the top level within linear-gradient()/radial-gradient()/repeating-linear-gradient()/repeating-radial-gradient(). There are some corner case calc()-accepting locations like nth-child()/@keyframe and I think it's safe to ignore those at the moment. (It's considered OutOfScope by css3-values too, I think). That's go into the future: Example 4: element((auto + min-content)) I don't think there's any way you would expect calculation to happen within element() since it doesn't take a property value, so there should not be calc() syntax checking at the top level within element(), and what this does is to select a <min-content> element preceded by an <auto> element. If people really think this is confusing we can introduce selector(), as element(selector(auto + min-content)) Comparing * calc()/() * ()/selector() , I would go with latter, but both these tags are, as far as I can tell, not necessary. If I am asked to compare * calc()/() * ()/arg() (described above) , I think I would go with the latter too. Any more examples we can analyze? Cheers, Kenny
Received on Friday, 6 July 2012 11:36:42 UTC