

Re: [cssom] CSS Value API

From: Tab Atkins Jr. <jackalmage@gmail.com>
Date: Thu, 22 Apr 2010 10:23:11 -0700
Message-ID: <x2idd0fbad1004221023vbcfc7832ta08956e6aef8cfc3@mail.gmail.com>
To: Brad Kemper <brad.kemper@gmail.com>
Cc: Anne van Kesteren <annevk@opera.com>, Boris Zbarsky <bzbarsky@mit.edu>, François REMY <fremycompany_pub@yahoo.fr>, www-style@w3.org
On Thu, Apr 22, 2010 at 8:56 AM, Brad Kemper <brad.kemper@gmail.com> wrote:
> On Apr 7, 2010, at 9:02 AM, Anne van Kesteren wrote:
>> On Wed, 07 Apr 2010 17:50:45 +0200, François REMY <fremycompany_pub@yahoo.fr> wrote:
>>> To be logical, we should modify margin-top to calc(15%+1px).
>>> Or is that no more allowed by CSS-Values?
>> For some definition of logical that is certainly an interesting idea. It would however completely break the getter/setter symmetry of "px". I personally value that a little higher.
> Could you explain this further? Wouldn't you also get the px value of something that had a percentage style, as though you were using calc()?
> Or, put differently, when setting the margin-top in this example, I would hope for this to  convert the percentage to px, add one px, then convert back to percentage (so that you are increasing the margin by one pixel based on the current width of the containing block, but not changing the continuing relationship between the margin and the containing block).

This is getting into a more complex issue that I think needs to be
brought to light explicitly.  CSS lengths can occur in at least three
contexts, which affect how the respond to changes in the values of
other elements.  For simplicity, I'll just talk about it in terms of
the width property:

1. The specified length is in "absolute space".  This means it's
specified in px, in, etc.  The used value for this length is
unaffected by changes in any other property.

2. The specified length is in "em space".  The used value is affected
by the font-size of the element, and will change if the font-size

3. The specified length is in "% space".  The used value is affected
by the width of the element's containing block, and will change if the
containing block's width does.

(4. The specified length is in a mixed space, created by a calc expression.)

It matters very much which space the specified value is in.  This is
unambiguous in normal CSS, because it's defined simply by whatever
unit you use to specify the value.  But this new get/set method makes
it ambiguous.  If you specify a width in %s, then say width.px++, what
happens?  Does it convert it to an equivalent value in % space?  Does
it switch it to absolute space?  Does it mix the two, implicitly
creating a calc() expression?  What if you then say width.em++?  What
about more complex values, such as if we introduce a flex unit and I
say width.flex++?  Does it even make *sense* to talk about converting
between flexes?

There are multiple ways to approach this, but we need to settle on a
definite way.

(My preferred approach is that the value is the space of whatever
access was used last.  If you last did a width.em set, it's in em
space.  If you last did a width.px, it's in absolute space.  Gets
don't change the space, only sets.  Is it possible for no-change sets
to be optimized away?  If so, that ruins this approach, so it's
important to know.)

One thing that might help reduce the tension between the options is an
additional function placed on each element that can do unit
interconversion in the context of an element/property.  That way you
can call, say, elem.width.convert(1,"px","em") and get the equivalent
em value out.  This way we can do unit combinations/conversions

Using my preferred approach, then, if you had an element with
width:15% and you wanted to increase it by 1px but stay in % space,
you'd do elem.width.percent=elem.width.convert(elem.width.px+1,"px","%");

> If you actually wanted to go further and change the margin-top to a calc value, you would instead do something like this:
> style.margin.m.top.calc.px++
> Then, if the margin-top in the example would become "calc(15%+1px)", and in a different example where margin-top already had a calc value, then it would become "calc((<previous-formula>)+1px)". If you wanted to convert a value to calc when getting it (for whatever strange reason), you could do that like this:
> style.margin.m.top.calc // --> "calc(15%)" in the first example

Making calc()ing an explicit option would be pretty cool, but let's
solve the base problem first.  ^_^

Received on Thursday, 22 April 2010 17:24:03 UTC
