This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 16328 - Use of "containing block" does not match CSS2.1 definition
Summary: Use of "containing block" does not match CSS2.1 definition
Status: RESOLVED MOVED
Alias: None
Product: CSS
Classification: Unclassified
Component: Transforms (show other bugs)
Version: unspecified
Hardware: All All
: P2 normal
Target Milestone: ---
Assignee: Simon Fraser
QA Contact: public-css-bugzilla
URL:
Whiteboard:
Keywords:
: 18500 19637 (view as bug list)
Depends on:
Blocks:
 
Reported: 2012-03-12 19:55 UTC by Aryeh Gregor
Modified: 2017-01-13 17:57 UTC (History)
16 users (show)

See Also:


Attachments

Description Aryeh Gregor 2012-03-12 19:55:17 UTC
See Mozilla bug: https://bugzilla.mozilla.org/show_bug.cgi?id=733849

The spec says:

"""
Elements establish and participate in 3D rendering contexts as follows:

* A 3D rendering context is established by a a transformable element whose computed value for ‘transform-style’ is ‘preserve-3d’, and which itself is not part of a 3D rendering context. Note that such an element is always a containing block. An element that establishes a 3D rendering context also participates in that context.
* An element whose computed value for ‘transform-style’ is ‘preserve-3d’, and which itself participates in a 3D rendering context, extends that 3D rendering context rather than establishing a new one.
* An element participates in a 3D rendering context if its containing block establishes or extends a 3D rendering context.
"""
http://dev.w3.org/csswg/css3-transforms/#transform-3d-rendering

One problem here is that a containing block is not always an element.  For instance, in the markup

  <div><img src=foo><div>More text</div></div>

the img's containing block is an anonymous block box.  What does it mean for that box to establish or extend a 3D rendering context?  If the outer div has transform-style: preserve-3d, is the img part of a 3D rendering context or not?  More concretely, consider the following:

  data:text/html,<!doctype html>
  <div style="transform-style:preserve-3d;transform:rotatex(90deg)">
    <img src=image style="transform:rotatex(90deg)">
    <div>Some text</div>
  </div>

In Chrome 19 dev (Linux), WebKit nightly r109732 (Windows 8), and Firefox 13.0a1, the image appears, so it is part of the rendering context.  How are we supposed to spec this?


Another problem is the statement "Note that such an element is always a containing block."  As Boris points out in <https://bugzilla.mozilla.org/show_bug.cgi?id=733849#c4>, this isn't always true.  According to <http://www.w3.org/TR/CSS2/visuren.html#block-boxes>, a table box isn't a block container box, for instance.  Also, per bug 16326, we want things like table rows to be transformable, but they aren't block container boxes.  Thus they can't be containing blocks.


I suggested the following wording, which doesn't use the concept of containing blocks at all:

"""
Elements establish and participate in 3D rendering contexts as follows:

* If a transformable element's computed value for 'transform-style' is 'preserve-3d', and either its parent is not transformable or its parent's 'transform-style' computes to 'flat', it establishes a new 3D rendering context and participates in that context.

* If a transformable element's parent is transformable, and its parent's 'transform-style' computes to 'preserve-3d', it participates in the same 3D rendering context as its parent.

* If an element is not transformable, or its 'transform-style' and its parent's both compute to 'flat', or its 'transform-style' computes to 'flat' and its parent is not transformable, it does not participate in any 3D rendering context.
"""

However, this doesn't match how browsers behave.  See the test-case in <https://bugzilla.mozilla.org/show_bug.cgi?id=733849#c7>.


I'm not sure what to spec here.  Any ideas?  What do Gecko and WebKit actually do?
Comment 1 Simon Fraser 2012-03-12 20:05:24 UTC
WebKit's behavior here is buggy and a side-effect of the implementation.

When I wrote that part of the spec I wasn't sure if 'containing block' was the right term to use. I'm not sure that 'parent' is either, since for an absolutely positioned element, what matters its its containing block, not its parent.
Comment 2 Aryeh Gregor 2012-03-12 20:23:42 UTC
Yes, my proposed definition changes behavior for absolute positioning.  Is this a problem, or is it a marginal enough corner case that we can just ask browsers to change?  If that's the only problem with my proposed definition, it could always be changed to have an extra special case for absolute positioning.
Comment 3 Boris Zbarsky 2012-03-12 22:06:11 UTC
The "containing block" is a rectangle; it's not an element or a box.  So talking about its styles is just nonsensical.

We really do need to decide what behavior we want in the anonymous block case and in the abspos/fixedpos cases before we can figure out how to define this....
Comment 4 Aryeh Gregor 2012-03-15 18:41:13 UTC
I think what we want here is to define some new term and use that instead of "containing block".  Like call it "transform parent", and say that the transform parent of an element is the nearest transformable ancestor if the element's position is relative or static, and the nearest ancestor with non-static position if the element's position is absolute, and the nearest ancestor that either is the root element or has a transform applied if the element's position is fixed.  All uses of "containing block" in the spec should be reviewed to see if they deserve to be changed.
Comment 5 Simon Fraser 2012-03-15 18:45:42 UTC
That sounds reasonable. I'd have to think about how to define "transform parent".
Comment 6 Boris Zbarsky 2012-03-15 18:52:41 UTC
The exact definition in comment 4 is not quite right (e.g. for position:absolute or position:fixed ancestors with transform not "none" should probably be treated as transform parents, and similar for svg:foreignObject), but the general approach makes sense, I think.  I wonder how to best keep the definition from getting out of sync with the containing block stuff for positioned elements...
Comment 7 Simon Fraser 2012-10-18 22:24:34 UTC
Need to discuss at the F2F meeting.
Comment 8 Edward O'Connor 2012-10-18 22:48:38 UTC
*** Bug 18500 has been marked as a duplicate of this bug. ***
Comment 9 Simon Fraser 2012-10-19 17:14:51 UTC
*** Bug 19637 has been marked as a duplicate of this bug. ***
Comment 10 Binyamin 2014-08-11 17:36:47 UTC
Chrome related bug "rendering bug : position:fixed AND -webkit-transform" https://code.google.com/p/chromium/issues/detail?id=20574
Comment 11 Binyamin 2015-05-04 07:27:17 UTC
Also "will-change" breaks because of this issue, see http://cssmojo.com/the-dark-side-of-the-will-change-property/
Comment 12 Mike 2016-05-20 15:27:07 UTC
+1 for updating the spec on this issue.
Comment 13 Sergey 2016-07-08 12:01:19 UTC
+1 Still need spec update as browser won't fix this issue without having spec changed.
Comment 14 oria 2016-09-15 15:17:02 UTC
This issue was raised and discussed in 2012 and forgotten, but the position property is still non-functional inside transformed elements - to this day.

position:fixed/absolute behavior needs to be consistent. Fixpos is relative to view-port in any other case; abspos is relative to first non-static parent in any other case; there's no reason for this special exception of transformed elements.

To be honest, from the user perspective this like a margin behaves as padding on elements with round-borders... it simply makes no sense.

There's not one case where a position:fixed element needs to be relative to transformed element and not view-port. If there was such a case, the right way was to set it as position:absolute and set the parent to position:relative.
Comment 15 allah.taskbar 2016-09-16 14:22:43 UTC
+1 for updating the spec
Comment 16 vvavrychuk 2016-09-20 12:26:46 UTC
As far as I understand this issue applies to `background-attachment: fixed` too. It also becomes fixed to the parent transformed block and not to the viewport.
Comment 17 FremyCompany 2016-10-21 18:07:12 UTC
Just wanted to point out that Chrome shows that implementing this fix (position:fixed not disabled by transforms) is possible and even trivial by accidentally have this happen as a result of a bug:

https://jsfiddle.net/6phnrad7/1/

Except if we have strong reasons not to revert this change, I would recommend we revert it, and allow position:fixed to work inside transformed elements.
Comment 18 Boris Zbarsky 2016-10-21 19:09:54 UTC
> is possible and even trivial

With what exact resulting behavior?  What's the z-ordering of the result, for example?
Comment 19 FremyCompany 2016-10-21 20:08:21 UTC
Fair point, I think I just got too excited :-)

I would need to investigate more, but the returning theme I heard is that it would be very difficult to maintain position:fixed and apply the transform nonetheless, and from what I can see this happens by accident in a browser which makes me believe this argument doesn't hold strongly. 

I'll open an issue on the csswg github when I will have had time to investigate this.
Comment 20 Simon Fraser 2016-10-21 20:12:02 UTC
Clipping is also hard to get right.
Comment 21 Boris Zbarsky 2016-10-21 20:32:25 UTC
> I heard is that it would be very difficult to maintain position:fixed and apply the transform nonetheless

Which it is.  If you try actually scrolling your testcase at https://jsfiddle.net/6phnrad7/1/ in Chrome you will note that it's not really fixed exactly, because scrolling happens on the compositor and just brings the entire transformed thing along, including the "fixed" piece.  Then a relayout happens and it gets repositioned to its original viewport-relative place again.

This is probably not the scrolling behavior people expect out of "position: fixed".
Comment 22 Pascal Blessing 2016-11-11 14:33:48 UTC
The problem with transform and position: fixed was an issue for me for quite a long time. Luckily I was able to solve it with some kind of JS polyfill.
However, looking up the position: sticky specs I've just stumbled across the containing block definition of CSS 3 (https://drafts.csswg.org/css-position/#def-cb) which says:

"""
If the element has position: fixed, the containing block is established by the viewport in the case of continuous media or the page area in the case of paged media.
"""

which would conflict with the previous definition and implementation of Chrome (and finally resolve https://bugs.chromium.org/p/chromium/issues/detail?id=20574)
Comment 23 Simon Fraser 2017-01-13 17:57:06 UTC
Moved to https://github.com/w3c/csswg-drafts/issues/913