Re: CSSStyleDeclaration: Setting only a value or a priority

On Wed, Aug 21, 2013 at 3:42 PM, L. David Baron <> wrote:
> On Wednesday 2013-08-21 15:22 -0700, Tab Atkins Jr. wrote:
>> On Wed, Aug 21, 2013 at 3:14 PM, L. David Baron <> wrote:
>> > On Wednesday 2013-08-21 14:58 -0700, Tab Atkins Jr. wrote:
>> >> On Wed, Aug 21, 2013 at 2:46 PM, L. David Baron <> wrote:
>> >> > I think this is a really bad idea (which has apparently now made its
>> >> > way into the spec according to comments in
>> >> > , although I
>> >> > don't see any mention in this thread of it).
>> >> >
>> >> > The underlying mental model of setProperty has, I think, always been
>> >> > "append declaration".  The object model of declaration blocks was
>> >> > designed without an idea of preserving order; setProperty appends a
>> >> > declaration to the end.  Thus setProperty with no priority being a
>> >> > no-op if the declaration block already has an !important declaration
>> >> > for that property.
>> >>
>> >> I don't think it's ever been clear that the mental model was "append a
>> >> declaration".  The style OM is, as you say, an unordered dict.  The
>> >> underlying data has an order, but we lose that detail, along with
>> >> several others, in the translation to the OM.  Preserving the ordering
>> >> quality in one, somewhat hidden, way seems like a recipe for
>> >> confusion.
>> >
>> > Also, we're going to need to change to preserving order in order to
>> > support logical properties.  Having things like margin-start,
>> > margin-before, etc., requires preserving their order relative to
>> > margin-left, margin-top.  So all CSSOM operations on declarations
>> > will need to define what effect on order they have.
>> Wait, why?  Why is margin-left/start any different from
>> border-color/left?  Both are two shortcuts that touch the same
>> longhands.  We don't need anything special for ordering the border-*
>> properties.
> The approach of treating them as shorthands doesn't really scale to
> vertical; it explodes into too many properties.
> The alternative is to preserve order, which is the approach current
> drafts take.

This is getting rather tangential, but which drafts?  (We were unaware
of this when drafting Cascade, which treats everything from cascaded
value onward as unordered.)

>> >> It would be easy to argue that many parts of our OM weren't designed
>> >> well, but that's not what you're doing here.  (For example, we could
>> >> have exposed a list of declarations which is mutable, and a dict of
>> >> all properties/values which reflects the cascade and which is
>> >> read-only.)
>> >>
>> >> > I also think the use case is really obscure, and having to make an
>> >> > extra function call to address it (as today) is fine.  I don't see
>> >> > strong evidence that we need to change the Web platform to address
>> >> > it.
>> >>
>> >> I think it's quite reasonable to want an easy operation for "set this
>> >> property to this value".  When you're already in JS, the importance
>> >> doesn't matter nearly as much.
>> >
>> > I'm not convinced.  It's conceptually much more complex to depend on
>> > what's already in the declaration in this way.
>> It's just changing the value.  I think you're mixing up your more
>> intimate knowledge of what a declaration is composed of with what
>> authors actually think of.  As an author myself, I can tell you that
>> saying "setProperty('color', 'red')" is me just saying "set the
>> 'color' property to 'red'", not "if the property isn't currently
>> important, set it to 'red'; otherwise, set it to 'red !important'.
>> The fact that importance exists doesn't enter into my mind except in
>> rare circumstances when I'm having cascade issues.  I don't think I'm
>> rare in this position.
> Agreed that use of !important is rare overall.
> But I think the main use case for this API is "set this property on
> this element/rule".  The intent is to make a specific assignment.
> This assignment, due to the cascade, doesn't work all of the time,
> but use of !important makes it work a little more often.
> It seems really odd for that assignment to take place at totally
> different levels of the cascade depending on whether *that rule*
> happens to have a !important declaration of that property already.
>> I don't think authors will really need to use the other argument anyway.
> Right, which is why I think it makes more sense for omission of that
> argument to behave the same way the empty string does today, since I
> think that's the simple and understandable behavior (in so far as
> the cascade is understandable).
>> More importantly, though, I think it's very natural for omitting an
>> argument to mean "don't do anything special", which is what is
>> happening here.  You'd only give the third argument if you're
>> specifically trying to set the importance to a particular value; if
>> you omit it, you're just not thinking about importance at all, and
>> don't want to be bothered by it.
> I don't think authors "not thinking about importance at all" should
> get random importance as a function of what's already there.

There's your problem!  The cascade's not really understandable to most
people in the first place, so making them think about when using an
API that *actively hides the important parts of the cascade* (the
ordering aspect) probably isn't a good idea.

It's not about "[getting] random importance", it's about just changing
the value of a declaration *without touching the importance*.  You
don't care about the importance 99% of the time - you're in JS, the
cascade is unimportant, you're just trying to set a value.  Something
stupid you did to make the cascade work in your actual stylesheet has
no relevance to what you're trying to do right now, in JS.  If it
*is*, then you know what importance means and can live with providing
an extra argument.  Forcing authors who don't care about importance to
in fact care *more* about importance (you have to actively query the
current importance, something that virtually no one ever has a reason
to do) is backwards.


Received on Wednesday, 21 August 2013 23:00:12 UTC