Re: [css-containment] Splitting up the value

> 
> On 24 Apr 2015, at 23:52, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
> 
> Currently, there are four distinct types of "containment" invoked by
> the property:
> 
> 1. Layout containment - the element stops paying attention to its
> children for sizing purposes, defaulting to either 0x0 or 300x150 if
> not otherwise specified. (I was surprised to find that this isn't
> actually in the spec yet, but pretend it is.)
> 2. Paint containment - the element's contents are strongly clipped to
> the element's boundaries.  This is #1, #4, and #5 in the list defining
> strict containment
> <http://dev.w3.org/csswg/css-containment/#strictly-contained>.
> 3. Scroll containment - the element doesn't scroll.  This is #2 and #3
> in the list.
> 4. Style containment - none of the element's descendants have an
> effect on how styles are computed for any other element in the
> document.  This is #6 and #7 in the list.
> 
> During the talk, there was some discussion over whether scroll
> containment was necessary; it seemed like it would sometimes be Too
> Much Containment, and prevent people from being able to use the
> property.  Discussion with Ojan just now pointed out the it's not even
> necessary to add - paint containment + overflow:visible gives the
> exact same behavior.  Since this is the default, we'll get scroll
> containment for free on most elements anyway, and don't need this
> property to address it.
> 
> Of the remaining three, layout containment and paint containment seem
> like they can be usefully separated.  One can imagine common cases
> whether you'd want one of them, but not the other.  For example, the
> G+ stream can use paint containment on its posts, but needs layout to
> work normally so that heights are auto-calculated.
> 
> It doesn't seem like style containment is particularly important to
> separate out either way, but pulling it out gives us a simple naming
> scheme, so I'm doing so.
> 
> This brings me to the following proposal for a new grammar:
> 
> contain: none | strict | [ layout || paint || style ]
> 
> Where layout/paint/style turn on the appropriate form of containment,
> and "strict" turns on all three.
> 
> It feels like this a reasonably usable syntax for authors.  Thoughts?

I've been looking at some use cases Bloomberg is facing[1], and I agree that
layout containment is really useful, so whether or not we separate containment
into several toggles or not, I strongly support adding it.

Now, onto the splitting.

Layout containment and paint containment are indeed independently useful,
and should be possible to toggle separately.

It's far from obvious to me that you'd ever want style containment without
layout containment, but while it might be useless to control separately,
it don't think it's harmful, so maybe.

I also agree that scroll containment is somewhat coupled to paint containment.

With that in mind, your proposal seems generally reasonable.

However, I'm wondering if the containment property really is the best way
to trigger paint containment. If you want paint containment without scroll
containment, you can already get what you want. In the following
example, the containment property doesn't do do anything that wasn't
already achieved by the rest.
  foo {
    position: relative;
    overflow: hidden;
    containment: paint; /* does nothing */
  }

Instead of having a paint value on the containment property, we could
add a new value to overflow (clipped?) that does the same as
"overflow:hidden" plus scroll containment. Note that this already exists
in Gecko: "overflow: -moz-hidden-unscrollable" [2]

A few reasons to prefer that over "containment: paint;"

1) Even though "overflow: hidden" allows for scrolling through scripts,
the vast majority of the time, authors do not intend to use that. Adding
a value that does what they want (and nothing more) sounds right, especially
given that the unintended difference can affect performance.

Phrased differently, there are many case where you want overflow:hidden
and scroll containing, but you don't want the element to be a formatting
context, so "containment: paint" wouldn't be appropriate. This is
actually most uses of "overflow: hidden".

2) There are a few things other than overflow itself which depend on
overflow being non-visible, and which also make sense on a paint
contained element, but wouldn't work right if paint containment was
triggered with a property other than overflow:

Both the resize and the text-overflow properties only take effect
if overflow is something other than visible. If you want paint
containment, scroll containment, and resizability, in your model,
you can't get it:
  foo {
    containment: paint; /* paint containment */
    overflow: visible; /* scroll containment */
    resize: both; /* doesn't work because overflow is visible */
  }

This, however, would work:
  foo {
    position: relative;
    overflow: clip;
    resize: both; 
  }

Of course, we could change the definition of resize and text-overflow
to also take effect if the computed value of containment either strict
or an enumeration that includes paint, but it feels like another hint
that paint containment would be hanging off the wrong property.


All in all, I'd prefer not adding paint to containment, and adding
"clipped" to the 'overflow' property instead instead of having 'paint'
in the 'containment' property.

There's also a possible middle ground:
* add "clipped" to 'overflow'
* have "paint" in 'containment'. It's effect is that:
  * if 'overflow' is "visible", it computes to "clipped"
  * the element becomes a formatting context if it wasn't one already

Defined that way, "containment: paint" adds no new capability, but
maybe it is still convenient to have, so that authors who want total
containment can flip one single property (containment), rather
than 3 (containment, position, overflow).

 - Florian


[1] https://bloomberg.github.io/chromium.bb/#feature-setDataNoRelayout
[2] https://developer.mozilla.org/en-US/docs/Web/CSS/overflow

Received on Saturday, 25 April 2015 13:20:11 UTC