Mark Thomas Miller

Fix blurry edges when using transform: scale

I recently made Breathe, a simple CSS project to help me regain focus while working on long projects. In Breathe, a circular div is kept in a constant state of transformation as it swells along with the user’s breath. I accomplished to animate it with pure CSS by using keyframes and the transform: scale property.

However, I noticed that, as it was scaling, my div had increasingly blurry edges. Basically, since the div never stopped increasing or decreasing its width, the browser would never render it correctly and kept it in a perpetual state of pixelation.

If you’re trying to solve this issue, you can think of a div with a scale of greater than 1 as an image. If you stretch an image to twice its size, there will naturally be some pixelation. In order to combat this, you can make sure the maximum scale never exceeds 1, like so:

@keyframes doubleSizeOfElement {
    0%   { transform: scale(0.5); }
    100% { transform: scale(1.0); }
}

Afterwards, set the div’s default width and height to what it needs to be at your largest size (scale(1)). For example, if I have a keyframe animation that doubles a square from 100 × 100 to 200 × 200 pixels, I’ll set the square to 200×200, then start off the keyframe at scale(.5). (which will give it the starting width of 100 × 100 pixels).

As it grows, the div will double in size in a completely clean fashion (your intended effect), when in actuality, it’s simply moving from half size to whole size.

Magical, right?