preserve-3d isn't handled right on tables
Categories
(Core :: CSS Parsing and Computation, defect)
Tracking
()
People
(Reporter: ayg, Unassigned)
References
(Blocks 2 open bugs)
Details
(Keywords: parity-chrome, parity-safari)
Attachments
(3 files)
Context: https://www.w3.org/Bugs/Public/show_bug.cgi?id=15943 Test-cases: data:text/html,<!doctype html> <div style="-moz-transform: rotatex(90deg); -moz-transform-style: preserve-3d"> <table style="-moz-transform-style: preserve-3d"> <tbody style="-moz-transform-style: preserve-3d"> <tr style="-moz-transform-style: preserve-3d"> <td style="-moz-transform-style: preserve-3d"> <div style="-moz-transform: rotatex(90deg)">Some text</div> </table> </div> data:text/html,<!doctype html> <div style="-moz-transform: rotatex(90deg); -moz-transform-style: preserve-3d"> <div style="display: table; -moz-transform-style: preserve-3d"> <div style="display: table-row; -moz-transform-style: preserve-3d"> <div style="display: table-cell; -moz-transform-style: preserve-3d"> <div style="-moz-transform: rotatex(90deg)">Some text</div> </div> </div> </div> </div> data:text/html,<!doctype html> <div style="-moz-transform: rotatex(90deg); -moz-transform-style: preserve-3d"> <div style="display: table-cell; -moz-transform-style: preserve-3d"> <div style="-moz-transform: rotatex(90deg)">Some text</div> </div> </div> In all three cases, Gecko displays nothing. This is presumably because there are anonymous frames inserted at various points that have the default -moz-transform-style of "flat", and should instead have -moz-transform-style: inherit. I should be able to write a patch for this if someone can give me some pointers. How do I distinguish anonymous table frames from regular ones, in ua.css or wherever would be appropriate?
![]() |
||
Comment 1•13 years ago
|
||
The only anonymous box in that first testcase is the ::-moz-cell-content, right? does adding a style for that to ua.css help? In general, should we be looking at the moz-transform-style on the style parent instead of on the frame tree parent? How does the spec define this? It matters for the third testcase, in which CSS2.1 actually requires anonymous boxes.
![]() |
||
Comment 2•13 years ago
|
||
Oh, and in general the anonymous table frames use the various anon box styles in ua.css: ::-moz-table, ::-moz-inline-table, ::-moz-table-row-group, ::-moz-table-row, ::-moz-table-cell. But before we start changing all of those, I'd really like to understand what behavior the spec actually calls for.
Reporter | ||
Comment 3•13 years ago
|
||
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 So it actually doesn't define anything for boxes that don't come from elements, read literally. Probably the third bullet point should be changed from "An element" to "A block" or "A box" or similar. Do you have wording suggestions? I do think the intent is that any boxes that don't correspond to elements should inherit the transform-style of the nearest element ancestor.
![]() |
||
Comment 4•13 years ago
|
||
> * A 3D rendering context is established by a a transformable element Table rows and row groups and cells don't seem to be transformable elements per sper, right? > Note that such an element is always a containing block. Which I believe table rows and row groups at least are not. The situation for cells is a bit vague. > * An element participates in a 3D rendering context if its containing block establishes > or extends a 3D rendering context. OK, so this says one should be looking at containing blocks... of course a containing block is a rectangle, not an element, so this part is somewhat nonsensical. > Do you have wording suggestions? That kind of depends on the desired behavior, no? I haven't looked at how 3d transforms work at enough length to comment on that... One thing: boxes don't have styles in CSS. Elements have styles. Does that help anything?
Reporter | ||
Comment 5•13 years ago
|
||
(In reply to Boris Zbarsky (:bz) from comment #4) > Table rows and row groups and cells don't seem to be transformable elements > per sper, right? It says block-level or atomic inline-level, so that's what the spec claims, yeah. That seems like a spec bug. Transformable CSS2.1 display types seem to be, ignoring table-column(-group): Spec: block, list-item, inline-block, table, inline-table; plus inline if replaced IE 10 Developer Preview: spec plus table-caption, table-cell, and all inline (everything except table-*-group and table-row) Gecko: spec plus table-* (everything except non-replaced inline) Chrome 19 dev: spec plus table-* (everything except non-replaced inline) Opera Next 12.00 alpha: spec plus table-caption and all inline It seems like the spec should be updated to match Gecko/WebKit. I filed a bug: https://www.w3.org/Bugs/Public/show_bug.cgi?id=16326 > Which I believe table rows and row groups at least are not. The situation > for cells is a bit vague. > > . . . > > OK, so this says one should be looking at containing blocks... of course a > containing block is a rectangle, not an element, so this part is somewhat > nonsensical. So maybe we want to change the definition of "transformable element" to include table-* (except table-column and table-column-group), and then change the steps I quoted above to say: """ 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. """ How does that sound?
![]() |
||
Comment 6•13 years ago
|
||
How do you want things to behave when absolutely positioned elemnets are involved? Given this markup: <div style="position: relative"> <p> <span style="position: absolute"> </span> </p> </div> and the <div> and <span> have "transform-style: preserve-3d" while the <p> has "transform-style: flat", does the <span> establish a new 3d rendering context? In your proposed wording, it does. I _think_ the intent of the current spec is that it not do so... maybe. Quite apart from that, by the way, it seems like the behavior, if I understand things at all correctly, would be saner if transform-style were 'preserve-3d' by default. But maybe that ship has sailed....
Reporter | ||
Comment 7•13 years ago
|
||
(In reply to Boris Zbarsky (:bz) from comment #6) > How do you want things to behave when absolutely positioned elemnets are > involved? Given this markup: > > <div style="position: relative"> > <p> > <span style="position: absolute"> > </span> > </p> > </div> > > and the <div> and <span> have "transform-style: preserve-3d" while the <p> > has "transform-style: flat", does the <span> establish a new 3d rendering > context? In your proposed wording, it does. I _think_ the intent of the > current spec is that it not do so... maybe. Yeah, the WebKit versions that I tested in seem to not establish a new 3D rendering context here. Same for Gecko. That seems overly complicated, though. I filed a spec bug: https://www.w3.org/Bugs/Public/show_bug.cgi?id=16328 > Quite apart from that, by the way, it seems like the behavior, if I > understand things at all correctly, would be saner if transform-style were > 'preserve-3d' by default. But maybe that ship has sailed.... I thought so too, but it turns out that wouldn't be a great idea. See <http://lists.w3.org/Archives/Public/www-style/2012Feb/0291.html>. It's a pretty long discussion. I don't like the status quo, but I can't think of anything clearly better -- particularly not better enough to change both WebKit and Gecko.
Unfortunately, I can confirm that bug related to 3d transforms and table rendering still exists (both Firefox 47 stable and Firefox 50 nightly on Windows 7 x64). I tried to emulate "fixed table header" pattern with the pure CSS parallax effect: http://codepen.io/SelenIT/pen/pbAzxb. It consistently applies the 3d transform to the `thead` element in Chromium-based browsers, but in Firefox there seems to be something between the container with `perspective` and the `thead` element with `transform` (maybe the table wrapper object or `table` element itself?) that breaks the perspective. Setting explicit `transform-style: preserve-3d` for the `table` doesn't help anything.
Comment 9•3 years ago
|
||
I think this bug is the root cause of these three WPT test failures:
https://wpt.fyi/results/css/css-transforms/transform-table-009.html
https://wpt.fyi/results/css/css-transforms/transform-table-010.html
https://wpt.fyi/results/css/css-transforms/transform-table-011.html
Live test links (which render blank in Firefox):
https://wpt.live/css/css-transforms/transform-table-009.html
https://wpt.live/css/css-transforms/transform-table-010.html
https://wpt.live/css/css-transforms/transform-table-011.html
Comment 10•3 years ago
|
||
For convenience, I'm attaching copies of the three testcases from comment 0, as actual attachments for easy clickability (and with the -moz prefixes removed).
Comment 11•3 years ago
|
||
Comment 12•3 years ago
|
||
Updated•2 years ago
|
Updated•1 year ago
|
Comment 13•10 months ago
•
|
||
After checking the frame tree by using the wpt, transform-table-009.html:
TableWrapper(table id=t)(1)@107a4ac00 parent=107a4ab38 (x=0, y=0, w=6360, h=6360) ink-overflow=(x=0, y=0, w=0, h=0) scr-overflow=(x=0, y=0, w=0, h=0) transformed combines-3d-transform-with-ancestors [content=10cc18220] [cs=10c3b56c8:-moz-table-wrapper]
Table(table id=t)(1)@107a4acb0 parent=107a4ac00 (x=0, y=0, w=6360, h=6360) [content=10cc18220] [cs=10c3b5038]
TableRowGroup(tbody)(1)@107a4ade0 parent=107a4acb0 (x=120, y=120, w=6120, h=6120) pre-transform-ink-overflow=(x=0, y=0, w=6120, h=6120) pre-transform-scr-overflow=(x=0, y=0, w=6120, h=6120) transformed extend-3d [content=10cc0d6f0] [cs=10c3b5128]
TableRow(tr)(1)@107a4ae90 parent=107a4ade0 (x=0, y=0, w=6120, h=6120) ink-overflow=(x=0, y=0, w=0, h=0) scr-overflow=(x=0, y=0, w=0, h=0) transformed extend-3d combines-3d-transform-with-ancestors [content=10cc0d780] [cs=10c3b5218]
TableCell(td)(1)@107a4af58 parent=107a4ae90 (x=0, y=0, w=6120, h=6120) ink-overflow=(x=0, y=0, w=0, h=0) scr-overflow=(x=0, y=0, w=0, h=0) transformed extend-3d combines-3d-transform-with-ancestors [content=10cc0d810] [cs=10c3b5308]
Block(td)(1)@107a4b020 parent=107a4af58 (x=60, y=60, w=6000, h=6000) [content=10cc0d810] [cs=10c3b5a88:-moz-cell-content] < line@107a4b1b0 count=1 state=block,clean,prevmarginclean,not-impacted,not-wrapped,no-break,clear-before:none,clear-after:none(x=0, y=0, w=6000, h=6000) ink-overflow=(x=0, y=0, w=0, h=0) scr-overflow=(x=0, y=0, w=0, h=0)
Block(div)(0)@107a4b0e8 parent=107a4b020 (x=0, y=0, w=6000, h=6000) ink-overflow=(x=0, y=0, w=0, h=0) scr-overflow=(x=0, y=0, w=0, h=0) transformed combines-3d-transform-with-ancestors [content=10cc0d8a0] [cs=10c3b53f8]
It seems like we have an extra Block(td)
frame between TableCell(td)
and Block(div)
, but it doesn't have transformed extend-3d combines-3d-transform-with-ancestors
. This means that its nsIFrame::Extend3DContext()
is false, and I suspect it may be the root cause which breaks the chain of preserved-3d in this test.
Note: same for Table
frame. Need to figure out what happen there for preserve-3d
Comment 14•10 months ago
|
||
We might want transform-style: inherit
on the corresponding table parts in ua.css. (That seems to be what the end of comment 0 and comment 1 are suggesting).
It looks like we used to have that for the -moz-table-wrapper
box, but that got reverted (commented out) in bug 1560704. But per bug 1560704 comment 10, it looks like we weren't sure that we really wanted to keep that fix, and the root cause there might really have been somewhere else.
Comment 15•10 months ago
•
|
||
Yes, adding transform-style: inherit
into -moz-table-wrapper
makes everything disappear. And got an assertion if I add transform-style: inherit
into -moz-cell-content
.
One thing to note: WebKit may also have something wrong in the similar cases. It doesn't pass the wpt, and have some strange behaviors if we use rotateX(90deg)
in the outer div. (Not sure what happens. It looks like Gecko has the similar behavior, so I have to tweak the test to make sure the combined rotateX is less than 90deg.)
Besides, in the frame tree, I notice TableRowGroup(tbody)
doesn't have combines-3d-transform-with-ancestors
. This may be a hint that it doesn't combine its 3d context with its ancestor. (So I tried to move the outer rotateX()
from outer div
into tbody
. Well, the result becomes correct, if the combined rotation is less than 90deg.) Need to dig deeper anyway.
Comment 17•10 months ago
•
|
||
So looks like preserve-3d
on <table>
or <div style="display: table;"></div>
doesn't take effect.
mTransformStyle
of nsTableWrapperFrame
is always flat
even if we set transform-style: preserve-3d
to table element.
e.g. we can simplify these failed test cases to this one:
<style>
#outer {
transform-style: preserve-3d;
transform: rotateY(30deg);
display: table;
}
#target {
width: 100px;
height: 100px;
background: green;
transform: rotateX(30deg);
}
</style>
<div id=outer>
<div id=target></div>
</div>
And Gecko doesn't render target
and outer
in the same 3D space.
I tried to hack nsIFrame::Extend3DContext()
to make it always return true for nsTableWrapperFrame
, but the elements inside the table disappears. :( (It's bug 1560704)
Note: The reason that we failed the test which uses display: table-cell
in css/css-transforms/transform-table-011.html may be another bug. That happens when using rotateX(90deg)
in the outer div. (If we change it to other values, e.g. 80deg or 100deg, our behavior is the same as Blink.)
Comment 18•10 months ago
|
||
The severity field for this bug is set to S4
. However, the following bug duplicate has higher severity:
- Bug 928322: S3
:emilio, could you consider increasing the severity of this bug to S3
?
For more information, please visit BugBot documentation.
Updated•10 months ago
|
Updated•4 months ago
|
Description
•