W3C home > Mailing lists > Public > www-style@w3.org > February 2016

Re: [css-variables] Why so inefficient?

From: Patrick Dark <www-style.at.w3.org@patrick.dark.name>
Date: Tue, 23 Feb 2016 19:24:24 -0600
To: "Tab Atkins Jr." <jackalmage@gmail.com>
Cc: darkdragon <darkdragon-001@web.de>, www-style list <www-style@w3.org>
Message-ID: <b49eeaa9-0185-90be-77e3-c3ea3745a236@patrick.dark.name>
On 2/23/2016 3:32 PM, Tab Atkins Jr. wrote:
> On Sun, Feb 21, 2016 at 10:10 AM, Patrick Dark
> <www-style.at.w3.org@patrick.dark.name> wrote:
>> On 2/16/2016 5:35 PM, Tab Atkins Jr. wrote:
>>> On Wed, Feb 10, 2016 at 12:45 AM, darkdragon <darkdragon-001@web.de>
>>> wrote:
>>>> Currently, you need at least 7(!) characters plus the actual name just to
>>>> use one variable. This is quite much to encourage users to use it!
>>>> Why do you need "--" AND "var()"?
>>>> Wouldn't be one of it be enough?
>>> We need the -- in var(--foo) so that the name matches exactly between
>>> definition and use. Anything else is potentially confusing, and makes
>>> searching in a document harder.
>>> We need a var() function for a few reasons.  For one, there are a few
>>> places in CSS where you can have arbitrary names already, like counter
>>> styles or animation names, so allowing a bare custom property name
>>> would be ambiguous there.  Theoretically we could make it invalid to
>>> name your @keyframes or @counter-style rule something that looks like
>>> a custom property name, but that means more rules for authors to
>>> learn.
>> I think it would be good to go ahead and do this. I've used CSS variables
>> and find that having to declare each variable reference twice—once with
>> var() and again with the "--" prefix—is onerous. Being able to eliminate
>> var() would continue to address your first concern (i.e., syntax
>> consistency) while making the feature significantly easier to use.
>> One reason it's onerous aside from the verbosity, is that if I create a
>> custom property like --color, then try to copy and paste what I just typed
>> to multiple locations, I can't do that without first typing "var(" at the
>> beginning of what I pasted and ")" at the end of what I pasted, then copying
>> that before continuing the paste process. In case it's not obvious, I arrive
>> in this situation because it's typically the case that I'll write part of a
>> style sheet before deciding that I need variable to ensure that certain
>> parts of the style remain consistent.
> Yeah, I sympathize with this.  But I disagree that it's sufficiently
> onerous to justify the drawbacks of bare keywords.
> For example, I *messed up* when I was speccing @counter-style.  By
> allowing any arbitrary name, I had to produce a list of disallowed
> keywords (and keep it updated, and swallow the possible compat pain if
> in the meantime someone *used* a name that I'm now disallowing), and
> had to add several subtle and annoying tweaks to the spec,
> complicating it and implementations.  If I were writing it today, I'd
> require the @counter-style name be a <custom-ident> (the -- prefix) so
> they were distinguishable from built-in keywords and could never
> collide.  Same with @keyframes - handling an arbitrary keyframes name
> in the 'animation' shorthand is really kinda messed up, and required
> us to define some pretty weird parsing rules to cover it.  Any future
> user-defined names are probably gonna be <custom-ident>s from now on,
> to avoid these issues.
> (Actually, Firefox is the only one with @counter-style support.  I
> wonder if I could get them to make this change. I'll make another
> thread. ^_^)
> This would, obviously, conflict with treating bare custom-idents as
> variable references.
>>> For two, var() is required in some circumstances, like when you want
>>> to provide a fallback.  In general, a language shouldn't provide
>>> multiple ways to do something unless there are good reasons for each,
>>> and there isn't a strong reason to omit var() when you're not using
>>> any other functionality, so I don't allow it.
>> The name of this feature, var, provides no indication whatsoever that it
>> permits fallback values. This is the first I've heard of that functionality
>> and finding it in the spec isn't obvious either because the fallback
>> feature's description doesn't have its own section. This seems inconsistent
>> with your "readability and understandability" principle (quoted below).
> I can edit the spec to fix that - thanks for the suggestion. ^_^

I think it'd make sense to create a Section 3.1.2. Specifying Fallback 
so that it's after the explanation about invalid variables (Section 3.1) 
and move most of the fallback stuff from Section 3.0 to there. The title 
will allow that information to easily be found through the table of 
contents. Obviously, you want to mention fallback where the syntax is 
defined since there has to be an explanation for the second argument to 
var(), but that could be through a link to Section 3.1.2 or equivalent.

>> It also seems strange to have this feature, which is unrelated to variables,
>> be part of the Variables module when there's already a Conditional Rules
>> module that does the same thing. This seems inconsistent with your "a
>> language shouldn't provide multiple ways to do something" principle.
> Conditional Rules has nothing to do with variable fallback - it's an
> expansion on the syntax-fallback behavior that you get from writing a
> declaration twice, once with new or prefixed values and once with old.
> As I said in my previous email to darkdragon, even if it *did* apply,
> it would be *extremely* onerous in practice.  This would fall clearly
> under the "unless there's a good reason" escape valve.

It seems to be the same thing to me. For example:

* { --text-color: gray(20%); }
p { color: var(--text-color, hsla(0, 0%, 20%, 1)); }
table { color: var(--text-color, hsla(0, 0%, 20%, 1)); }

As far as I can tell, that's equivalent to:

* { --text-color: hsla(0, 0%, 20%, 1); }
@supports (color: gray(0%)) { * { --text-color: gray(20%); } }
p { color: var(--text-color); }
table { color: var(--text-color); }

Instead of determining that the property value is valid before using it, 
you use it, throw it away, then use a fallback that has to be repeatedly 
specified. The end result is the same.

I'm not sure what's onerous about the Conditional Rules version of this 
technique (aside from typing "var(" and ")" :). Maybe you can put an 
onerous versus non-onerous-equivalent example in the Variables spec to 
clear things up?

>>>> Why not something like "v()" as a shortcut (people using jQuery and stuff
>>>> are used to such shortcuts!)?
>>> While I highly value terseness in CSS and promote it whenever
>>> possible, it must be balanced against other concerns, like readability
>>> and understandability.  Single-letter names are generally a bad
>>> tradeoff here - they only save a little bit, but they make it much
>>> more difficult to tell what's being referred to.  The name "var()" is
>>> already abbreviated from "variable()", but it's a pretty unambiguous
>>> cut, and anyone working in the web platform is already familiar with
>>> "var" from JS.
>> If this was seriously a concern, then the syntax would have been something
>> more like -var-property so that custom property declarations are clearly
>> variables. But it isn't.
> It used to be (well, var-*). People complained about the length of the
> prefix, so I dropped it down to --*.  It's not as obvious *for
> variables*, but Custom Properties are useful for a lot more than
> variables, and the --* syntax actually makes them feel similar to
> browser-prefixed properties, which is a good thing.
>> And, if authors can do without a var() equivalent when invoking variables in
>> other languages, I think authors can do without it in CSS. "--" is the
>> syntax CSS is using for declaring variables and "--" is required when using
>> variables; that follows the paradigm of languages like PHP and is more than
>> is required in languages like JavaScript, which doesn't use variable
>> signifiers at all.
>> For more perspective, imagine having to type var() or let() around every
>> variable use in JavaScript; that would be absurd.
> Other languages don't have the same syntax flexibility of CSS. They
> tend to have a very small set of syntaxes for literals, and
> *everything else* is a variable of some sort implicitly.  CSS is the
> exact opposite - it's got a very wide set of syntax literals, and
> literals are the *default*, with variables being relatively rare in
> comparison.
> ~TJ
Received on Wednesday, 24 February 2016 01:24:54 UTC

This archive was generated by hypermail 2.4.0 : Friday, 25 March 2022 10:09:00 UTC