Re: [css-variables] var() for non-custom properties

Letting implementation complexity leak into the UI is a common antipattern and this is exactly what’s happening here.

I never quite understood why functions like element() [1] can just brush this off with “The element() function can produce nonsensical circular relationships, such as an element using itself as its own background. These relationships can be easily and reliably detected and resolved, however, by keeping track of a dependency graph and using common cycle-detection algorithms.”

*ALL* cycles can be detected by “keeping track of a dependency graph and using common cycle-detection algorithms”. Worst case scenario, we can just be very aggressive about what depends on what and it’s still better than rejecting entire features that are needed by thousands of authors daily on the grounds of “but if used nonsensically it could result in a cycle and then the world would explode!!!11”.

Not to mention that using variables, besides being an ugly solution, is not an option when you want to reference CSS you do not control.

Potential cycles come up all the time with any reasonable styling mechanism that supports the kinds of constraints needed by real designs. Maybe it’s time to devise a way of dealing with them when they actually occur or at least have a real chance of occurring.

The ripple effects of avoiding cycles like the plague accounts for most of the utter puzzlement people feel when dealing with CSS even in their first few lines of CSS code. I’m sure we can do better.

~Lea

[1]: http://dev.w3.org/csswg/css-images-4/#element-notation

Lea Verou ✿ http://lea.verou.me ✿ @leaverou







> On May 22, 2015, at 12:16, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
> 
> On Fri, May 22, 2015 at 7:21 AM, François REMY
> <francois.remy.dev@outlook.com> wrote:
>>> Is there some reason that var() can not be used for non-custom properties?
>> 
>> It depends. If you want to use the computed value of a property, you'll be
>> out of luck, because that would create inadvertent cycles. Think about:
>> 
>>    ELEMENT {
>>        width: var(padding-left);
>>        padding-left: 50% /* of the width */;
>>    }
>> 
>> If you want the specified value, the previous example would work but provide
>> the surprising
>> 
>>    ELEMENT {
>>        width: 50%;
>>        padding-left: 50% /* so 25% of parent bfc's width*/;
>>    }
> 
> Yes, this is the main reason we don't and won't allow this.
> 
>>> Except shorthand, it would be a good idea.
>> 
>> And this is the second issue.
>> 
>>    ELEMENT {
>>        border-left-width: 10px; /*overriden*/
>>        border-width: 5px;
>>        width: var(border-left-width); /* would have to be 5px, but that
>> means we resolved border-width. okay, hold on */
>>    }
>> 
>> Not let's suppose that we did this instead:
>> 
>>    ELEMENT {
>>        border-width: 5px;
>>        border-left-width: 10px;
>>        width: var(border-width); /* even if this was valid, this means we
>> have to reconstruct the shorthand, which is hard */
>>    }
>> 
>> Now the issue is that any propery can become a shorthand at some point. See
>> for instance display which could have been divided into "display-inside" and
>> "display-outside" and that would make old code break if the browser engine
>> doesn't do a lot of work to make things up for it.
> 
> This isn't really an issue.  Shorthands are expanded at declared-value
> time, right at the very beginning.  Reconstructing a shorthand from
> longhands isn't always possible, which is an issue, but resolving a
> longhand that has been specified multiple times, some by the explicit
> longhand and some by shorthands, isn't problematic.
> 
>> That why it was ruled out. Even if this is possible in theory, this requires
>> too much work to be worked out by browser vendors. Just do this instead:
>> 
>>    * {  border-width: var(--border-width)  }
>>    ELEMENT {
>>        --border-width: 5px
>>        width: var(--border-width);
>>    }
> 
> Yes, this is the recommended practice.  Just move the property value
> into a variable, and then use that in both places.  That avoids all
> possible problems and is possible today.
> 
>>> We're already using a similar mechanism such as var() for non-custom
>>> property; currentcolor.
>> 
>> We should definitely introduce more keywords like this for things that could
>> be safely expressed this way. I would love to have currentBackgroundColor
>> for instance.
> 
> The issue is "safely"; we want to avoid computed-value dependencies
> when possible.  Color stuff probably is generally safe, but there's
> also not a ton of value over just using a variable in both
> background-color and whatever you want to share background-color with.
> 
> ~TJ

Received on Saturday, 23 May 2015 03:16:56 UTC