- From: Tab Atkins Jr. <jackalmage@gmail.com>
- Date: Mon, 13 Sep 2010 18:36:19 -0700
- To: www-style list <www-style@w3.org>
We've been discussing CSSOM stuff recently in Chrome team, and I wanted to push back some of the discussion to the CSSWG list. This email *does not* represent Chrome's position, just my own, though various team members' contributions have played a part in forming these opinions. We've been mostly discussing Anne's proposed Values API. I think it's a great start, but doesn't address the larger problem that the shape of the APIs surrounding CSS is somewhat crazy. They don't work together - you've got el.style pointing to the @style attribute on an element, el.ownerDocument.defaultView.getComputedStyle('someproperty') to get a resolved value (sometimes a 'computed', sometimes a 'used' value), and the stylesheet-based API. These all work *completely* differently, with vastly different access patterns, some being writable while other are readonly, etc. It's just a bad situation overall. So, I've boiled down the use-cases I think are useful to address (not included in this email for brevity, but can be provided upon request) and come up with the list of what I think are the necessities for a complete and sane CSS API. I'm working out right now what I think this would actually end up looking like - I'll send a separate email when I have some concrete suggestions. On the subject of what values to get/set: 1. Author should be able to get the set of all cascaded values that contribute to the element's style. These should have the context (selector if they're from a decl block, or otherwise indicating that they come from a @style attribute or inheritance) and a specificity (possibly the list is sorted by specificity?). These entries should be readable and writable (except for decl blocks from user stylesheets, of course). (Possibly, @style should always be in the list, even if it doesn't actually specify any values. The inheritance block should always be in the list, because it always passes *something*, even if just the initial values to the root element.) 2. Author should be able to easily read and write styles in stylesheets and @style attributes. CSSOM has interfaces for the former, though they're clumsy. The latter is already exposed in a convenient way through the .style attribute of elements. 3. Author should be able to read the actual used style for all properties. This is the result of resolving all the cascaded values for each property to a single value. (This more-or-less refers to the "used value" in the CSS Values & Units draft.) In particular, this should do what authors naively *expect* el.style to do - it should give you the value of, say, font-style no matter whether it came from @style, cascaded in from a style sheet, or inherited in from the parent. 4. Author should be able to read the "animated style" of an element - the current value of the property as affected by transitions/animations/other stuff that changes the value without actually touching the "specified value". 5. Author should be able to write to an "override style" that doesn't affect any specific decl block or @style attribute. This can be thought of as a special js-only style attribute on the element, with appropriate specificity (probably, stronger than everything except user !important rules). That is, it automatically overrides any value that comes from stylesheets or the @style attribute. (It can, of course, subsequently be unset, allowing normal cascading to happen.) 6. Author should be able to ask a given element to convert an arbitrary value from one unit to another. This is useful for various scripting purposes, when you're trying to set various lengths and being able to refer to the environment of a particular element (for its definition of em or %, for example) is useful. Possibly #3 and #5 can be merged to be the read/write behavior of a single interface. Except for user !important rules, setting #5 immediately changes the value of the property no matter what, and reading #3 gives you the final value, which, if #5 was used, is the value from #5. Not completely certain this gives us the most sane behavior, but it should be definitely be looked into, to make author's lives easy. I could also see #5 instead participating in some slightly magical way in the list returned by #1, though I'm still working out how I'd like it to look. Notice that *not* listed above is a specific segregation between specified/computed/used values. This distinction between specified, computed, and used is completely useless to authors in general. When they're getting at decl blocks or @style (from #1 or #2), sure, stick with the specified value in the form that was provided. But when you're accessing the "real style" (#3 above), they shouldn't have to care - they should be able to ask for the value in px, em, or percent (or keyword, rgb, or hsl, for that matter) no matter what the original value was specified in. Using Anne's Values API for this seems great. Possibly use it for #1 too, with some caveats that it can only convert between certain units (specifically, those that don't depend on layout to figure out, so px->em is cool, but not %->px). This does bring up a few interesting conflicts. For example, how can you distinguish between wanting the specified value regardless of source (say, "50%"), and the used/actual value based on layout (if the element is display:none, "0px" or maybe some defined "this value doesn't exist" value, since there's no box to measure - especially important for prop)? I think that can be punted by the fact that authors would have easy access to both the cascaded values (#1) and the "real value" (#3). #1 is easy to ask for the specified value - if nothing else, you can just walk the returned array (assuming it's sorted by specificity), grabbing the value from the first block that specifies it. We could easily convenience this away, too, giving the author an easy ability to ask "what decl block contributed the winning value for this property?". #3 is then free to be as magical/useful as we can make it, properly paying attention to layout and such. Once you've dropped down to used value level, converting between units should be easy to do, too - all the information you need is already there. I think the "animation style" (#4) would be similar, in terms of allowing easy conversion between units? I think this hits all the major use-cases for things we want to do with CSS, in a relatively sane way. You can access all the various stylesheet levels for reading/writing, get access to the declaration blocks that contribute values for specific properties, set style regardless of what comes in from the document, and query for the used value of a property in any unit. Thoughts? Am I missing something? Am I off-track in something? ~TJ
Received on Tuesday, 14 September 2010 01:37:13 UTC