Firefox CSS Animation Smoothing (Sub-Pixel Smoothing)

Firefox CSS Animation Smoothing (sub-pixel smoothing)

The rendering engines for each browser is obviously different. Firefox does not implement an anti-aliasing effect on CSS animations. This does not inherently make it better or worse, it just depends on what you are animating. Linear transitions can appear undesirably blurred in Chrome for example.

It appears what you would like to achieve is to have an anti-aliased/sub-pixel smoothed transitions. We can't change the way the engine renders but we can manipulate the animation to appear softer to the end user.


ALL IS NOT LOST

I have modified your answer and rendered a smoother version next to your original. This should appear softer when viewed in Firefox.

CLICK FOR COMPARISON

Techniques used for this effect:

  • Linear transitions instead of ease.
  • Box-shadow on animated object. (Softened edge helps create fake AA effect).
  • Rotate object. Adding the smallest rotate helps to better utilised 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 little either way to fit your requirements.
It's not perfect but I hope it helps soften the end effect for your actual animation.

Rotate css animation glitchy in firefox

Your issue is half-pixel/sub-pixel rendering. Playing around and changing border-bottom: 1px solid #f00; to border-bottom: 3px solid #f00; shows that animation is ok, but the rendering is very different from other browser engines... From another answer here of StackOverflow: Firefox CSS Animation Smoothing (sub-pixel smoothing)

The rendering engines for each browser is obviously different. Firefox does not implement an anti-aliasing effect on CSS animations. This does not inherently make it better or worse, it just depends on what you are animating. Linear transitions can appear undesirably blurred in Chrome for example.

That said it appears what you would like to achieve is to have an anti-aliased/sub-pixel smoothed transitions. We can't change the way the engine renders but we can manipulate the animation to appear softer to the end user.


But, differently from the approach provided by the answer in the link, in your scenario I think that there is a easier way to make the rendering more equivalent: http://jsfiddle.net/zg8vdyns/7/

Adding border-left: 1px solid rgba(255, 0, 0, 0.7); will kinda "force" the rendering of the half-pixels/sub-pixels that FireFox doesn't naturally...

Update:

@joshin855 also give a great answer below: adding the property background:rgba(255,255,255,0.01); will kinda "force" the rendering of the half-pixels/sub-pixels too. Your solution is very nice... It only have the disadvantage of a filled circle which depending on the scenario may not be suitable, but the line animation seems even more equivalent than in my solution... So, it also may be a good solution.

Synchronous CSS3 transition in FireFox is not smooth

Your real problem here is that Firefox allows non-integer-pixel padding values but only integer-device-pixel border values (because it turns out that web pages depend on borders being integer-width). Chrome forces both to integer numbers of pixels, so things work out there. For now. Until they start doing subpixel padding. But in Firefox you're getting 1-device-px bounce whenever the border goes from a bit less than a half-integer to a bit more than a half-integer.

There really isn't a great solution here, unfortunately. See http://robert.ocallahan.org/2008/01/subpixel-layout-and-rendering_22.html for a description of the problems WebKit's approach causes, for example.

CSS width transition choppy in FireFox if element rotated

Maybe you could use writing-mode instead transform :

function animate() {

var e = document.getElementById('rotbox1');

if (e.style.height == '120px') e.style.height = '200px';

else e.style.height = '120px';

e = document.getElementById('rotbox2');

if (e.style.width == '120px') e.style.width = '200px';

else e.style.width = '120px';

}

animate();

setInterval(animate, 2000);
.wrp-v {

text-align: center;

-webkit-writing-mode: vertical-lr;

/* old Win safari */

writing-mode: vertical-lr;

writing-mode: tb-lr;

direction: ltr;

padding-right: 30px;

position: absolute;

right: 30%;

bottom: 30%;

}

.wrp-h {

padding-right: 30px;

position: absolute;

right: 30%;

bottom: 20%;

}

.rotbox {

background: green;

color: white;

display: inline-block;

text-align: center;

height: 40px;

line-height: 40px;

border-radius: 20px;

font-size: 16px;

-webkit-transition: width 2.0s ease;

transition: width 2.0s ease;

}

#rotbox1 {

height: 200px;

-webkit-transition: height 2.0s ease;

transition: height 2.0s ease;

}
<div class="wrp-v">

<div class="rotbox" id="rotbox1">Hello world</div>

</div>

<div class="wrp-h">

<div class="rotbox" id="rotbox2">Hello world</div>

</div>


Related Topics



Leave a reply



Submit