Search code examples
htmlcsssvgcss-transforms

Problem of blurring background image (svg) while using scale on hover


I need to zoom image in on hover and focus. On hover from .9 to 1 and on focus from 1 to 1.2. The problem is that while scaling, the picture is blurry. No matter what size I start with, .9 or 1. I used two solutions:

transform: scale3d(.9, .9, .9);
transform: translateZ(0) scale (.9, .9);

But it didn't work (solution in snippet).

What am I doing wrong? Maybe there are other solutions?

.button {
  border: none;
  background-color: transparent;
  background-size: 100%;
  background-position: center;
  background-repeat: no-repeat;
  background-image: url('https://svgshare.com/i/FWE.svg');
  width: 28px;
  height: 36px;
  transition: transform .3s ease, background .3s ease, opacity .2s ease;
  box-shadow: none;
  will-change: transform;
  transform: scale3d(.9,.9,.9);
  transform: translateZ(0) scale(.9, .9);
}

.button:hover {
  cursor: pointer;
  transform: scale3d(1,1,1);
  transform: translateZ(0) scale(1, 1);
}

.button:focus {
  outline: none;
  transform: scale3d(1.2,1.2,1.2);
  transform: translateZ(0) scale(1.2, 1.2);
}
<button class="button">
</button>
<button class="button">
</button>


Solution

  • You could put the image into a pseudo element and transition the size of that element - that way you will always keep a sharp svg (seems a lot sharper than any of the other ways we discussed in the comments):

    .button {
      cursor: pointer;
      outline: none;
      border: none;
      width: 36px;
      height: 36px;
      background-color: transparent;
      box-shadow: none;
      position: relative;
    }
    
    .button:after {
      content: '';
      display: block;
      background: url('https://svgshare.com/i/FWE.svg') center center no-repeat;
      background-size: contain;
      width: 26px;
      height: 26px;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%,-50%);
      transition: all .15s linear;
    }
    
    .button:hover:after {
      width: 30px;
      height: 30px;
    }
    
    .button:focus:after {
      width: 34px;
      height: 34px;
    }
    <button class="button">
    </button>
    <button class="button">
    </button>