When I try to scale a div on mouse hover, the text wobbles/jitters and the animation is not smooth. This is especially apparent in FireFox, but can also be seen in Chrome.
Are there any changes I can do to make the animation smooth?
JS Fiddle: https://jsfiddle.net/jL4dbxf9/
.mtw {
max-width: 200px;
margin: 0 auto;
}
.mt .mp {
text-align: center;
}
.mt .mp .ma {
color: #fff;
font: 800 40px OpenSansBold, Arial, Helvetica, sans-serif;
min-height: 60px;
}
.mt .header-blue {
background: blue;
}
.mt {
transition: all 0.4s linear;
}
.mt:hover{
z-index: 1;
transform: scale(1.1);
-webkit-transform: scale(1.1);
-moz-transform: scale(1.1);
-o-transform: scale(1.1);
-ms-transform: scale(1.1);
}
<div class="mtw">
<div class="mt">
<div class="header-blue">
<h2 class="mp">
<span class="ma">49</span>
</h2>
</div>
</div>
</div>
I had this problem with SVG scaling and blurry images. I scaled up a background image to 4.5 and the image rendered very blurry while scaling up. I read that you can scale down first transform: scale(0.7) and then scale up to transform: scale(1.0) . In my case this meant a huge rebuild of my animation.
This scaling transformation is characterized by a two-dimensional vector. Its coordinates define how much scaling is done in each direction. If both coordinates are equal, the scaling is uniform (isotropic) and the aspect ratio of the element is preserved (this is a homothetic transformation).
So you've got multiple things going on here, and unfortunately it's going to require various things between browsers as you tackle some of the nuances of the measure / arrange passes, anti-aliasing, hardware acceleration, perspective, etc...
.mtw {
max-width: 200px;
margin:0 auto;
}
.mt .mp { text-align: center }
.mt .mp .ma {
color: #fff;
font: 800 40px OpenSansBold, Arial, Helvetica, sans-serif;
min-height: 60px;
}
.mp { margin: 0 }
.mt .header-blue {
background: blue;
}
.mt {
transition: all 0.4s linear;
backface-visibility: hidden;
-webkit-font-smoothing: subpixel-antialiased;
}
.mt:hover {
z-index: 1;
-webkit-transform: scale(1.1) translate3d( 0, 0, 0) perspective(1px);
-moz-transform: scale(1.1) translate3d( 0, 0, 0) perspective(1px);
-o-transform: scale(1.1) translate3d( 0, 0, 0) perspective(1px);
-ms-transform: scale(1.1) translate3d( 0, 0, 0) perspective(1px);
transform: scale(1.1) translate3d( 0, 0, 0) perspective(1px);
}
/* --- cleaner way --- */
#boom {
color: #fff;
background-color: blue;
font: 800 40px OpenSansBold, Arial, Helvetica, sans-serif;
min-height: 60px;
max-width:200px;
margin:0 auto;
text-align: center;
transition: transform 0.4s linear;
backface-visibility: hidden;
-webkit-font-smoothing: subpixel-antialiased;
will-change: transform;
}
#boom:hover {
-webkit-transform: scale(1.1) translate3d( 0, 0, 0) perspective(1px);
-moz-transform: scale(1.1) translate3d( 0, 0, 0) perspective(1px);
-o-transform: scale(1.1) translate3d( 0, 0, 0) perspective(1px);
-ms-transform: scale(1.1) translate3d( 0, 0, 0) perspective(1px);
transform: scale(1.1) translate3d( 0, 0, 0) perspective(1px);
}
/* --- Another way --- */
#weee {
color: #fff;
background-color: blue;
font: 800 40px OpenSansBold, Arial, Helvetica, sans-serif;
min-height: 60px;
max-width:200px;
margin:0 auto;
text-align: center;
transition: font-size 0.4s linear;
backface-visibility: hidden;
-webkit-font-smoothing: subpixel-antialiased;
will-change: font-size;
}
#weee:hover {
font-size: 120px;
}
<div class="mtw">
<div class="mt">
<div class="header-blue">
<h2 class="mp">
<span class="ma">49</span>
</h2>
</div>
</div>
</div>
<br/><br/>
Or, cleaner way....
<div id="boom">50</div>
<br/><br/>
Or, an entirely different way...
<div id="weee">51</div>
So if we look through the changes, we see some things added...
backface-visibility: hidden;
= The user doesn't care about the back, remove it from the compositor consideration...
-webkit-font-smoothing: subpixel-antialiased;
= I'm sure the font is cool, but you re-try redrawing all the pixel specific shading crap on the fly smoothly....
translate3d( 0, 0, 0)
= 'ol hack to force hardware acceleration in some instances and let the gpu help out.
margin: 0
= on your h2 to remove the user agent margin garbage from consideration...
perspective(1px)
= Because you're transforming, remind it where home is...
Between these hopefully you should see the result you're expecting, hope it helps, cheers!
Oh, and just a quick PS: You don't need that many elements to accomplish the same thing (unless there's more to your example than what we see), I would try to shake that habit. One element and some text could deliver the same result with a cleaner DOM and less for the compositor thread to care about while doing its thing.
ADDENDUM; Eventually with scale
you're going to run into a resolution loss as it's resizing an elements dimensions and its children on a 2d plane with a rasterization. Avoiding blurry effect the larger something is scaled is inevitable (as far as I know today) unless you want refactor into say a canvas with zoom, or easier yet treat the instance for what it is and instead just target the font in this scenario since it's the only thing actually needing to stay legible. So see the added example, which is targeting font-size as a vector instead. Cheers!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With