Re: WebKit now supports CSS Variables

On Fri, Jun 27, 2008 at 3:15 PM, Andrew Fedoniouk
<news@terrainformatica.com> wrote:
> Here is what people are doing in this case:
>
> --- site-a.css ---
> @const PrimaryColor: blue;
> @const SecondaryColor: green;
> @const LinkColor: purple;
> @const PanelBackground: maroon url(purple-circle.png) repeat;
>
> @import url(../common.css); /* styles that use parameters above */
> --- EOF ---
> . . .
> As you see common.css contains so called fallback set
> of constants. These values are used as defaults when master/host stylesheet
> does
> not contain some or all definitions.
>
> Such way of value inheritance (first-defined-first-used) is made
> intentionally.
> Pretty much the same can be achieved with !important modifier but there
> are cases when !important is not acceptable as it is too strong.

But if I'm reading this correctly, this requires local styles to be
placed *before* global styles.  This is the opposite of the way things
are normally done in CSS, where the *later* styles take precedence.  I
think this might cause quite a bit of extra clutter.  For instance,
consider the MediaWiki software.  It loads all of the following
stylesheets, in the following order (some possibly appended onto the
end of others, some loaded really as separate files):

* A hardcoded common CSS file shared among all skins, users, etc.
* A hardcoded skin-specific CSS file
* An admin-customizable common CSS file
* An admin-customizable skin-specific CSS file
* A user-specific CSS file to enforce preferences selected through the GUI
* A manually-created user-specific CSS file (that can contain
arbitrary CSS rules)

Each one of these must override the previous one, logically.
Currently this is achieved simply by loading them in that order.  To
override the previous one, you just include a rule, and it magically
works, overriding existing rules with the same specificity.

But for constants to be overridable at all levels, the stylesheets
would have to be loaded in the *opposite* order.  The manual
user-specific stylesheet's constants would need to go first, then the
automatic user-specific stylesheet, and so forth.  This reverses
current behavior and complicates it.  To get the full flexibility of
the proposal, allowing any stop along the line to change the
variables, you'd have to include twice as many stylesheets, separating
constants out from everything else.  Or at least, I can see no other
way this would work, with earlier declarations overriding later ones.

> As I have shown above @const will allow you to do this.
>
> @const give you two options:
>
> 1) You can parametrize (a.k.a. pass parameters) slave style sheets in master
> CSS and
> 2) You can redefine/overwrite rules if it is needed in slave CSS.

Only by including everything in reverse order to usual, with the most
specific coming first and the most general coming last.

> In case of @variables parametrization is doubtful.
> Say some style sheet on 3rd level and under some condition (MQ, hello!)
> of inclusion will accidentally redefine some of variable(s). That will break
> the whole
> system you originally crafted. To find such redefinition is difficult
> usually.

But exactly the same applies to constants, just in reverse.  Say some
style sheet on the *first* level and under some condition of inclusion
will accidentally redefine some *constants*.  Then all *subsequently*
loaded stylesheets will break.  (And finding such a redefinition
should just be a matter of grep, in either case; plus it shouldn't
arise to begin with, with proper naming conventions.)

I think that "constants" and "variables" are the wrong way to contrast
the two proposals.  Instead, the contrast should be "first occurrence
overrides later ones" vs. "last instance overrides earlier ones".  The
former might be somewhat easier to implement, but the latter is how
CSS rules work, and so it's more consistent with how things work now,
IMO.

> Consider this:
>
> Say you have company "A" that is designing web application/component
> "www.AA.com".
> Another company "B" is willing to use that application with styles tweaked
> for their own
> case (that is known as [re-]branding in real world).
> @const allow you to do such thing naturally but @variables will not help you
> here.

Why don't they?  Just redefine the @variable after you load the
company A stylesheet.  This will immediately change all previous uses
of the variable.

To clarify, suppose we have these three stylesheets:

a.css:
@variables { x: 10em; }
div.myclass { height: var(x); }

b.css:
@variables { x: 15em; }

c.css:
@import "a.css";
@import "b.css";

I'm imagining that this will cause div.myclass to have height 15em,
*not* 10em.  This would then be the same as

b.css:
@const x: 15em;

a.css:
@const x: 10em;
div.myclass { height: var(x); }

c.css:
@import "b.css";
@import "a.css";

So as I say, the only difference is the order of inclusion.  If you're
supposing that the variables will work like in programming languages,
and the @variables section above would give a result of 10em because
that's what x is when the .myclass rule is parsed, then I completely
agree that this would be much less useful.  I don't think that's
what's being discussed, however.  As David Hyatt clarified earlier:

On Tue, Jun 24, 2008 at 1:43 PM, David Hyatt <hyatt@apple.com> wrote:
> On Jun 24, 2008, at 10:39 AM, Francois Remy wrote:
>> The normal way it should be, if we reuse known CSS Priority types :
>>  Each variable is globally defined and the last variable defined in the
>> normal order is used accross all stylesheets.
>
> This is how the WebKit implementation currently behaves.


> And yet @const are 1) significantly easier to implement 2) allow to define
> aggregates so expect
> them to be implement uniformly across all UAs.

I'll leave comments on ease of implementation up to the implementers,
but as a web programmer, it would be considerably more convenient to
have later declarations override earlier ones.  I don't know what you
mean by #2.

Received on Sunday, 29 June 2008 17:00:42 UTC