Firefox CSS Animation Smoothing (Subpixel Smoothing)

I am animating a CSS keyframe so that the element looks like it is randomly / slowly floating around. It is nested in parents, which uses translateX () to slowly move it left and right, and one that uses translateY () to slowly and independently move it up and down.

Chrome and Safari do a great job with this, giving it a flickering motion. It smooths the animation (maybe smoothing the subpixels?), So that everything looks very smooth. However, Firefox animates pixel by pixel, so instead of swaying smoothly, you can see how it jumps on each pixel.

Check out JSFiddle in Chrome and FireFox to see the difference: http://jsfiddle.net/gonygdfz/6/

Is there a way to make FireFox render it smoothly rather than jumping pixel by pixel? This is very noticeable in the application itself for this.

Markup:

<div id="parent"> <div id="move-x"> <div id="move-y"> <div id="child"></div> </div> </div> </div> 

CSS:

 #parent { width: 400px; height: 326px; background-color: yellow; background: url(http://paint.net.amihotornot.com.au/Features/Effects/Plugins/Render/Grid_CheckerBoard_Maker/Grid_CheckerBoard_Maker.Paint.NET.001.png) top center repeat; } #child { position: absolute; top: 75px; left: 150px; width: 100px; height: 100px; background-color: black; animation: range-y 10s infinite ease; } #move-x { animation: range-x 10s infinite ease; -webkit-animation: range-x 10s infinite ease; } #move-y { animation: range-y 15s infinite ease; -webkit-animation: range-y 15s infinite ease; } @keyframes range-x { 0% { transform: translateX(0); } 30% { transform: translateX(-8px); } 50% { transform: translateX(1px); } 65% { transform: translateX(6px); } 80% { transform: translateX(0px); } 89% { transform: translateX(-3px); } 100% { transform: translateX(0); } } @keyframes range-y { 0% { transform: translateY(0); } 20% { transform: translateY(13px); } 35% { transform: translateY(-1px); } 70% { transform: translateY(-14px); } 90% { transform: translateY(2px); } 100% { transform: translateY(0); } } @-webkit-keyframes range-x { 0% { transform: translateX(0); } 30% { transform: translateX(-8px); } 50% { transform: translateX(1px); } 65% { transform: translateX(6px); } 80% { transform: translateX(0px); } 89% { transform: translateX(-3px); } 100% { transform: translateX(0); } } @-webkit-keyframes range-y { 0% { transform: translateY(0); } 20% { transform: translateY(13px); } 35% { transform: translateY(-1px); } 70% { transform: translateY(-14px); } 90% { transform: translateY(2px); } 100% { transform: translateY(0); } } 
+14
css firefox animation css-animations
source share
2 answers

The rendering mechanisms for each browser are obviously different. Firefox does not implement a smoothing effect for CSS animations. It doesnโ€™t actually make it better or worse, it just depends on what you are animating. For example, line transitions may look undesirably blurry in Chrome.

However, it seems that you would like to achieve smoothed transitions with anti-aliasing on subpixels. We cannot change the way the engine is rendered, but we can manipulate the animation so that it is softer for the end user.


EVERYTHING IS NOT LOST

I modified your answer and provided a smoother version next to your original. This should look softer when viewed in Firefox.

CLICK FOR COMPARISON

Methods used for this effect:

  • Linear transitions instead of lightness.
  • Shadow box on an animated object. (A softened edge helps create an artificial AA effect.)
  • Rotate an object Adding the least rotation helps make better use of the rendering engine. โ€ 

CSS

 #parent { width: 50%; float:left; height: 326px; background-color: yellow; background: url(http://paint.net.amihotornot.com.au/Features/Effects/Plugins/Render/Grid_CheckerBoard_Maker/Grid_CheckerBoard_Maker.Paint.NET.001.png) top center repeat; } #child { position: absolute; top: 75px; left: 150px; width: 100px; height: 100px; background-color: black; box-shadow:0 0 1px rgba(0,0,0,0.7); animation: range-y 10s infinite linear; -webkit-animation: range-y 10s infinite linear; } #move-x { animation: range-x 10s infinite linear; -webkit-animation: range-x 10s infinite linear; } #move-y { animation: range-y 15s infinite linear; -webkit-animation: range-y 15s infinite linear; } @keyframes range-x { 0% {transform: translateX(0);} 30% {transform: translateX(-8px) rotate(0.02deg);} 50% {transform: translateX(1px) rotate(0deg);} 65% {transform: translateX(6px) rotate(0.02deg);} 80% {transform: translateX(0px) rotate(0deg);} 89% {transform: translateX(-3px) rotate(0.02deg);} 100% {transform: translateX(0) rotate(0deg);} } @keyframes range-y { 0% {transform: translateY(0);} 20% {transform: translateY(13px) rotate(0.02deg);} 35% {transform: translateY(-1px) rotate(0deg);} 70% {transform: translateY(-14px) rotate(0.02deg);} 90% {transform: translateY(2px) rotate(0deg);} 100% {transform: translateY(0) rotate(0.02deg);} } @-webkit-keyframes range-x { 0% {transform: translateX(0);} 30% {transform: translateX(-8px) rotate(0.02deg);} 50% {transform: translateX(1px) rotate(0deg);} 65% {transform: translateX(6px) rotate(0.02deg);} 80% {transform: translateX(0px) rotate(0deg);} 89% {transform: translateX(-3px) rotate(0.02deg);} 100% {transform: translateX(0) rotate(0deg);} } @-webkit-keyframes range-y { 0% {transform: translateY(0);} 20% {transform: translateY(13px) rotate(0.02deg);} 35% {transform: translateY(-1px) rotate(0deg);} 70% {transform: translateY(-14px) rotate(0.02deg);} 90% {transform: translateY(2px) rotate(0deg);} 100% {transform: translateY(0) rotate(0.02deg);} } 

FINAL WORD

You can still tweak the effects a bit to suit your requirements. This is not ideal, but I hope this helps soften the final effect for your real animation.

+11
source share

Use a small amount of rotation with the conversion. This forces Firefox to avoid optimization and recount the image in each frame.

 @keyframes optimized { 0%{ transform: translateX(0%); } 100%{ transform: translateX(200px); } } @keyframes subpixel { 0%{ transform: translateX(0%) rotate(0.1deg); } 100%{ transform: translateX(200px) rotate(0.1deg); } } div{ width:5px; height:50px; background-color: red; animation-duration:30s; animation-iteration-count: infinite; animation-direction:alternate; animation-timing-function:linear; } .optimized{ animation-name: optimized; margin-bottom:1px; } .subpixel{ animation-name: subpixel; } 
 <div class="optimized"> </div> <div class="subpixel"> </div> 

0
source share

All Articles