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

Re: [css-multivalued][proposal] Lists as first-class CSS citizens

From: François REMY <fremycompany_pub@yahoo.fr>
Date: Wed, 22 Feb 2012 21:19:49 +0100
Message-ID: <482590F012D84A48A39E9D9B86937E85@FREMYD2>
To: "Tab Atkins Jr." <jackalmage@gmail.com>, "CSS 3 W3C Group" <www-style@w3.org>
Okay, sorry for late reply, I'm fairly overloaded these days.

I've nothing to change about what I said in the previous mail: variables 
offer poor solution for the list problem, but I recognize they provide a 
solution and they'll probably be the first available solution. I continue to 
support that. However, the following issues makes them higly unpractical:

(1) Variables are inherited, while many list properties are not, due to 
their nature. This includes at least 'background', 'transform', and 
'transition', which are the main use cases I'm targeting here. Your code 
need to be reworked like that :

.foo {
  transform: data(rotate) data(zoom);
  data-rotate: rotate(0); // identity
  data-zoom: scale(1); // identity

.foo > * {
    data-rotate: rotate(0); // identity
    data-zoom: scale(1); // identity

.foo.rotated { data-rotate: rotate(180deg); }
.foo.zoomed { data-zoom: scale(1.1); }

This is really long for such a simple feature.

(2) It's not possible to mitigate content using contextual fallback. Imagine 
a browser who only support three lenghts for box-shadow. With a proper 
solution, it's possible to do:

.innerGlow {
    box-shadow[innerGlow]: 0px 0px 2px;
    box-shadow[innerGlow]: 0px 0px 5px 3px;

It's not possible to do that with variables. Worse, this situation happening 
with variables will invalidate the whole box-shadow property and invalidate 
other box shadows (outer glow...) that could have been perfectly correctly 
applied otherwhise. A possible solution for variables would be to include a 
"firstOf(a,b,...)" function which return the first recognized value for the 
current token type read by the user argent but this will take a while to be 

(3) You need to know exactly how many elements will fit in the list and 
their name, and their nature. All the (potential) elements included in the 
collection need to be known 'from begining' (the "transform: data(rotate) 
data(zoom);" part of your sample). This is unfortunate and doesn't play well 
in the case multiple stylesheets from different sources apply (think: 
alternate stylesheets, user style, main.css+part1.css...).

(4) It makes code less understandable. By requiring to search where the data 
property is finally used to understand how it works, and by favorising the 
use of 'custom' non-standard properties, it lead to more difficult to manage 

(5) Requires list to have the concept of "no-op", or to introduce it to 
variables instead.

I think this list should be sufficient to motivate the adoption of a more 
suited solution, at least in the long run. As for the order of 
identifier-indexed properties, maybe could we use the "most important 
declaration is first" principle, which is frequent in CSS.

-----Message d'origine----- 
From: Tab Atkins Jr.
Sent: Wednesday, February 22, 2012 1:31 AM
To: François REMY
Cc: CSS 3 W3C Group
Subject: Re: [css-multivalued][proposal] Lists as first-class CSS citizens

I support the general idea of getting syntax support for list-valued
property manipulation.  I definitely support integer indexes.

I like the idea of named indexes, but I really don't like the
implementation you describe.  For starters, identifiers aren't
restricted to ASCII, so ASCII-sorting doesn't work.  ^_^  Using the
name to sort is bad, too - in your example, if you wanted the 'zoom'
transform to come before the 'rotate' one, you'd have to change the
names to something like 'a-zoom' and 'b-rotate'.

In the previous discussion about list-valued properties, I noted that
Variables solves the problem for free, with only slightly more syntax
than the minimum case.  For example, your first example could be
written as:

.foo {
  transform: data(rotate) data(zoom);
  data-rotate: rotate(0); // identity
  data-zoom: scale(1); // identity
.foo.rotated { data-rotate: rotate(180deg); }
.foo.zoomed { data-zoom: scale(1.1); }

If I add the ability to give default values for unset vars, it gets
even shorter:

.foo { transform: data(rotate, rotate(0)) data(zoom, scale(1)); }
.foo.rotated { data-rotate: rotate(180deg); }
.foo.zoomed { data-zoom: scale(1.1); }

This depends on every list-valued property having a no-op value.  I
think this is true for all the parallel-lists (like text-shadow), but
not the fallback-lists (like font-family), but I'd have to do a search
to check.  If there are enough without that we think it matters, or if
we just wanted to make it work generically without people having to
memorize the no-op value for every property, we could add this into
Variables directly with a value that always represents a no-op.

Your other examples can be similarly converted into Variables.  This
isn't without its problems - vars being used for different properties
can accidentally collide unless you deliberately prefix them.  But it
gets us a lot of the way there without having to add more new syntax
that violates the Core Grammar.

Received on Wednesday, 22 February 2012 20:20:13 UTC

This archive was generated by hypermail 2.3.1 : Wednesday, 7 January 2015 16:28:39 UTC