Bug 15871 - 'opacity' should not cause transform-style: preserve-3d to be ignored (resolved)
Summary: 'opacity' should not cause transform-style: preserve-3d to be ignored (resolved)
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:
Depends on:
Reported: 2012-02-03 18:01 UTC by Aryeh Gregor
Modified: 2012-10-18 20:59 UTC (History)
6 users (show)

See Also:

Intended rendering (with opacity 0.5) (6.29 KB, image/png)
2012-03-05 20:02 UTC, Simon Fraser

Note You need to log in before you can comment on or make changes to this bug.
Description Aryeh Gregor 2012-02-03 18:01:59 UTC
The following CSS property values require the user agent to create a flattened representation of the descendant elements before they can be applied, and therefore override the behavior of transform-style: preserve-3d:

. . .
opacity: any value other than 1.


data:text/html,<!doctype html>
<div style="transform:rotatex(90deg);opacity:0.5;
<div style="transform:rotatex(90deg);height:100px;

In both Firefox 13.0a1 and Chrome 18 dev, this shows a translucent lime square.  If you change "preserve-3d" to "flat", the square disappears.  This indicates that in implementations, opacity does not disable preserve-3d.  The spec should remove it.  (IE10 Developer Preview doesn't display the square in either case, so I suspect it doesn't implement preserve-3d properly at all.)
Comment 2 Aryeh Gregor 2012-02-06 16:15:04 UTC
Okay, thanks for the context.  Is it really better to make 'transform-style' nonfunctional in this case, though?  We could also call WebKit's behavior a bug, or make it required.
Comment 3 Aryeh Gregor 2012-03-01 21:27:24 UTC
I suggest removing the exception for opacity.  Any objections?
Comment 4 Simon Fraser 2012-03-01 22:13:50 UTC
I'm not sure what you mean by "removing the exception". If we don't say that opacity forces flattening, then we break "group opacity" which David brought up in his email, which I don't think we should (even though it doesn't match implementations).

It's pretty useful for authors to be able to fade out a whole subtree of elements without flattening, but if we enforce group opacity via flattening here, authors will have to change opacity on all the leaf elements.

Maybe this needs group discussion.
Comment 5 Aryeh Gregor 2012-03-05 16:34:29 UTC
I agree that opacity should apply to the whole group at once, not to each element individually.  Does that necessarily have to imply transform-style: flat?  If I have something like

  <div id=d1>
    <div id=d2a>
      <div id=d3a></div>
      <div id=d3b></div>
    <div id=d2b></div>
  div { transform-style: preserve-3d }
  #d2a { opacity: 0.5 }
  /* ... */

why can't the children of #d2a have group opacity while still being in the same 3D rendering context as #d2b?  Is that just too hard given how this stuff is actually implemented?  I.e., you can't tell the graphics card that #d2b should be visible through #d3a but #d3b shouldn't be?

I'm not sure I'm being clear here at all.  But without knowing anything about the implementations, I'd expect opacity and transform-style to be entirely orthogonal.  The dependency seems surprising to me.
Comment 6 Simon Fraser 2012-03-05 17:43:04 UTC
Yes, transform-style has to imply flat if you want group opacity to work. You have to render the children opaquely into a bitmap, and then apply opacity to the bitmap.
Comment 7 Aryeh Gregor 2012-03-05 19:09:18 UTC
Hmm, okay.  Here's a new test-case:

data:text/html,<!doctype html>
<div style="transform-style: preserve-3d">
  <div style="transform-style: preserve-3d; opacity: 0.8">
    <div style="height:100px; width:100px; background:lime;
    transform: translatez(10px)"></div>
    <div style="height:100px; width:100px; background:red;
    transform: translate3d(0, -50px, -10px)"></div>
  <div style="height:100px; width:100px; background:yellow;
  transform: translate3d(50px, -175px, -20px)"></div>

Firefox 13.0a1 respects opacity here -- the red and green boxes are all translucent relative to the background (removing the opacity property changes the color).  The opacity is group opacity -- the green box covers the red box opaquely.  And the translucent div does respect transform-style: preserve-3d -- the green box is on top of the red one.  But the red and green boxes don't participate in 3D rendering with the yellow box -- the yellow box is drawn on top.

Chrome 19 dev respects transform-style: preserve-3d, but just applies the opacity to the leaf nodes.  Thus the green box is on top of the red box, but you can see the red box through it.  Both boxes are on top of the yellow box, but you can see it through them.

As I've mentioned, I don't have access to a copy of Safari on Mac right now.  Safari 5.1.2 on Windows 8 Developer Preview behaves the same as Chrome.  The spec implies it should display with group opacity, and with the red/green boxes on top of the yellow, but with the red box on top of the green one.  Is that how Safari on Mac behaves?  If so, that's three different behaviors in three different implementations.

What I think we really want here is a fourth behavior: what Firefox does, except with the yellow box below the green/red boxes, partially visible through them.  But you're saying that's not practical in general.  Firefox's behavior is closest -- at least it has the green box opaque and on top of the red box.

I think it's not clear what we want to require here.  I'll post to the list.
Comment 8 Simon Fraser 2012-03-05 20:01:00 UTC
> with the yellow box below the green/red boxes, partially visible through them

I agree that's the correct rendering. It should be exactly equivalent to having transform-style: flat on the element with opacity.
Comment 9 Simon Fraser 2012-03-05 20:02:35 UTC
Created attachment 1087 [details]
Intended rendering (with opacity 0.5)
Comment 10 Aryeh Gregor 2012-03-05 20:17:41 UTC
Discussion on list: http://lists.w3.org/Archives/Public/public-fx/2012JanMar/0148.html

(In reply to comment #8)
> > with the yellow box below the green/red boxes, partially visible through them
> I agree that's the correct rendering. It should be exactly equivalent to having
> transform-style: flat on the element with opacity.

See my reply there.  I agree that your attachment is how it should render, but it doesn't seem like it's the same as transform-style: flat.
Comment 11 Dirk Schulze 2012-05-09 14:48:00 UTC
FX TF agreed to flatten and that the spec text should be more clear on other cases like for z-index.
Comment 12 Simon Fraser 2012-06-06 15:22:21 UTC
I don't understand "on other cases like for z-index".
Comment 13 Simon Fraser 2012-07-12 18:29:56 UTC
Can this be closed?
Comment 14 Simon Fraser 2012-10-18 20:59:20 UTC
The spec already says that non-1 opacity flattens. No more work is required here.