CSS3 Transition shifts rotated element by 1px in Safari - css

Safari fails to correctly render 180deg rotated element. In particular there are two examples when it can be shown (used Safari 9.1):
Issue with odd width. You can see (look at the border) that the bottom element is shifted 1px right against its parent div initially and shifts more on transition.
Issue with even width. It looks fine initially but also shifts 1px right on transition.
Here's css for even case (in odd it's just all widths and heights subtracted 1px):
.no-overflow-container {
width: 518px;
height: 368px;
margin: 10px;
overflow: hidden;
}
.container {
width: 368px;
height: 368px;
background: red;
margin-right: 30px;
-webkit-transition: margin 350ms;
-moz-transition: margin 350ms;
transition: margin 350ms;
}
.container:hover {
margin-left: 150px;
}
.threed-container {
width: 100%;
height: 100%;
-webkit-perspective: 800px;
-moz-perspective: 800px;
perspective: 800px;
position: relative;
box-sizing: border-box;
}
.faced-item {
width: 100%;
height: 100%;
border: 1px solid black;
font-size: 28px;
position: absolute;
padding: 30px;
box-sizing: border-box;
}
.rotated-item {
width: 100%;
height: 100%;
border: 1px solid black;
font-size: 28px;
position: absolute;
-webkit-transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
transform: rotateY(180deg);
box-sizing: border-box;
}
And HTML:
<div class="no-overflow-container">
<div class="container">
<div class="threed-container">
<div class="faced-item">
HELLO WORLD FACE
</div>
</div>
</div>
</div>
<div class="no-overflow-container">
<div class="container">
<div class="threed-container">
<div class="rotated-item">
HELLO WORLD BACKFACE
</div>
</div>
</div>
</div>
It works quite fine in Chrome(52) and Firefox(47).
So any suggestions about how to fix it in Safari?

I solved this using will-change: transform; (Safari 10)
https://jsfiddle.net/4hocy9qt/2/

take a look at backface-visibilityproperty, it could solve your issue:
backface-visibility: hidden;
https://css-tricks.com/almanac/properties/b/backface-visibility/

Related

CSS| Are 3D Absolute Items always on top of every other item?

so i have an issue, i am developing a website and i'm playing around with 3 dimensional cards. so the problem i run in is basically, no matter which z-index i give the div that should be above it, the card is still always in front. Is this an normal behavior or am i missing something? Thank you really much :)
Heres the HTML:
<div class="project">
<div class="project-title">
<h1>someproject</h1>
</div>
<div class="project-scene">
<div class="project-card">
<div class="project-face project-front">
</div>
<div class="project-face project-back">
<p>blablabla</p>
<img src="../assets/solarflarepi-presentation.gif">
<p>
blablabla
</p>
</div>
</div>
</div>
</div>
And here is the css:
.project{
border: white solid 0.3em;
border-radius: 1em;
margin-bottom: 1em;
margin-left: 1em;
flex: 1;
align-items: center;
}
.project-card{
background-color: transparent;
width: 25em;
height: 26em;
position: relative;
transition: transform 0.5s;
transform-style: preserve-3d;
}
.project-scene{
perspective: 1000px;
}
.project-scene:hover .project-card{
transform: rotateY(180deg);
}
.project-face{
position: absolute;
backface-visibility: hidden;
z-index: 0; /* The Div which should be above it has 5 */
}
.project-back .project-card{
background-color: black;
}
.project-front{
background-color: white;
width: 100%;
height: 100%;
}
.project-back{
background-color: black;
width: 100%;
height: 100%;
transform: rotateY(180deg);
}
.project-title{
background-color: white;
color: black;
}
.project-title h1{
margin: 0;
padding: 0em 0.5em 0em 0.5em;
font-weight: normal;
text-align: center;
}
.project-back img{
width: 25em;
}
In this case z-index do not fix your problem, you must use transform: translateZ(5);
like this:
enter image description here

Skewing divs via CSS

Attached is a brief mockup of what I need to create. The div not only needs to skew on the bottom, but the next row will need to skew to the top.
Is there a clean way this can be done using CSS? I've tried some CSS solutions ( e.g http://jsfiddle.net/mXLgF/ ) but can not get this effect.
My current HTML / CSS is at this stage:
<div class="skew_bottom_right">
<div style="height: 300px; background: url('http://placehold.it/850x350');">
</div>
</div>
.skew_bottom_right div:after {
content: '';
position: absolute;
left: 0;
bottom: -60px;
width: 100%;
height: 115px;
background: white;
-webkit-transform: skewY(8.5deg);
-moz-transform: skewY(8.5deg);
-ms-transform: skewY(8.5deg);
-o-transform: skewY(8.5deg);
transform: skewY(8.5deg);
-webkit-backface-visibility: hidden;
z-index: 5;
}
Each of those containers will eventually made into a slide, so ideally they should be div's with background images or containing divs having a background image.
Your code is pretty good.
Just needed some minor adjustments...
.container{
overflow:hidden;
}
.parallelogram {
width: 600px;
height: 100px;
margin: 30px 0;
transform: skewY(5deg);
background: gray;
overflow:hidden;
position:relative;
}
.parallelogram.header {
height: 150px;
margin: -30px 0;
}
.parallelogram.footer {
height: 150px;
margin: -30px 0;
}
.image{
background: url(http://placekitten.com/300/300);
background: blue;
width: calc(100% / 3);
height: 100%;
display: inline-block;
float: left;
border: 3px solid white;
box-sizing: border-box;
}
<div class="container">
<div class="parallelogram header"></div>
<div class="parallelogram">
<div class="image"></div>
<div class="image"></div>
<div class="image"></div>
</div>
<div class="parallelogram footer"></div>
</div>

Why does setting overflow:hidden; break the backface-visibility declaration?

I have a "flippable" modal dialogue consisting of two divs (front and back):
<div class="modal-dialogue">
<div class="modal-content">
<div class="front">
<h1>Front</h1>
</div>
<div class="back">
<h1>Back</h1>
</div>
</div>
</div>
Using CSS transform I flip the modal over to reveal the back by adding the "flipped" class to the modal-content with:
.modal-content.flipped {
-webkit-transform: rotateY(180deg);
}
This all works fine... except when I add the overflow:hidden; property to the modal-content. Suddenly, the back div is not visible and instead the backface of the front div becomes visible (even though it has backface-visibility set to hidden).
This seems very strange. Why would setting the overflow property change the backface-visibility in this way?
You can see it in action in this fiddle: https://jsfiddle.net/amxp02mx/ . It works fine, but if you comment out line 31 in the CSS, making the overflow:hidden, it is broken.
Can anyone explain why?
document.querySelector(".modal-content")
.addEventListener("click", function () {
this.classList.toggle("flipped");
});
.modal-dialogue {
z-index: 1050;
display: block;
width: 25rem;
min-height: 30rem;
margin-left: -12.5rem;
margin-top: -15rem;
position: fixed;
left: 50%;
top: 50%;
-webkit-perspective: 800px;
}
.modal-content {
width: 25rem;
min-height: 30rem;
position: relative;
background-color: transparent;
border-radius: 10px;
outline: none;
transition: 0.8s ease;
-webkit-transform-style: preserve-3d;
-webkit-transition: -webkit-transform 1s;
margin: 5rem auto 0 auto;
/* With overflow:hidden; the back of the panel is
not visible and the backface-visibility:hidden
stops working. Why? */
overflow: hidden;
/* With overflow: visible; it works fine. */
overflow: inherit;
}
.modal-content div {
display: block;
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
color: white;
font-size: 140px;
font-weight: bold;
text-align: center;
overflow: hidden;
}
.modal-content .front {
background: red;
z-index:0;
}
.modal-content .back {
background: blue;
-webkit-transform: rotateY(180deg);
z-index:-1;
}
.modal-content.flipped {
-webkit-transform: rotateY(180deg);
}
<div class="modal-dialogue">
<div class="modal-content">
<div class="front">
<h1>Front</h1>
</div>
<div class="back">
<h1>Back</h1>
</div>
</div>
</div>
you can see the explanation here in the documentation:
https://drafts.csswg.org/css-transforms/#grouping-property-values
also your issue is easily fixed by adding
overflow:hidden;
to the .modal-content div rule
https://jsfiddle.net/amxp02mx/4/

How to mask corners of static content of oval-shaped div?

Here's the HTML:
<div class="root">
<div class="oval">
<div class="val"></div>
</div>
</div>
and here's the relevant CSS, so far:
.oval {
box-sizing: padding-box;
width: 200px;
height: 100px;
border: 10px solid black;
border-radius: 60px;
position: relative;
}
.oval .val {
width: 93%;
height: 100%;
position: absolute;
}
Go here to see what it looks like at the moment.
I want to mask the square corners of the .oval .val element, so that they appear to be behind the "opening" suggested by the .oval element's border.
The right edge of .oval .val element should run vertically from top to bottom, without any rounding.
NOTE: The width of the .oval .val can be anything between 0% and 100%, including problematic values such as 93%.
Add overflow: hidden; to the .oval class.
Add
.oval {
overflow: hidden;
}
to your CSS.
To explain this, I've added a background-color to .val class
.oval {
box-sizing: padding-box;
width: 200px;
height: 100px;
border: 10px solid black;
border-radius: 60px;
position: relative;
overflow: hidden;
}
.oval .val {
width: 93%;
height: 100%;
position: absolute;
}
.val {
background-color: red;
}
<div class="root">
<div class="oval">
<div class="val"></div>
</div>
</div>

Clip child to parent element with border-radius

How do I force clip a child to a parent element that has rounded corners.
<div class="item" >
<div class="top">
<h1>Tile</h1>
<h2>Click me</h2>
</div>
<div class="behind">
<h3>Details</h3>
</div>
</div>
When animating the child, its ignores the border-radius of the parent element. Is there a way to fix the two corners on the top?
.item{
text-align: center;
cursor: pointer;
overflow: hidden;
height: 280px;
width: 280px;
float: left;
border-radius: 5px;
background: white;
margin: 10px;
position: absolute;
}
.top{
z-index: 1;
position: absolute;
height: 280px;
width: 280px;
background: #ed844b;
transition: 0.3s;
border-radius: 5px;
}
.behind{
z-index: 0;
position: absolute;
width: 100%;
top: 136px;
height: 138px;
padding: 10px 16px;
background: #DDDDDD;
box-sizing: border-box;
border-radius: 5px;
}
.slide-up{
transform: translate3d(0, -136px, 0);
border-radius: 0px;
}
Here is a little demo:
http://codepen.io/Koopa/pen/xbaMez
Thanks
Koopa
When you add a css 3d transform to the child, you kinda move it to the separate GPU layer. You can move parent element to GPU layer instead adding null-transform hack transform: translateZ(0) to .item. Or you can replace translate with translateY (In this case child is clipped only when not being animated).

Resources