Intent to Implement and Ship: “all” CSS shorthand.

146 views
Skip to first unread message

Kenji Baheux

unread,
May 12, 2014, 4:58:08 AM5/12/14
to blink-dev, Takashi Sakamoto, Hayato Ito, Dimitri Glazkov

Contact emails

hay...@chromium.org, ta...@chromium.org (kenji...@chromium.org)


Spec

http://dev.w3.org/csswg/css-cascade/#all-shorthand


Summary

The all property is a shorthand that resets all CSS properties except direction and unicode-bidi. It only accepts the CSS-wide keywords.


Motivation

resetStyleInheritance has been removed from Shadow DOM. Folks have taken notice and are asking for the CSS all shorthand as an alternative.


Compatibility Risk

I believe that the risk is fairly low:

  • The CSS Level 3 specification is a candidate recommendation.

  • Firefox is shipping an implementation of the all shorthand.

  • The API surface is small.


Firefox: Shipped (27)

Internet Explorer: No public signals (*)

Safari: No public signals (*)

Web developers: Positive


*: didn’t find anything major from a quick search => defaulting to “no signals”.



OWP launch tracking bug

https://code.google.com/p/chromium/issues/detail?id=172051


Ongoing technical constraints

None.


Will this feature be supported on all five Blink platforms (Windows, Mac, Linux, Chrome OS and Android)?

Yes.


OWP launch tracking bug?

None has been filed.


Entry in Chromium Dashboard

http://www.chromestatus.com/admin/features/edit/6178222542684160


Requesting approval to ship?

Yes.

Adam Barth

unread,
May 12, 2014, 5:03:04 AM5/12/14
to kenji...@chromium.org, blin...@chromium.org, ta...@chromium.org, hay...@chromium.org, dgla...@chromium.org, Elliott Sprehn
Pardon my ignorance, but how would this constrain our ability to change the data structure we use for RenderStyle.  For example, I can imagine that setting "all: inherit" would require that we reify a RenderStyle that contained every possible property, which could make it difficult to switch to a RenderStyle data structure that optimizes for the common case of not every property existing on most RenderStyles.

Relatedly, are there use cases for "all" besides "all: initial" ?  It's unclear to me why it would be useful to set "all: inherit"...

Adam

Dirk Schulze

unread,
May 12, 2014, 5:11:49 AM5/12/14
to Adam Barth, kenji...@chromium.org, blin...@chromium.org, ta...@chromium.org, hay...@chromium.org, dgla...@chromium.org, Elliott Sprehn

On May 12, 2014, at 11:03 AM, 'Adam Barth' via blink-dev <blin...@chromium.org> wrote:

> Pardon my ignorance, but how would this constrain our ability to change the data structure we use for RenderStyle. For example, I can imagine that setting "all: inherit" would require that we reify a RenderStyle that contained every possible property, which could make it difficult to switch to a RenderStyle data structure that optimizes for the common case of not every property existing on most RenderStyles.
>
> Relatedly, are there use cases for "all" besides "all: initial" ? It's unclear to me why it would be useful to set "all: inherit"…

For scripting 'all: inherit' can be useful. Consider that one encapsulate content into a new wrapper element but wants the content to be consistent to its previous behavior — including inheritance from parents.

Sounds obscure, but there are use cases like embedding HTML text into a new created <svg> element for styling purposes with fill and stroke. One wants the text within the <svg> element to have the same font and text settings as it had before wrapping.

Today, users work around it by setting all necessary properties manually to inherit. Since new properties appear in the future, ‘all: inherit’ is more future proof and you would just set it on <svg>.

Greetings,
Dirk

Adam Barth

unread,
May 12, 2014, 5:33:15 AM5/12/14
to dsch...@chromium.org, kenji...@chromium.org, blin...@chromium.org, ta...@chromium.org, hay...@chromium.org, dgla...@chromium.org, esp...@google.com
On Mon May 12 2014 at 2:11:52 AM, Dirk Schulze <dsch...@chromium.org> wrote:

On May 12, 2014, at 11:03 AM, 'Adam Barth' via blink-dev <blin...@chromium.org> wrote:

> Pardon my ignorance, but how would this constrain our ability to change the data structure we use for RenderStyle.  For example, I can imagine that setting "all: inherit" would require that we reify a RenderStyle that contained every possible property, which could make it difficult to switch to a RenderStyle data structure that optimizes for the common case of not every property existing on most RenderStyles.
>
> Relatedly, are there use cases for "all" besides "all: initial" ?  It's unclear to me why it would be useful to set "all: inherit"…

For scripting 'all: inherit' can be useful. Consider that one encapsulate content into a new wrapper element but wants the content to be consistent to its previous behavior — including inheritance from parents.

Sounds obscure, but there are use cases like embedding HTML text into a new created <svg> element for styling purposes with fill and stroke. One wants the text within the <svg> element to have the same font and text settings as it had before wrapping.

Today, users work around it by setting all necessary properties manually to inherit. Since new properties appear in the future, ‘all: inherit’ is more future proof and you would just set it on <svg>.

Do you really want to inherit properties like margin or transform?  Rather than making your wrapper transparent, they'd make your content telescope off in some direction.

Eric Seidel

unread,
May 12, 2014, 6:11:15 AM5/12/14
to Adam Barth, Dirk Schulze, Kenji Baheux, blink-dev, Takashi Sakamoto, Hayato Ito, Dimitri Glazkov, Elliott Sprehn
I'm very skeptical of the use-case of this feature.

https://developer.mozilla.org/en-US/docs/Web/CSS/all

Does anyone know of documentation of use-cases for this? Presumably
this is to break inheritance chains by adding a dummy root element
with all: unset; and then at least all the kids won't inherit
properties from the grandparents? Specifying all: unset; on anything
you actually want to style seems disruptive since I wouldn't expect
you'd want to override the UA's styling in many cases.

On Mon, May 12, 2014 at 11:33 AM, 'Adam Barth' via blink-dev

Takashi Sakamoto

unread,
May 12, 2014, 9:50:09 AM5/12/14
to Adam Barth, kenji...@chromium.org, blink-dev, Takashi Sakamoto, Hayato Ito, dgla...@chromium.org, Elliott Sprehn
I think, "all" should not affect RenderStyle. So my patch doesn't need to update RenderStyle.

My patch is adding "all longhands=" line to CSSShorthands.in. However, adding the line to CSSShorthands.in manually is too expensive to maintain "all". (e.g. if someone wants to add a new CSSProperty, he needs to update the line...)

So the patch introduces a new python script and modifies the way to generate StylePropertyShorthand.cpp and StylePropertyShorthand.h from CSSShorthands.in:

css/CSSShorthands.in + css/CSSPropertyNames.in + CSSShorthands.in.tmp (newly added)
 ==> gen/Blink/CSSShorthands.in (<== done by make_css_shorthands.py added newly)

So Blink generates StylePropertyShorthand.h and cpp from the above gen/Blink/CSSShorthands.in:

 ==> gen/Blink/StylePropertyShorthand.h, StylePropertyShothand.cpp

When updating CSSPropertyNames.in or CSSShorthands.in, "all" will be updated automatically.

Best regards,
Takashi Sakamoto

Adam Barth

unread,
May 12, 2014, 12:43:25 PM5/12/14
to Takashi Sakamoto, kenji...@chromium.org, blink-dev, Takashi Sakamoto, Hayato Ito, dgla...@chromium.org, Elliott Sprehn
Doesn't it cause every sub-object of RenderStyle to become reified?  In the future, we might want to change RenderStyle to optimize for the normal case of most RenderStyles not having many non-initial property values.  If we do that, reifying every possible property in RenderStyle could become prohibitively expensive.

To be clear, all: initial seems like something that has good use cases and won't constrain future development of the engine.  My concern is whether the other values have sufficient use cases to justify the constraints they place on the style system.

Adam

Eric Bidelman

unread,
May 12, 2014, 1:24:43 PM5/12/14
to Adam Barth, Takashi Sakamoto, Kenji Baheux, blink-dev, Takashi Sakamoto, Hayato Ito, Dimitri Glazkov, Elliott Sprehn
Eric, 

I can't speak to general use cases, but an important one for web components is resetting styles at a shadow root.

From Kenji:
Motivation

resetStyleInheritance has been removed from Shadow DOM. Folks have taken notice and are asking for the CSS all shorthand as an alternative.


When resetStyleInheritance was removed, it left authors without an easy way to start fresh.
We've been promising devs a replacement ever since (CSS "all"). Including a reset stylesheet in each component is a solution, but highly cumbersome. Setting a css property is much nicer.


To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Takashi Sakamoto

unread,
May 12, 2014, 2:08:34 PM5/12/14
to Adam Barth, kenji...@chromium.org, blink-dev, Takashi Sakamoto, Hayato Ito, dgla...@chromium.org, Elliott Sprehn
I'm interested in the new RenderStyle. I would like to know whether "all" blocks implementing the new RenderStyle or not.

2014-05-12 18:43 GMT+02:00 Adam Barth <aba...@google.com>:
Doesn't it cause every sub-object of RenderStyle to become reified?  In the future, we might want to change RenderStyle to optimize for the normal case of most RenderStyles not having many non-initial property values.  If we do that, reifying every possible property in RenderStyle could become prohibitively expensive.

I would like to know how the new RenderStyle treats the following normal "initial"s:

  color: initial;
  background-color: initial;
  ...
  border-left-width: initial;
  ...

I think, we still need to support the case that we have many properties with initial values.

"all: initial" is converted into such many properties with initial values in CSS property parser.

So from the viewpoint of StyleResolver, StyleBuilder, and so on, no "all" is found. Just many properties with initial value are found.

Best regards,
Takashi Sakamoto

Elliott Sprehn

unread,
May 12, 2014, 3:23:10 PM5/12/14
to Takashi Sakamoto, Adam Barth, Kenji Baheux, blink-dev, Takashi Sakamoto, Hayato Ito, Dimitri Glazkov
On Mon, May 12, 2014 at 2:08 PM, Takashi Sakamoto <ta...@google.com> wrote:
I'm interested in the new RenderStyle. I would like to know whether "all" blocks implementing the new RenderStyle or not.

2014-05-12 18:43 GMT+02:00 Adam Barth <aba...@google.com>:

Doesn't it cause every sub-object of RenderStyle to become reified?  In the future, we might want to change RenderStyle to optimize for the normal case of most RenderStyles not having many non-initial property values.  If we do that, reifying every possible property in RenderStyle could become prohibitively expensive.

I would like to know how the new RenderStyle treats the following normal "initial"s:

  color: initial;
  background-color: initial;
  ...
  border-left-width: initial;
  ...

I think, we still need to support the case that we have many properties with initial values.

"all: initial" is converted into such many properties with initial values in CSS property parser.

So from the viewpoint of StyleResolver, StyleBuilder, and so on, no "all" is found. Just many properties with initial value are found.



I don't think we want that, it means that the "all" property is super expensive. Normally we go through applyMatchedProperties with only a few properties for each element. A custom element that uses "all" would go through it for hundreds of properties. It also means the StylePropertySet for that rule will be massive.

I think we need to figure out how to implement this in a way that does't involve O(N) space and property application where N is the ever increasing number of CSS properties in the whole platform.

I don't think we should ship this until we figure out how this can be implemented in constant time. If it can't, we need to rethink the feature.

- E

Takashi Sakamoto

unread,
May 13, 2014, 4:36:50 AM5/13/14
to Elliott Sprehn, Adam Barth, Kenji Baheux, blink-dev, Takashi Sakamoto, Hayato Ito, Dimitri Glazkov
2014-05-12 21:23 GMT+02:00 Elliott Sprehn <esp...@google.com>:

On Mon, May 12, 2014 at 2:08 PM, Takashi Sakamoto <ta...@google.com> wrote:
I'm interested in the new RenderStyle. I would like to know whether "all" blocks implementing the new RenderStyle or not.

2014-05-12 18:43 GMT+02:00 Adam Barth <aba...@google.com>:

Doesn't it cause every sub-object of RenderStyle to become reified?  In the future, we might want to change RenderStyle to optimize for the normal case of most RenderStyles not having many non-initial property values.  If we do that, reifying every possible property in RenderStyle could become prohibitively expensive.

I would like to know how the new RenderStyle treats the following normal "initial"s:

  color: initial;
  background-color: initial;
  ...
  border-left-width: initial;
  ...

I think, we still need to support the case that we have many properties with initial values.

"all: initial" is converted into such many properties with initial values in CSS property parser.

So from the viewpoint of StyleResolver, StyleBuilder, and so on, no "all" is found. Just many properties with initial value are found.



I don't think we want that, it means that the "all" property is super expensive. Normally we go through applyMatchedProperties with only a few properties for each element. A custom element that uses "all" would go through it for hundreds of properties. It also means the StylePropertySet for that rule will be massive.

Yeah. "all" is converted into many longhands. This affects StylePropertySet and applyMatchedProperty, not RenderStyle.

However, "all" is just shorthand. If we need special code for "all", I think, the design is not good.

In my understandings,
 - resetStyleInheritance is rarely use (just for debugging?).
 - "all" is proposed to replace "resetStyleInheritance".
 - So custom elements rarely use "all".

If we have no "all", instead, web developers need to write many properties. If they write, StylePropertySet will be massive. So we have the same problem, I think.

I think we need to figure out how to implement this in a way that does't involve O(N) space and property application where N is the ever increasing number of CSS properties in the whole platform.

I guess, this means, we need to make applyMatchedProperties more complicated.

I don't think we should ship this until we figure out how this can be implemented in constant time. If it can't, we need to rethink the feature.

I think, few web developers need "all". If we need special code (that normal shorthands don't use) for "all", it would be better to unship "all".

Best regards,
Takashi Sakamoto

Tab Atkins Jr.

unread,
May 13, 2014, 9:43:42 AM5/13/14
to Takashi Sakamoto, Elliott Sprehn, Adam Barth, Kenji Baheux, blink-dev, Takashi Sakamoto, Hayato Ito, Dimitri Glazkov
On Tue, May 13, 2014 at 10:36 AM, 'Takashi Sakamoto' via blink-dev
<blin...@chromium.org> wrote:
> However, "all" is just shorthand. If we need special code for "all", I
> think, the design is not good.

I strongly disagree. The fact that 'all' is a shorthand has nothing
to do with the fact that it might require special code to handle -
it's a very special kind of shorthand which expands out to 400+
properties, whereas no other shorthand expands to more than a dozen or
so properties. While saying "it's a shorthand!" is very simple
conceptually and easy for authors, it's violates internal assumptions
sufficiently that I think it's rather normal for it to not be handled
by the existing shorthand code.

> In my understandings,
> - resetStyleInheritance is rarely use (just for debugging?).

No, it's useful any time you're doing an *independent* custom element,
which is supposed to have its own style or "look" rather than
integrating with the surrounding page, such as the Facebook Like
button.

> - "all" is proposed to replace "resetStyleInheritance".
> - So custom elements rarely use "all".
>
> If we have no "all", instead, web developers need to write many properties.
> If they write, StylePropertySet will be massive. So we have the same
> problem, I think.

Yes.

~TJ

Tab Atkins Jr.

unread,
May 13, 2014, 9:46:41 AM5/13/14
to Adam Barth, Kenji Baheux, blink-dev, ta...@chromium.org, Hayato Ito, Dimitri Glazkov, Elliott Sprehn
On Mon, May 12, 2014 at 11:03 AM, 'Adam Barth' via blink-dev
<blin...@chromium.org> wrote:
> Pardon my ignorance, but how would this constrain our ability to change the
> data structure we use for RenderStyle. For example, I can imagine that
> setting "all: inherit" would require that we reify a RenderStyle that
> contained every possible property, which could make it difficult to switch
> to a RenderStyle data structure that optimizes for the common case of not
> every property existing on most RenderStyles.
>
> Relatedly, are there use cases for "all" besides "all: initial" ? It's
> unclear to me why it would be useful to set "all: inherit"...

Yes, "all: unset;" is also useful. In the future, we intend to define
the (currently reserved but useless) global keyword of "default" to be
like "unset" but respecting the UA and user stylesheets, so that'll be
useful in the future too.

"all: inherit", itself, isn't very useful, but it's the last global
keyword, and we thought it would be confusing to not include it. If
there are implementation concerns about it, please discuss this on
www-style, because this is the first I've heard of this.

~TJ

Takashi Sakamoto

unread,
May 13, 2014, 11:04:58 AM5/13/14
to Tab Atkins Jr., Elliott Sprehn, Adam Barth, Kenji Baheux, blink-dev, Takashi Sakamoto, Hayato Ito, Dimitri Glazkov
2014-05-13 15:43 GMT+02:00 Tab Atkins Jr. <jacka...@gmail.com>:
On Tue, May 13, 2014 at 10:36 AM, 'Takashi Sakamoto' via blink-dev
<blin...@chromium.org> wrote:
> However, "all" is just shorthand. If we need special code for "all", I
> think, the design is not good.

I strongly disagree.  The fact that 'all' is a shorthand has nothing
to do with the fact that it might require special code to handle -
it's a very special kind of shorthand which expands out to 400+
properties, whereas no other shorthand expands to more than a dozen or
so properties.  While saying "it's a shorthand!" is very simple
conceptually and easy for authors, it's violates internal assumptions
sufficiently that I think it's rather normal for it to not be handled
by the existing shorthand code.

So we need special code to support the following:

  all: initial !important;

or

  background-color: red !important;
  all: initial;

...

because we cannot expand all shorthand to longhands.

In applyMatchedProperties, we need to add special path for "all", all with important? (all + important + user-agent / author stylesheets + animated property + ...?)

I'm afraid that "all" makes Blink much more complicated. I think, we should not implement all at all.

No, it's useful any time you're doing an *independent* custom element,
which is supposed to have its own style or "look" rather than
integrating with the surrounding page, such as the Facebook Like
button.
>  - "all" is proposed to replace "resetStyleInheritance".
>  - So custom elements rarely use "all".
>
> If we have no "all", instead, web developers need to write many properties.
> If they write, StylePropertySet will be massive. So we have the same
> problem, I think.

Yes.

So currently web developers often write 400+ properties with "initial" or "unset".
Is there any difference between "before all" and "after all"?

If we expect that "all" is one solution to avoid 400+ properties, my current patch is bad. The patch doesn't solve this issue.

Best regards,
Takashi Sakamoto

Takashi Sakamoto

unread,
May 13, 2014, 11:36:46 AM5/13/14
to Tab Atkins Jr., Elliott Sprehn, Adam Barth, Kenji Baheux, blink-dev, Takashi Sakamoto, Hayato Ito, Dimitri Glazkov
I will try another solution, updating StyleBuilderCustom to support "all".


dgla...@google.com

unread,
May 19, 2014, 12:03:37 PM5/19/14
to blin...@chromium.org, Takashi Sakamoto, Hayato Ito, Dimitri Glazkov
LGTM

Ojan Vafai

unread,
May 20, 2014, 2:11:50 PM5/20/14
to Dimitri Glazkov, blink-dev, Takashi Sakamoto, Hayato Ito, Dimitri Glazkov
This LGTM to implement, but we should wait to ship until we are confident that we have an efficient implementation.


On Mon, May 19, 2014 at 9:03 AM, <dgla...@google.com> wrote:
LGTM

Eric Seidel

unread,
May 20, 2014, 2:27:37 PM5/20/14
to Eric Bidelman, Adam Barth, Takashi Sakamoto, Kenji Baheux, blink-dev, Takashi Sakamoto, Hayato Ito, Dimitri Glazkov, Elliott Sprehn
So this seems useful.

Do you want <iframe>-like style behavior of creating a new "style
inheritance context" (but including UA sheets) or do you want fully
clean-slate behavior? It appears all: initial; is attempting to do
clean-slate

Either of these feels like *input* into the style phase. It's setting
what element/stylesheets to inherit from.

I would recommend we re-think this as a DOM attribute instead of a CSS
property. CSS property is too late in the game. We're already
applying properties by the time we hit one of these, and then we have
to magically expando out to all properties, or we have to somehow
teach the style system to re-think the inheritance of the current
RenderStyle object it's operating on.

Would it make sense to have a stylesheet which set * { all: initial;
}? Presumably then the 100 stylesheets earlier in the cascade order
are then completely wasted work, and it might have been nice eto know
that before processing the properties of the 101th stylesheet and
applying them, only to reset everything done before.

It might be useful to the discussion to understand what tricks mozilla
employed to implement this.

Boris Zbarsky

unread,
May 20, 2014, 3:12:59 PM5/20/14
to blink-dev
On 5/20/14, 2:27 PM, Eric Seidel wrote:
> Would it make sense to have a stylesheet which set * { all: initial;
> }? Presumably then the 100 stylesheets earlier in the cascade order
> are then completely wasted work

Fwiw, "all: initial" doesn't actually set all properties to initial
values. See http://dev.w3.org/csswg/css-cascade/#all-shorthand which says:

The all property is a shorthand that resets all CSS properties except
direction and unicode-bidi.

and there's a note explaining why.

> It might be useful to the discussion to understand what tricks mozilla
> employed to implement this.

No tricks. We just expand "all: initial" as if it were an actual
shorthand by looping over every single longhand property except
'direction' and 'unicode-bidi' and setting them all to "initial". If
this starts getting used enough that it matters, we'll think about
something more efficient, but if you just have a few uses per page it's
not worth worrying about.

-Boris

Elliott Sprehn

unread,
May 20, 2014, 3:46:39 PM5/20/14
to Boris Zbarsky, blink-dev
On Tue, May 20, 2014 at 12:12 PM, Boris Zbarsky <bzba...@mit.edu> wrote:
On 5/20/14, 2:27 PM, Eric Seidel wrote:
Would it make sense to have a stylesheet which set * { all: initial;
}?  Presumably then the 100 stylesheets earlier in the cascade order
are then completely wasted work

[...]

It might be useful to the discussion to understand what tricks mozilla
employed to implement this.

No tricks.  We just expand "all: initial" as if it were an actual shorthand by looping over every single longhand property except 'direction' and 'unicode-bidi' and setting them all to "initial".  If this starts getting used enough that it matters, we'll think about something more efficient, but if you just have a few uses per page it's not worth worrying about.

Assuming a web components world, we expect pretty common usage, just like inline <style> in ShadowRoot. Every <jq-button> or <polymer-panel> on the page might use it, and a typical app might have hundreds of those.

- E

Boris Zbarsky

unread,
May 20, 2014, 3:58:18 PM5/20/14
to blink-dev
On 5/20/14, 3:46 PM, Elliott Sprehn wrote:
> Assuming a web components world, we expect pretty common usage, just
> like inline <style> in ShadowRoot. Every <jq-button> or <polymer-panel>
> on the page might use it, and a typical app might have hundreds of those.

Sure, but on the specified style level presumably they're all actually
matching the same rule that sets "all: initial", so the specified style
is present exactly once.

And at least in Gecko, the computed style in this case will also be
shared (because this is the easy case where we can store the computed
style next to the specified style except in cases where other rules
override this one) so will be present in memory exactly once.

The inefficient case for us isn't when lots of elements all match the
same "all: initial" rule but when there are lots of different
"all:initial" rules around.

-Boris

Boris Zbarsky

unread,
May 20, 2014, 4:00:36 PM5/20/14
to blink-dev
On 5/20/14, 3:58 PM, Boris Zbarsky wrote:
> The inefficient case for us isn't when lots of elements all match the
> same "all: initial" rule but when there are lots of different
> "all:initial" rules around.

Or, for computed style, when there is a high-specificity "all:initial"
rule for elements which have different low-specificity rules applying to
them, since in those cases we can't do computed style sharing I described.

-Boris
Reply all
Reply to author
Forward
0 new messages