- From: Roland Steiner <rolandsteiner@chromium.org>
- Date: Thu, 6 Oct 2011 12:28:17 +0000
- To: www-style@w3.org
- Message-ID: <CACFPSpjJO3f=egkf-k=1rw+5A6rOTVN2Gn8F42TxvZDzMsLDMg@mail.gmail.com>
Hi all,
In a previous thread regarding components and user-defined pseudo-elements (
http://lists.w3.org/Archives/Public/www-style/2011Aug/0280.html) I made a
suggestion to add user-defined CSS properties instead. However, I believe
this idea might have wider applicability, so I'd like to present it here in
a more general context. But please note that all this still very much is
brainstorming, so please be gentle... ;)
Overview:
The proposal consists of 2 parts:
1.) Allow users to define arbitrary CSS properties (using some syntax) that
inherit and cascade as normal.
2.) Add a function apply() that returns the current value of a CSS property.
Details:
In style rules, a user can add arbitrary properties, prefixed by '::' (a
parallel to pseudo-elements, but the exact syntax doesn't matter). Such
properties cascade and inherit as normal. In and of themselves, user-defined
properties have no effect, but a script can query them using
getComputedStyle(). The value of a user-defined property is similarly
arbitrary, but we might add an (optional?) type identifier.
apply(<property>) returns the current inherited value of the specified
property for the current node. apply() on an undefined property is invalid
(or returns the empty string?). For example:
<div class=A>
<div class=B>
<div class=C>
.A {
::foo: color red;
::bar: color blue;
::quz: length 2px;
}
.B {
color: apply(::foo); [1]
}
.C {
::foo: color green; [2]
background-color: apply(::foo); [3]
border-color: apply(color); [4]
padding: 0 2px; [5a]
padding: 0 apply(::quz); [5b]
padding: 0 apply(::quz) 0 apply(::qoz); [5c]
}
[1] set color to the current value of ::foo, i.e., red. It is NOT set to a
dynamic 'apply(::foo)' value.
[2] as noted in [1], apply() is NOT dynamic, so even though ::foo changes
here, 'color' is still red, as inherited.
[3] apply() returns the inherited value, NOT any overridden value of the
current rule, so background-color would be red.
[4] apply should be usable with any property, not just user-defined
properties.
[5a] a default padding
[5b] a more specific padding to be used iff ::quz is defined and applicable
(which it is), overriding [5a]
[5c] ::quz is defined and legal here, but ::qoz isn't, so the whole line
isn't applied, leaving the padding defined in [5b]
Other usage examples:
.menu {
::lo-color: color #000044;
::hi-color: color #0000CC;
}
.warning {
::lo-color: color #440000;
::hi-color: color #CC0000;
}
div.colored {
color: apply(::hi-color);
background-color: apply(::lo-color)
}
pre {
border: 1px solid apply(::lo-color)
}
body {
::level: integer 0;
}
.nested {
::level: calc(apply(::level) + 1);
}
.nested::before {
content: apply(::level) ' ';
}
A component use case (which spawned this whole proposal):
video {
border: 1px solid black;
::play-background-color: slategrey;
::stop-background-color: darkred;
::panel-color: black;
::click-sound: true;
}
As implied above, apply() can be useful in and of itself:
.negative { /* switch background and text color, whatever they currently
are */
color: apply(background-color);
background-color: apply(color);
}
Fundamentally, this proposal is similar to CSS variables, but - I would
argue - more powerful:
.) The user-defined properties inherit and participate in the cascade. I.e.,
they can change based on combination of layout, media queries, etc.
.) apply() can express inter-dependencies, like shown in the examples above.
.) It'd be terribly useful for components... ;)
What do you think?
- Roland
Received on Thursday, 6 October 2011 12:29:06 UTC