17

I want to make this card to scale on hover (including the elements inside it) but the text wobbles/jitters during the transformation (when you hover the card) and gets blurry during and after it's scaled (sometimes, with some ratios more than others, which I think is due to sub-pixel value rounding).

How do you remove that wobbling and blurriness during the transformation?

  • I don't care about IE browsers, I only want it to work in the latest Chrome.

  • It seems that it's caused by the transition property.

Codepen #1: https://codepen.io/x84733/pen/yEpYxX

.scalable {
  transition: 0.3s ease-in-out;
  box-shadow: 0 6px 10px rgba(0,0,0,0.14);
}
.scalable:hover {
  transform: scale(1.05);
  box-shadow: 0 8px 40px rgba(0,0,0,0.25);  
}

.card {
  width: 100%;
  background: white;
  padding: 20px;
}

body {
  width: 50%; 
  height: 100%; 
  background: #999;
  padding: 20px;
}
<div class="card scalable">
  <div>here's some description</div>
</div>

UPDATE:

I just found that when you animate it programatically, it doesn't wobble/jitter:

Can I use that somehow with JS?

Codepen: https://codepen.io/anon/pen/LqXwOb?editors=1100

.anim {
  animation: scale 0.3s ease-in-out infinite alternate;
}

@keyframes scale {
  to { transform: scale(1.05) }
}

.scalable {
  transition: 0.3s ease-in-out;
  box-shadow: 0 6px 10px rgba(0,0,0,0.14);
}
.scalable:hover {
  transform: scale(1.05);
  box-shadow: 0 8px 40px rgba(0,0,0,0.25);  
}

.card {
  width: 100%;
  background: white;
  padding: 20px;
}

body {
  width: 50%; 
  height: 100%; 
  background: #999;
  padding: 20px;
}
<div class="el anim card scalable">
  <div>here's some description</div>
</div>
Community
  • 1
  • 1
Un1
  • 3,874
  • 12
  • 37
  • 79
  • I don't know what's causing it. Have you tried setting backface-visibility: hidden, that works for me. – Countingstuff Dec 24 '18 at 23:20
  • @Countingstuff just tried adding this rule into the specified codepen, still doesn't work. Text gets blurry and wobbly during the transformation – Un1 Dec 25 '18 at 01:21
  • @Countingstuff has the right answer. Adding backface-visibility: hidden on both the class and the hover solves it! – Adrian Danlos Feb 14 '19 at 23:10
  • @AdrianDanlos it doesn't, it still wobbles during transformation and gets blurry after it's scaled, see this codepen: https://codepen.io/anon/pen/aXRdXV – Un1 Feb 14 '19 at 23:30
  • Damn u are right -_- – Adrian Danlos Feb 14 '19 at 23:33
  • It think this is because of font smoothing. The issue was there before CSS animations were a thing. – Salman A Feb 21 '19 at 12:32

2 Answers2

7

Instead of using scale you can consider a translateZ with a perspective. Make sure to define the perspective initially to avoid the bad effect when moving the cursor fast:

.scalable{
  transition: 0.3s ease-in-out;
  box-shadow: 0 6px 10px rgba(0,0,0,0.14);
  transform:perspective(100px);
}

.scalable:hover {
  transform:perspective(100px) translateZ(5px);
  box-shadow: 0 8px 40px rgba(0,0,0,0.25);  
}

.card {
  width: 100%;
  background: white;
  padding: 20px;
}

body {
  width: 50%; 
  height: 100%; 
  background: #999;
  padding: 20px;
}
<div class="card scalable">
  <div>here's some description</div>
</div>

One idea to reduce the blur effect is to start from the negative translate and then get back to 0:

.scalable{
  transition: 0.3s ease-in-out;
  box-shadow: 0 6px 10px rgba(0,0,0,0.14);
  transform:perspective(100px) translateZ(-5px);
}

.scalable:hover {
  transform:perspective(100px) translateZ(0px);
  box-shadow: 0 8px 40px rgba(0,0,0,0.25);  
}

.card {
  width: 100%;
  background: white;
  padding: 25px;
}

body {
  width: 50%; 
  height: 100%; 
  background: #999;
  padding: 20px;
}
<div class="card scalable">
  <div>here's some description</div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • 1
    Thanks, it works, but the text gets really blurry, mate – Un1 Feb 17 '19 at 11:39
  • By the way, how do I know that `100px` perspective is the value I need to use? Why not, let's say, `200px`? – Un1 Feb 17 '19 at 11:41
  • @Un1 yes , I am trying to figure out the blur ... for the value you can read this: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective .. it's a bit different from scale as it defined the distance from the object, so basically I set a distance equal to 100px then I moved 5px from it. So simply adjust the values to get close to the scale you want to achieve. – Temani Afif Feb 17 '19 at 11:45
  • @Un1 check the update, the second idea will probably reduce the blur effect – Temani Afif Feb 22 '19 at 14:51
  • Thanks, that works better. It still gets blurry on negative scale because `translateZ` turns the element into a texture and rasterizes it regardless of the direction. But if you use a font like `"Noto sans"` and bigger values like `-20px` it's almost imperceptible – Un1 Feb 22 '19 at 17:17
  • This kinda solves it but ...it inverses the problem, instead of being blurry in the middle of transition, gets blurry in the end and before, or always... the answer might be: there is no solution for this problem. maybe using SVGs is the only way??? idk but i´ll keep trying to find an answer to this problem... how to make text don´t change when animated? is there any way? – Yala Yala Herzlin Jan 17 '20 at 18:25
1

Also add the origin from 100% to 104%. This will prevent jumping and a blurry end result

.scalable {
  backface-visibility: hidden;
  transition: all 0.3s ease-in-out;
  transform-origin: 100% 104%;
}

.scalable:hover {
  backface-visibility: hidden;
  transform: scale(1.04);  
}

Cheers!

doğukan
  • 23,073
  • 13
  • 57
  • 69
arvie
  • 742
  • 1
  • 5
  • 9
  • Thanks for the code, mate, but the text still "wobbles" (jumps) during the transformation and is blurry in the end. I think it's because of the `transition` interpolation, even `linear` will give us the same result. (I'm using the latest Chrome): https://codepen.io/anon/pen/zeMVXQ – Un1 Feb 17 '19 at 10:24