Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is text getting blurry and wobbles during 2d scale transform

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>
like image 891
Un1 Avatar asked Jun 18 '18 16:06

Un1


2 Answers

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>
like image 69
Temani Afif Avatar answered Nov 08 '22 22:11

Temani Afif


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!

like image 25
arvie Avatar answered Nov 08 '22 22:11

arvie