Problem with z-index and/or backface-visibility when applying transform: rotateY(180deg);

RESOLVED FIXED in Firefox 52

Status

()

defect
P3
normal
RESOLVED FIXED
3 years ago
3 years ago

People

(Reporter: john.vieth, Assigned: sinker)

Tracking

({regression, testcase})

46 Branch
mozilla52
Points:
---
Dependency tree / graph
Bug Flags:
in-testsuite ?

Firefox Tracking Flags

(firefox49 wontfix, firefox50 wontfix, firefox51 wontfix, firefox52 fixed)

Details

Attachments

(3 attachments, 2 obsolete attachments)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36

Steps to reproduce:

Applying...

transform: rotateY(180deg);

...to a div by toggling a class on that div using JavaScript does not produce the expected result. The z-index stack of the div's children should be flipped with the div is rotated. Also, backface-visibility of hidden should result in seeing one child div before flipping and the "back" child div after flipping. Instead, I see the back of the front div, and I can't see the back div. This works correctly in Chrome, Safari, and Edge, but not Firefox. You can see an example at http://test.prime.umark.wisc.edu/
Test that website in Chrome, and you will see the correct behavior when clicking one of the diamond shapes. But in Firefox, the effect does not work.


Actual results:

When the div is rotated, the back child should be revealed, but it's not. Instead, it's hidden behind the front div.


Expected results:

The z-index stack of the div's children should be flipped with the div is rotated. Also, backface-visibility of hidden should result in seeing one child div before flipping and the "back" child div after flipping.
Could you provide a reduced testcase, please.
Flags: needinfo?(john.vieth)
Keywords: testcase-wanted
Here is a link to a reduced test case:
http://test.prime.umark.wisc.edu/test.php

And here is the HTML of the reduced test case, complete with inline CSS and inline JavaScript...

<!doctype html>
<html lang="en">
  <head>
    <title>Prime | University of Wisconsin–Madison</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="http://www.wisc.edu/fonts/uw160/fonts.0.0.1.css" type="text/css">
    <link rel="stylesheet" href="/css/test.css" type="text/css" media="screen">
    <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
    <script type="text/javascript">
      $( document ).ready(function() {
        // Flip diamonds
        $('.uw-flipper').click(function() {
          $(this).toggleClass('uw-flipped');
        });
      });
    </script>
    <style>

      html, body {
        margin: 0;
        padding: 0;
        background-color: #000;
        font-family: Verlag, Helvetica Neue, Helvetica, Arial, sans-serif;
        font-size: 16px;
        letter-spacing: 0.15rem;
        color: $white;
      }
      body {
        background-image: url(/images/background-shapes.png);
        background-repeat: repeat-y;
        background-size: 100% auto;
        background-attachment: fixed;
      }
      #uw-why {
        display: block;
        position: relative;
        color: $white;
        width: 1024px;
        margin: 5rem auto;
        padding: 0;
      }
      #uw-why ul {
        display: block;
        position: relative;
        width: 100%;
        height: 870px;
        list-style-type: none;
        margin: 0;
        padding: 0;
      }
      #uw-why li {
        display: block;
        position: absolute;
        box-sizing: border-box;
        width: 670px;
        height: 335px;
        clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
        -webkit-clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
        clip-path: url('data:image/svg+xml;utf8,%3Csvg xmlns="http://www.w3.org/2000/svg"%3E%3Cdefs%3E%3CclipPath id="p" clipPathUnits="objectBoundingBox"%3E%3Cpolygon points="0.5 0, 1 0.5, 0.5 1, 0 0.5" /%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E#p');
        margin: 0;
        padding: 0;
        -webkit-perspective: 1000px;
        -moz-perspective: 1000px;
        -ms-perspective: 1000px;
        perspective: 1000px;
      }
      #uw-why li#uw-undergraduate-research {
        top: 0;
        left: 354px;
      }
      .uw-flipper {
        position: relative;
        width: inherit;
        height: inherit;
        cursor: pointer;
        transition: 0.6s;
        transform-style: preserve-3d;
      }
      .uw-front img {
        opacity: 0.3;
      }
      .uw-back {
        background-color: #202020;
      }
      .uw-front, .uw-back {
        display: block;
        position: absolute;
        width: inherit;
        height: inherit;
        top: 0;
        left: 0;
        color: $white;
        font-size: 1.4rem;
        font-weight: normal;
        text-transform: uppercase;
        text-align: center;
        clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
        -webkit-clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
        clip-path: url('data:image/svg+xml;utf8,%3Csvg xmlns="http://www.w3.org/2000/svg"%3E%3Cdefs%3E%3CclipPath id="p" clipPathUnits="objectBoundingBox"%3E%3Cpolygon points="0.5 0, 1 0.5, 0.5 1, 0 0.5" /%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E#p');
        background-color: #000;
        margin: 0;
        padding: 0;
        backface-visibility: hidden;
        -webkit-backface-visibility: hidden;
        -moz-backface-visibility: hidden;
      }
      .uw-front {
        z-index: 2;
        transform: rotateY(0deg);
        -webkit-transform: rotateY(0deg);
      }
      .uw-front img {
        position: absolute;
        top: 0;
        left: 0;
        width: 670px;
        height: 335px;
        opacity: 0.5;
      }
      .uw-front h3 {
        text-align: center;
        width: 400px;
        margin: 0 auto;
        font-size: 1.6rem;
        position: relative;
        top: 50%;
        color: #fff;
        transform: translateY(-50%);
        text-shadow: 0px 0px 10px rgba(0, 0, 0, 0.8), 0px 0px 10px rgba(0, 0, 0, 0.8);
      }
      .uw-back {
        z-index: 1;
        background-color: #282727;
        transform: rotateY(180deg);
      }
      .uw-back h3 {
        text-align: center;
        width: 450px;
        margin: 110px auto 0.3rem auto;
        font-size: 1.2rem;
        color: #fff;
      }
      .uw-back p {
        text-align: center;
        text-transform: none;
        width: 450px;
        margin: 0 auto;
        font-size: 1rem;
        line-height: 1.5;
        color: #fff;
      }
      .uw-flipper.uw-flipped {
        transform: rotateY(180deg);
        -webkit-transform: rotateY(180deg);
        -moz-transform: rotateY(180deg);
        -ms-transform: rotateY(180deg);
      }
      </style>
  </head>
  <body>
    <section id="uw-why">
      <ul>
        <li id="uw-undergraduate-research" class="uw-flipper-container">
          <div class="uw-flipper">
            <div class="uw-front">
              <img aria-hidden="true" src="/images/diamond-engineering.jpg" />
              <h3>Undergraduate Research</h3>
            </div>
            <div class="uw-back">
              <h3>Undergraduate Research</h3>
              <p>Undergraduate students at UW–Madison are fortunate to have the opportunity to work with some of the world's leading researchers to push the frontiers of knowledge.</p>
            </div>
          </div>
        </li>
      </ul>
    </section>
  </body>
</html>
Again, the "bug" is that, in Firefox, when you click the diamond shape, it rotates as it should, but you cannot see the "back" side of the object, which should show the div with class "uw-back." Instead, you see through to the back side of the "uw-front" div.

However, this works just fine in Chrome and Safari.

I suspect there might be a bad interaction between the animation/transform/rotation and the clip-path on the animated div which uses an svg mask.
Posted image screenshot33-52.png
Thanks. In fact, with old version like FF33, I see the backside correctly.
Flags: needinfo?(john.vieth)
The behavior changed after bug 1097464.
https://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=11dc79e232110ba6de5179e46dfbda77b52a88c3&tochange=4313752f69956ae248bd4e7ff3913c8dd4252698

:sinker, can you check after your return from PTO, please.
Blocks: 1097464
Component: CSS Parsing and Computation → Layout
Flags: needinfo?(tlee)
Posted file 1306107.html
Group: core-security
Group: core-security
I do not understand these negative comments. I checked a box because I thought the purpose of the checkbox is to hide an issue from the public for security reasons. In my case, the security reason is that I prefer not to have the public know about our microsite which has not launched yet. I was not trying to trick anyone into giving my issue faster attention, or anything like that. I regret posting this issue, and I regret the negative experience. I believe I made a mistake in getting involved with this community. I didn't realize there is this negative culture. I really think there is a bug that Mozilla should want to know about, but I don't want to upset anyone. Is there any way I can just delete this issue so that it cannot be found in the future?
I am looking on this bug.
Flags: needinfo?(tlee)
Version: unspecified → 43 Branch
This looks like caused by svg mask.  It causes to force painting with BasicLayerManager and disabling OMTA.
Flags: needinfo?(cku)
Version: 43 Branch → unspecified
It works correctly if clip-path of div |uw-undergraduate-research| is removed.
$ ./mach mozregression --good 2016-09-27 --bad 2016-10-17 --arg="https://bug1306107.bmoattachments.org/attachment.cgi?id=8796318"


INFO: Narrowed inbound regression window from [9dfac0d1, e1b0aaa2] (4 revisions) to [689f6fee, e1b0aaa2] (2 revisions) (~1 steps left)
INFO: Oh noes, no (more) inbound revisions :(
INFO: Last good revision: 689f6fee184628d3dd968e3b6518cc811cfb3e43
INFO: First bad revision: e1b0aaa20f1098b08537b2e13f9e97ee9759d4c7
INFO: Pushlog:
https://hg.mozilla.org/integration/mozilla-inbound/pushloghtml?fromchange=689f6fee184628d3dd968e3b6518cc811cfb3e43&tochange=e1b0aaa20f1098b08537b2e13f9e97ee9759d4c7
More precisely, this check-in is the first bad revision
https://hg.mozilla.org/integration/mozilla-inbound/rev/380eebfd9d89

Hi Kate, please have a look on this issue
Flags: needinfo?(cku) → needinfo?(kmckinley)
Oh, but the problem I found is not really the same with the description in comment 1.
This check-in (https://hg.mozilla.org/integration/mozilla-inbound/rev/380eebfd9d89) makes the loading speed became really slow. So that I can't even see the diamond at all
I can reproduce this in release, so I don't think this problem is my patch, but the slowness looks related to 1308612. The diamond loads eventually for me.
Flags: needinfo?(kmckinley)
The symptom described in comment 1 is a regression of revision 4313752f69956ae

$ ./mach mozregression --good 2015-01-01 --bad 2016-09-27 --arg="https://bug1306107.bmoattachments.org/attachment.cgi?id=8796318"

 6:42.38 INFO: Last good revision: 11dc79e232110ba6de5179e46dfbda77b52a88c3 (2015-09-18)
 6:42.38 INFO: First bad revision: 4313752f69956ae248bd4e7ff3913c8dd4252698 (2015-09-19)
 6:42.38 INFO: Pushlog:
https://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=11dc79e232110ba6de5179e46dfbda77b52a88c3&tochange=4313752f69956ae248bd4e7ff3913c8dd4252698
I have found two problem in the case here.

 1. |ComputeEffectiveTransform()| of BasicContainerLayer project transforms to 2D for leaf layers.  It makes backface hidden broken.
 2. |Matrix4x4::IsBackfaceVisible()| is broken with perspective.

Problem 1 is easy to fix.

Problem 2 is a little complicated.  I don't understand why we need to multiple the result with determinant of the transform.  I think we even don't need such complicated formula to determine if the backface is visible.  It is enough to determines backface visible transforming the normal vector of the origin surface and checking if the the vector project away from user.  Is there anyone know why it is as it is now?
Flags: needinfo?(bzbarsky)
Status: UNCONFIRMED → NEW
Ever confirmed: true
did in comment 5 already.
> Is there anyone know why it is as it is now?

I don't think I've ever seen this code before, sorry.  That said, at first glance if the transform matrix is singular then the backface won't be visible, because nothing is visible, right?  I guess that would be covered by the vector becoming zero-length or so?
Flags: needinfo?(bzbarsky)
But in general, the blame for this code goes back to https://hg.mozilla.org/mozilla-central/rev/15aadd79c480 so you may want to ask mattwoodrow or derf for the reasoning.
needinfoing Matt based on comment 22.

(In reply to Thinker Li [:sinker] from comment #18)
> I have found two problem in the case here.
> 
>  1. |ComputeEffectiveTransform()| of BasicContainerLayer project transforms
> to 2D for leaf layers.  It makes backface hidden broken.
>  2. |Matrix4x4::IsBackfaceVisible()| is broken with perspective.
> 
> Problem 1 is easy to fix.
> 
> Problem 2 is a little complicated.  I don't understand why we need to
> multiple the result with determinant of the transform.  I think we even
> don't need such complicated formula to determine if the backface is visible.
> It is enough to determines backface visible transforming the normal vector
> of the origin surface and checking if the the vector project away from user.
> Is there anyone know why it is as it is now?
Flags: needinfo?(matt.woodrow)
(In reply to Thinker Li [:sinker] from comment #18)
> I have found two problem in the case here.
> 
>  1. |ComputeEffectiveTransform()| of BasicContainerLayer project transforms
> to 2D for leaf layers.  It makes backface hidden broken.
>  2. |Matrix4x4::IsBackfaceVisible()| is broken with perspective.
> 
> Problem 1 is easy to fix.
> 
> Problem 2 is a little complicated.  I don't understand why we need to
> multiple the result with determinant of the transform.  I think we even
> don't need such complicated formula to determine if the backface is visible.
> It is enough to determines backface visible transforming the normal vector
> of the origin surface and checking if the the vector project away from user.
> Is there anyone know why it is as it is now?

I'm honestly not entirely sure. As Boris said, this was changed in bug 693520.

There's a testcase there that was broken when using the normal vector, and Tim suggested this as an alternative method that would be more reliable.
Flags: needinfo?(matt.woodrow)
Attachment #8802034 - Attachment is obsolete: true
Comment on attachment 8802807 [details] [diff] [review]
Stop calling ProjectTo2D() for leaf basic layers, v2

This patch move all |project2d()| to the head of |ComputeEffectiveTransform()|, and preserve 3d components of |ideaTransform| for layers with |CONTENT_BACKFACE_HIDDEN|.  It make sure that |Layer::IsBackfaceVisible()| works correctly.
Attachment #8802807 - Flags: review?(matt.woodrow)
Attachment #8802807 - Flags: review?(matt.woodrow) → review+
Thinker, what are the next steps here?
Assignee: nobody → tlee
Flags: needinfo?(tlee)
r=mattwoodrow
Attachment #8802807 - Attachment is obsolete: true
Attachment #8808093 - Flags: review+
Keywords: checkin-needed
Should this have an automated test as well?
Flags: needinfo?(tlee)
Flags: in-testsuite?
Version: unspecified → 46 Branch
Pushed by ryanvm@gmail.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/a0ff94cf57e7
Stop calling ProjectTo2D() for leaf basic layers. r=mattwoodrow
Keywords: checkin-needed
https://hg.mozilla.org/mozilla-central/rev/a0ff94cf57e7
Status: NEW → RESOLVED
Closed: 3 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla52
Is it ok to let this ride with 52, or is it something you think worth uplifting to beta 51?
We're quickly running out of time to get this into 51 if the patch is indeed suitable for uplift.
Flags: needinfo?(kchen)
Given that we've shipped it in multiple releases, it seems best at this point to just let it ride the trains.
clearing needinfo based on comment 35.
Flags: needinfo?(kchen)
Flags: needinfo?(tlee)
You need to log in before you can comment on or make changes to this bug.