Search code examples
javascriptcsstransformjittertranslate3d

Css jittery text translate


[SOLUTION]
Solution is to use the will-change CSS property taht forces GPU rendering:

will-change: transform;

[ORIGINAL QUESTION]
I've been digging a lot internet and found no solution to a problem that seems rather simple which is, translating a holder containing text, and having this text moving smoothly.

Here is an example of the problem, you can see the text is following its holder step by step, not smoothly:

enter image description here

I also made a small codepen to see the effect live :

https://codepen.io/Durss/pen/ExgBzVJ?editors=1111

var angle = 0;
var radius = 100;
function renderFrame() {
        requestAnimationFrame(renderFrame);
    var cx = document.documentElement.clientWidth / 2;
    var cy = document.documentElement.clientHeight / 2;
    var div = document.getElementById("text");
    var px = cx + Math.cos(angle) * radius;
    var py = cy + Math.sin(angle) * radius;
    angle += .001;
    div.style.transform = "translate3d("+px+"px, "+py+"px, 0)";
}

renderFrame();
body {
  background-color:black;
  width:100%;
  height:100%;
}

#text {
  position:absolute;
  left:0;
  top:0;
  border: 2px solid white;
  background-color: #2f9da7;
  padding: 10px;
  border-radius:20px;
  color: white;
  font-weight: bold;
}
<div id="text">blah blah</div>

Basically, the problem is that the holder is moving at a subpixel level but the text position seems rounded no matter what i try. I used translate3d() so it uses GPU rendering which fixes the holder's displacement but not its text content.

div.style.transform = "translate3d("+px+"px, "+py+"px, 0)";

I've seen here and there the following CSS "solutions" that didn't work for me:

text-rendering: geometricPrecision;
-webkit-font-smoothing: antialiased;
transform-style: preserve-3d;
backface-visibility: hidden;
-webkit-font-smoothing:none;

I've had this problem many time in the past but always gave up fixing it,i think it's time to seek for help as a last bullet !

Thanks for reading me!


Solution

  • will-change: contents;
    

    resolved my own jittery text issues when doing transform rotations. This tells the browser that the contents of an element are expected to change therefore should not be cached.

    This must be applied immediately before the transform.