stutter/flicker in 3d transform for firefox - html

I came across THIS SITE today and the 3dtransform of the QR code was unbearable in FF.
I viewed the same site in Chrome and the animation was much smoother. I wanted to know what was going on so I viewed the source and stripped out the non-pertinent info and created a fiddle:
DEMO
The core code I pulled from that site is here:
HTML
<div class="QRcode3d">
<img alt="QR Code Cube 1" src="http://blog.qr4.nl/images/QR-Cube-1.jpg">
</div>
CSS
.QRcode3d {
height: 331px;
margin: 150px auto;
position: relative;
transform: scale(0.9);
transform-style: preserve-3d;
width: 331px;
animation: 30s linear 0s normal none infinite spin1;
display: block;
}
#-webkit-keyframes spin1 {
0% {-webkit-transform: perspective(600px) rotateX(0deg) rotateY(90deg) rotateZ(0deg);}
100% {-webkit-transform: perspective(600px) rotateX(360deg) rotateY(450deg) rotateZ(0deg);}
}
#keyframes spin1 {
0% {transform: perspective(600px) rotateX(0deg) rotateY(90deg) rotateZ(0deg);}
100% {transform: perspective(600px) rotateX(360deg) rotateY(450deg) rotateZ(0deg);}
}
The only BUG REPORT I've seen on the topic doesn't have much info in the way of 'solving' the issue.. there is even difficulty in reproducing it.
Going to CanIUse shows that it was available on my version of FF, and even toggling hardware acceleration in the FF browser didn't really alter the situation.
Does anyone know the root cause of the 3D Transform issue in FF, and what may be done to remedy the situation?

Just get the perspective out of the animation and put it into the main rule:
.QRcode3d {
height: 331px;
margin: 150px auto;
position: relative;
transform: scale(0.9);
transform-style: preserve-3d;
width: 331px;
animation: 30s linear 0s normal none infinite spin1;
display: block;
perspective: 600px;
}
Here is the demo: http://jsfiddle.net/PLZ2j/1/
Updated DEMO (for Chrome)

Related

IE11 css animations with crazy timing function

For some reason all animations on my site that work perfectly on firefox/chrome/edge have some crazy timing on IE11.
The animation as it's intended: http://sendvid.com/52jn0saf
The animation on IE11: http://sendvid.com/vt6mk9pm
I tried changing animation-timing-function, I tried adding animation-delay 0, but nothing works.
The animation of scrolling in:
.step__hidden{
top: -100vh;
}
.step__active{
animation: scrollIn 1s ease-in-out 0s;
top: 0;
}
#keyframes scrollIn{
0%{
transform: translateY(-100vh);
}
100%{
transform: translateY(0);
}
}
Also, is there even a way to inspect animations in IE/Edge dev tool like in other, saner browsers?
It may be due to you missing out the IE vendor prefix for transform:
#keyframes scrollIn{
0%{
-ms-transform: translateY(-100vh);
transform: translateY(-100vh);
}
100%{
-ms-transform: translateY(-100vh);
transform: translateY(0);
}
}
You can install Firebug on IE to inspect

CSS circles shaking on animation

I have drawn a circle in CSS. I tried playing around with the code to fix this issue but to no avail. I have 2 main issues :
In Chrome :
The circles shake while rotating
In Firefox :
There appears a tail-like dot when the circle is animating in circular motions.
This is the CSS styling I am using :
.followers_arc_outer{
position:absolute;
width:300px;
height:300px;
border-radius:100%;
border:2px solid;
}
.followers_arc_start {
border-color:transparent #ecd201 #ecd201 #ecd201;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
.followers_arc_inner{
position:absolute;
top:18px;
left: 18px;
width: 280px;
height:280px;
border-radius:100%;
border:2px solid;
border-color:transparent #ecd201 #ecd201 #ecd201;
}
.o_circle {
-webkit-animation: rotation 2s infinite linear;
animation: rotation 2s infinite linear;
}
#-webkit-keyframes rotation{
from {-webkit-transform: rotate(0deg);transform: rotate(0deg);}
to {-webkit-transform: rotate(359deg);transform: rotate(359deg);}
}#keyframes rotation{
from {-webkit-transform: rotate(0deg);transform: rotate(0deg);}
to {-webkit-transform: rotate(359deg);transform: rotate(359deg);}
}
.i_circle {
-webkit-animation: rotation2 2s infinite linear;
animation: rotation2 2s infinite linear;
}
#-webkit-keyframes rotation2 {
from {-webkit-transform: rotate(359deg);transform: rotate(359deg);}
to {-webkit-transform: rotate(0deg);transform: rotate(0deg);}
}#keyframes rotation2 {
from {-webkit-transform: rotate(359deg);transform: rotate(359deg);}
to {-webkit-transform: rotate(0deg);transform: rotate(0deg);}
}
<div class="followers_arc_outer followers_arc_start o_circle"></div>
<div class="followers_arc_inner followers_arc_start i_circle"></div>
I have created a fiddle. Here is the link :
http://jsfiddle.net/r8cqet2c/4/
Am I doing something wrong?
If your circles are big then the browsers may take time to render them. And at the same time when you try to rotate and animate them, then it would be hard for the browser to do that smoothly with the CPU graphics(which the browser uses by default).
But you can make use of your GPU in your browser by using some hardware accelerated CSS. Which will boost the performance of you animations. Here is the code you can apply to your circles to make them run smoother.
-webkit-transform: translate3d(0,0,0);
-moz-transform: translate3d(0,0,0);
-ms-transform: translate3d(0,0,0);
-o-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
or you can use this below one...both will work..
-webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
-o-transform: translateZ(0);
transform: translateZ(0);
If you still see some weird lag or something in chrome or safari then you will have to add this below code as well.
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-perspective: 1000;
-moz-perspective: 1000;
-ms-perspective: 1000;
perspective: 1000;
Hope it helps..
Maybe transform-origin and perspective-origin properties can help you:
http://www.w3schools.com/cssref/css3_pr_transform-origin.asp
http://www.w3schools.com/cssref/css3_pr_perspective-origin.asp
I think it has to do with anti-aliasing and rounding. I changed to background to plain black and made the animations stop after one round. When the circles are still you can see that the anti-aliasing makes some parts of the circles look less solid, especially when you zoom smaller. I don't see the shaking or the tail.
Any case is shaking
I checked the code in Chrome, Mozilla, Opera and Safari (even 5.17 is working)
Maybe you're using a bad resolution or some graphic card problem.
No problem here stand-alone. (Chrome, Firefox, Safari)
If you see a problem here stand-alone; it may be due to your machine / hardware or browser settings.
But it's likely some other code you have in your application conflicting with this code causing the shake.
It's happens due to anti-aliasing and you can solve it by smoothing the border. You can use box-shadow with inset property instead of color with solid property in order to prevent it:
CSS
.followers_arc_outer {
position:absolute;
width:300px;
height:300px;
border-radius:100%;
box-shadow: 2px 0px 2px 0px #ecd201 inset;
}
.followers_arc_inner {
position:absolute;
top:18px;
left: 18px;
width: 280px;
height:280px;
border-radius:100%;
box-shadow: 2px 0px 2px 0px #ecd201 inset;
}
heres the fiddle to see how it works :
http://jsfiddle.net/heartagramir/xdmuvu9s/
To make transforms more smooth and prevent looking juddery or tattered you can reset translate3d to zero:
.transform {
-moz-transform: rotate(-4.7deg) translate3d(0, 0, 0);
-ms-transform: rotate(-4.7deg) translate3d(0, 0, 0);
-o-transform: rotate(-4.7deg) translate3d(0, 0, 0);
-webkit-transform: rotate(-4.7deg) translate3d(0, 0, 0);
transform: rotate(-4.7deg) translate3d(0, 0, 0);
}
I would suggest to add translate3d(0, 0, 0) whenever you use transform

webkit-transform breaks z-index on Safari

Problem
I'm trying to make a layer appear like it's a wall falling down, revealing the layer behind it. I've setup two fixed div positions. The "Wall" div has a z-index of 9999, the "Background" div has a z-index of 0;
In Webkit browsers (Safari/IOS) that I've tested, it seems like once the animation starts on the "wall", the z-indexes are lost or ignored, causing the "wall" layer to abruptly disappear behind the background div.
Any ideas on how to preserve the z-indexes of the layers? Thanks in advance!
Example Code
(note: jsFiddle at the bottom)
HTML Code
<div id="wall">
This is the wall
</div>
<div id="background">
This is the background
</div>
<button id="start" style="float: right;">
Flip Down
</button>
Some javascript to enable the button
$('#start').click(function(){
alert('Should Fall Down like a wall, revealing the background');
$('#wall').addClass('animated flipDown');
});
CSS Code (cribbed from animate.css)
#wall{
background-color: #F00;
width: 100px;
height: 100px;
position:fixed;
top:0;
left:0;
z-index: 9999;
}
#background{
background-color: #00F;
width: 100px;
height: 100px;
position:fixed;
top:0;
left:0;
z-index: 0;
}
.animated {
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
/*** flipDown ***/
#-webkit-keyframes flipDown {
0% {
-webkit-transform: perspective(400px) rotateX(0deg);
transform: perspective(400px) rotateX(0deg);
-webkit-transform-style: flat;
opacity: 1;
}
100% {
-webkit-transform: perspective(400px) rotateX(90deg);
transform: perspective(400px) rotateX(90deg);
-webkit-transform-style: flat;
opacity: 1;
}
}
#keyframes flipDown {
0% {
-webkit-transform: perspective(400px) rotateX(0deg);
-ms-transform: perspective(400px) rotateX(0deg);
transform: perspective(400px) rotateX(0deg);
opacity: 1;
}
100% {
-webkit-transform: perspective(400px) rotateX(90deg);
-ms-transform: perspective(400px) rotateX(90deg);
transform: perspective(400px) rotateX(90deg);
opacity: 0;
}
}
.flipDown {
-webkit-animation-name: flipDown;
animation-name: flipDown;
-webkit-backface-visibility: visible !important;
-ms-backface-visibility: visible !important;
backface-visibility: visible !important;
-webkit-transform-origin: bottom;
-ms-transform-origin: bottom;
transform-origin: bottom;
}
jsFiddle
http://jsfiddle.net/3mHe2/2/
Check out the differences in Safari vs Chrome.
My rotating element wasn't suitable to have a neighbour to the background, but I fixed it by applying
transform: translateZ(1000px);
transform-style: preserve-3d;
to the parent of the rotating element. Safari now thinks it's 1000px infront of the background.
Found a solution. Hopefully this helps someone in the future.
It turns out that there is a "bug" in the safari versions of webkit. When a 3d css animation is playing, the original z-indexes are lost. Instead, it seems like the animating pieces are put into a separate z-index "group" that is separate from the rest of the z-indexes of the DOM.
The solution is to join the backdrop div and the wall div into the same z-index group by wrapping it in a div with a webkit-transform that doesn't change anything. That causes the backdrop and wall to be children of the wrapper div and the z-indexing of the respective children are preserved.
<div id="wrapper" style="-webkit-transform: translate3d(0px, 0px, 0px);">
<div id="wall">
This is the wall
</div>
<div id="background">
This is the background
</div>
</div>
I believe it is the same or similar issue to this:
css z-index lost after webkit transform translate3d
I ran into this issue and nothing would fix it until i added perspective to the parent container of the item that should be behind.
.wrap{
perspective: 1000px;
}
In my case I was able to solve the issue by applying translateZ to the parent and translate scale to the child.
.parent {
transform: translateZ(22px);
}
.child {
transform: scale(0.955);
}

CSS3 animations - delay, stop and play

I am not very good at CSS3 animations so I need some help to improve the output.
I am trying to achieve the Windows8 tile effect and I am nearly done.
I am trying to achieve this
and here is the jsfiddle
The CSS which flips is the following.
The suffix '1' is for block1 ,'2' for block2 and so on 'til 5 for five blocks.
/*block one*/
.flip-container1, .front1, .back1 {
position:relative;
width: 432px;
height: 140px;
}
.flipper1 {
-webkit-transition: 0.6s;
-webkit-transform-style: preserve-3d;
-moz-transition: 0.6s;
-moz-transform-style: preserve-3d;
transition: 0.6s;
transform-style: preserve-3d;
position: relative;
}
.front1, .back1 {
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
background: #2FB1BE;
}
.vertical1.flip-container1 {
position: relative;
}
.vertical1 .back1 {
-webkit-transform: rotateX(180deg);
-moz-transform: rotateX(180deg);
transform: rotateX(180deg);
}
.vertical1.flip-container1 .flipper1 {
-webkit-transform-origin: 100% 70px;
-moz-transform-origin: 100% 70px;
transform-origin: 100% 70px;
}
#keyframes myFirst{
from{
webkit-transform: rotateX(-180deg);
-moz-transform: rotateX(-180deg);
transform: rotateX(-180deg);
}
to{
webkit-transform: rotateX(180deg);
-moz-transform: rotateX(180deg);
transform: rotateX(180deg);
}
}
#-webkit-keyframes myFirst{
from{
webkit-transform: rotateX(-180deg);
-moz-transform: rotateX(-180deg);
transform: rotateX(-180deg);
}
to{
webkit-transform: rotateX(180deg);
-moz-transform: rotateX(180deg);
transform: rotateX(180deg);
}
}
.vertical1.flip-container1 .flipper1{
animation:myFirst 3s;
-webkit-animation:myFirst 3s;
animation-direction:normal;
-webkit-animation-direction:normal;
animation-iteration-count:infinite;
}
Now I want to solve the following two problems:
1- I want that only one tile flips at a time.
Currently, I have applied different animation times which looks fine but multiple tiles are flipping at a time.
2- I want the animation of a particular tile to stop when the backside is shown and then move to another tile and when again its turn comes then front side is shown again. Currently, it shows front side and then immediately shows back side and then pauses for a while.
For your first problem, you'll want to use the :hover pseudo tag, and if needed also use tile-specific ids.
I don't quite understand what you mean by "then move to another tile and when again its turn comes then front side is shown again". But, you have animation-iteration-count: set to infinite so of course the animation will continue on infinitely.
It seems you don't quite understand CSS animations/transitions fully yet. Perhaps you should practice with just making a box grow on mouse hover, then work your way up to making just 1 box flip. W3Schools has a great reference to CSS Animations.

CSS keyframe animation with translation transform snaps to whole pixels in IE 10 and Firefox

It appears both IE 10 and Firefox snaps elements to whole pixels when animating their position using translate 2d transform in a css keyframe animation.
Chrome and Safari does not, which looks a lot better when animating subtle movements.
The animation is done the following way:
#keyframes bobbingAnim {
0% {
transform: translate(0px, 0px);
animation-timing-function:ease-in-out
}
50% {
transform: translate(0px, 12px);
animation-timing-function:ease-in-out
}
100% {
transform: translate(0px, 0px);
animation-timing-function:ease-in-out
}
}
Here's an example of what I mean:
http://jsfiddle.net/yZgTM/.
Just open it in Chrome and IE 10 (or Firefox) and you should notice the difference in smoothness of the motion.
I realise there might be many factors affecting this behaviour such as if the element is drawn with hardware acceleration or not.
Does anyone know of a fix to try to force browsers to always draw the elements on subpixels?
I found this similar question, but the answer was to animate using a translate transform, which is exactly what I'm doing:
CSS3 Transitions 'snap to pixel'.
Update:
After playing around a bit I found a fix for Firefox, doesn't do anything in IE 10 though. The trick is to scale down the element ever so slightly and use translate3d with a 1px offset in the Z-axis:
#keyframes bobbingAnim {
0% {
transform: scale(0.999, 0.999) translate3d(0px, 0px, 1px);
animation-timing-function:ease-in-out
}
50% {
transform: scale(0.999, 0.999) translate3d(0px, 12px, 1px);
animation-timing-function:ease-in-out
}
100% {
transform: scale(0.999, 0.999) translate3d(0px, 0px, 1px);
animation-timing-function:ease-in-out
}
}
I love your question!
Good job in noticing the pixel-snap in firefox and IE10.
I've researched this subject a while ago and I advise you to check the GSAP forums, as they contain a lot of useful information on web animations.
Here's a topic regarding IE10 pixel-snap issue.
What you need to do is add a minimal rotation to the element. This is so IE and Firefox will redraw it in a different way - which will stop pixel-snap for good :)
Tyr this:
#keyframes bobbingAnim {
0% {
transform: translate(0px, 0px) rotateZ(0.001deg);
animation-timing-function:ease-in-out
}
50% {
transform: translate(0px, 12px) rotateZ(0.001deg);
animation-timing-function:ease-in-out
}
100% {
transform: translate(0px, 0px) rotateZ(0.001deg);
animation-timing-function:ease-in-out
}
}
#Nemanja is correct you will find that if you tweak the speed you will see better results this is fairly typical with css animations. Also it doesn't really make a difference in this case if you enable hardware acceleration. I tidied up the code a little bit and ran it without any issues, i do not have ie10; However, I have 11. You may have to just remove the second transform of translateZ if it doesn't run in 10
body {
background-color: #ccc;
}
.bobbing {
position: absolute;
animation: bobbingAnim ease-in-out .5s infinite;
-moz-animation: bobbingAnim ease-in-out .5s infinite;
-webkit-animation: bobbingAnim ease-in-out .5s infinite;
}
.bobbing.text {
font-size: 50px;
color: #000;
left: 30px;
top: 30px;
}
.bobbing.image {
left: 30px;
top: 150px;
background: url(http://placehold.it/300x100/aa0000&text=Bobbing+image) 50% 50% no-repeat;
width: 310px;
height: 110px;
}
#keyframes bobbingAnim {
50% {
transform: translate(0, 12px) translateZ(0);
}
}
#-webkit-keyframes bobbingAnim {
50% {
-webkit-transform: translate3d(0, 12px, 0);
}
}
#-moz-keyframes bobbingAnim {
50% {
-moz-transform: translate3d(0, 12px, 0);
}
}
There cant be half a pixel movement, there is no such thing.
Your problem is the speed and smoothness of the animation, not the "pixel snapping".