I've got this loader, rendering fine in everything, but Safari:
.pageLoader {
min-height: 100vh;
min-width: 100vw;
background-color: white;
z-index: 2;
position: fixed;
opacity: .9;
top: 0;
left: 0;
transition: opacity .6s linear;
display: flex;
justify-content: center;
align-items: center;
}
.pageSpinner {
border-radius: 5%;
width: 80px;
height: 80px;
background-color: #f50;
animation: a 1.5s infinite cubic-bezier(.4,0,.2,1);
}
@keyframes a {
0% { transform: perspective(300px) rotateX(0deg) rotateY(0deg); }
50% { transform: perspective(300px) rotateX(-180deg) rotateY(0deg); }
100% { transform: perspective(300px) rotateX(-180deg) rotateY(-180deg); }
}
<div class="pageLoader">
<div class="pageSpinner"></div>
</div>
Fully prefixed version here:
.pageLoader {
min-height: 100vh;
min-width: 100vw;
background-color: white;
z-index: 2;
position: fixed;
opacity: .9;
top: 0;
left: 0;
-webkit-transition: opacity .6s linear;
-o-transition: opacity .6s linear;
-moz-transition: opacity .6s linear;
transition: opacity .6s linear;
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-webkit-justify-content: center;
-moz-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-webkit-align-items: center;
-moz-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.pageSpinner {
-webkit-border-radius: 5%;
-moz-border-radius: 5%;
border-radius: 5%;
width: 80px;
height: 80px;
background-color: #f50;
-webkit-animation: a 1.5s infinite cubic-bezier(.4,0,.2,1);
-moz-animation: a 1.5s infinite cubic-bezier(.4,0,.2,1);
-o-animation: a 1.5s infinite cubic-bezier(.4,0,.2,1);
animation: a 1.5s infinite cubic-bezier(.4,0,.2,1);
}
@-webkit-keyframes a {
0% { -webkit-transform: perspective(300px) rotateX(0deg) rotateY(0deg); transform: perspective(300px) rotateX(0deg) rotateY(0deg); }
50% { -webkit-transform: perspective(300px) rotateX(-180deg) rotateY(0deg); transform: perspective(300px) rotateX(-180deg) rotateY(0deg); }
100% { -webkit-transform: perspective(300px) rotateX(-180deg) rotateY(-180deg); transform: perspective(300px) rotateX(-180deg) rotateY(-180deg); }
}
@-moz-keyframes a {
0% { -moz-transform: perspective(300px) rotateX(0deg) rotateY(0deg); transform: perspective(300px) rotateX(0deg) rotateY(0deg); }
50% { -moz-transform: perspective(300px) rotateX(-180deg) rotateY(0deg); transform: perspective(300px) rotateX(-180deg) rotateY(0deg); }
100% { -moz-transform: perspective(300px) rotateX(-180deg) rotateY(-180deg); transform: perspective(300px) rotateX(-180deg) rotateY(-180deg); }
}
@-o-keyframes a {
0% { transform: perspective(300px) rotateX(0deg) rotateY(0deg); }
50% { transform: perspective(300px) rotateX(-180deg) rotateY(0deg); }
100% { transform: perspective(300px) rotateX(-180deg) rotateY(-180deg); }
}
@keyframes a {
0% { -webkit-transform: perspective(300px) rotateX(0deg) rotateY(0deg); -moz-transform: perspective(300px) rotateX(0deg) rotateY(0deg); transform: perspective(300px) rotateX(0deg) rotateY(0deg); }
50% { -webkit-transform: perspective(300px) rotateX(-180deg) rotateY(0deg); -moz-transform: perspective(300px) rotateX(-180deg) rotateY(0deg); transform: perspective(300px) rotateX(-180deg) rotateY(0deg); }
100% { -webkit-transform: perspective(300px) rotateX(-180deg) rotateY(-180deg); -moz-transform: perspective(300px) rotateX(-180deg) rotateY(-180deg); transform: perspective(300px) rotateX(-180deg) rotateY(-180deg); }
}
<div class="pageLoader">
<div class="pageSpinner"></div>
</div>
Safari, for some reason, refuses to render the part of the perspective that is behind the "center" of the transformation. What I have tried:
backface-visibility: hidden|visible|initial
;transform-style: preserve-3d;
in conjunction with addingtranslateZ(1000)
to the list oftransform
sperspective-origin-z:
(various values, for both parent and child).z-index
(various values, for both parent and child withposition:relative
on child).
Please note I already found a solution: I placed a second child besides .pageSpinner
into the parent and moved background-color
from parent to that child. And it works: .pageSpinner
renders above its sibling, when properly z-index
ed. However,
I don't understand why parents' background, when opaque, clips the child. Shouldn't the background render below children no matter what? My current understanding of stacking contexts is that each positioned parent is the stacking context for all its children. And parents' background should render below this stacking context.
Could anyone explain what's different in Safari in this regard? Does it have to do with parent's position:fixed
? If it has any importance, the parent is a direct child of the body
element in its original context.
Another note: a few properties might be irrelevant for the question at hand, such as opacity
on parent and its transitions but since they are also present in the original code (and required in production), I thought I should leave them in here as well, just in case they somehow have an influence on the bug.