Searching for a solution for iOS safari ONLY
When using -webkit-overflow-scrolling: touch
it breaks the 3d perspective on iOS.
See the demo on CodePen.
HTML
<div class="pers">
<div class="scroll">
<div class="el">
</div>
</div>
</div>
CSS
.pers {perspective:300px;}
.scroll {overflow-y:scroll;-webkit-overflow-scrolling:touch; height:100vh;}
.el {-webkit-transform:rotateX(80deg);transform:rotateX(80deg);}
Is there a workaround?
Update, May 29
Doh! I so stupid. The below, while true...ish doesn't address the question well enough.
If you want that configuration of the rotation to stay the same as you have illustrated, add a div between .scroll
and .el
, and style it such:
{perspective:300px;}
Thus, it would seem that you want the .pers
div switched with .scroll
or add another after .scroll
with the same perspective.
Also, try moving the perspective: 300px;
to .scroll
. The angle appears to change as one scroll up or down.
Original Answer
The answer is not really. One cannot contain a 3D transform inside a container with clipping which is being attempted here.
The problem is overflow-y:scroll
breaks the transform-style property as per spec. The overflow-y affects the nested element. If your problem persists, you may also have to use the -WebKit-transform-style: preserve-3d
declaration on .scroll
, though I think iOS already has a stacking context established in this case (Firefox requires this, Webkit seems not to).
One solution is to remove your overflow:hidden
from body
and overflow-y:scroll
from .scroll
, but I suspect you are going to want to have that as a smaller part of the page/screen and move image blocks inside it.
If this is the case, you will need fake this with transforms and some clever hackery and should use opacity be part of this endeavor, please note that this too (as in spec above, right below the transform-style) causes the flattening effect when not applied to the final node. Let's say you had opacity other than 1 on .el
, you are fine here as .el
is the final node, but if opacity was applied to .scroll
, the same flattening of .el
occurs as with the overflow.
Have yet to test on iOS as I lack access to the device.
Note: setting an overflow value other than visible for the body does not cause this issue on most desktop browsers that support 3D transforms. I do not know about iOS/mobile.
The shared snippet does not work on Mozilla Firefox as well. Below is the solution tested for iOS Safari/Chrome (iPhone-6S), Windows Mozilla/Chrome:
no need to use -webkit-overflow-scrolling
. There could be a possible bug for this feature as it is under development [Reference Link]. Removing this property generates the desired behavior. It might not be the exact solution, but it can act as a workaround.
.scroll {perspective:300px;overflow-y:scroll;height:100vh;}
.el {-webkit-transform:rotateX(80deg);transform:rotateX(80deg);}
Codepen: http://codepen.io/anon/pen/LxZZdX
This snippet from HERE might do it. They seem to have had this issue as well
.outer {`enter code here`
overflow: scroll;
-webkit-overflow-scrolling: touch;
/* More properties for a fixed height ... */
}
.inner {
height: calc(100% + 1px);
}
Please check this demo: http://codepen.io/tushar-chauhan/pen/yNgzem
You can try tweaking the values to get your desired results. This works on both mobile & desktop Safari. I am posting the HTML & CSS here too:
CSS & HTML below:
body{
width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
}
.pers{
-webkit-transform-style: preserve-3d;
-webkit-perspective: 300px;
height: 120vh;
margin: 0 auto; overflow-y: auto;
}
.scroll {
height: inherit;
-webkit-overflow-scrolling:touch;
}
.el {
width: 10em; height: 10em; background: url(http://placehold.it/200x200);background-size:cover;
margin: 80vh auto;
-webkit-transform-origin: 50% 35%;
-webkit-transform: rotateX(80deg);
transform: rotateX(80deg);
}
<div class="pers">
<div class="scroll">
<div class="el">
</div>
</div>
</div>