background-transition with background-size: cover

Ilmiont picture Ilmiont · Dec 9, 2014 · Viewed 20.6k times · Source

This may already be answered somewhere but I haven't found yet after a bit of searching.

I have a series of divs with background-images. The size is set to background-size: cover.

But I want to be able to have the images zoom in and grow on hover. This transition doesn't work with the cover attribute it seems. Actually, the image zooms but without the transition effect. It goes instantly from "cover" to, in this case, 110%. It works fine when the original background-size was set as 100%.

But with this, on resizing the page the image seems to tile somewhat behind the div, which is not what I want. Cover keeps it central at all times, what I want.

Any advice appreciated on how to have a transition as it grows with cover or the same effect.

Ilmiont

Answer

Marcelo picture Marcelo · Dec 9, 2014

You can't use keywords (such as cover) when using CSS animations for background-size.

More info here: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties

Relevant text:

background-size - yes, as a repeatable list of a simple list of a length, percentage or calc(); when both values are lengths, they are interpolated as lengths; when both values are percentages, they are interpolated as percentages; otherwise, both values are converted into a calc() function that is the sum of a length and a percentage (each possibly zero), and these calc() functions have each half interpolated as real numbers. . This means keyword values are not animatable.

One approach to get this effect is to place element with the background image in a wrapping element with overflow hidden and apply a scale transform.

.wrapper { 
  width:300px;
  height:400px;
  overflow:hidden;
}
.image {
  background:url("http://placekitten.com/g/500/500");
  background-size:cover;
  width:100%;
  height:100%;
  transition: transform 2s;
}

.image:hover { transform:scale(1.1) }
<div class="wrapper">
  <div class="image"></div>
</div>