Skip to main content
Inspiring
March 20, 2019
Answered

(CSS) Possible to easily animate changes to 'background-size' on hover/focus?

  • March 20, 2019
  • 3 replies
  • 20334 views

I'm using the following code to enlarge a background image (without exceeding the limits of the containing object).

a.item {

display: inline-block;

width: 300px;

height: 200px;

background-size: cover;

-webkit-transition: all .5s;

transition: all .5s;

}

a.item:hover {

-webkit-transition: all .5s;

transition: all .5s;

background-size: 110%;

}

I opted to do it this way because the transform:scale method (which auto-animates) apparently cannot be applied solely to a background image; as it will affect the whole container.

The downside of the background-size method is that it just jumps from one state to another in a single step (despite the addition of 'transition: all.5s' which I'd hoped would animate the tween, but seemingly has no effect whatsoever on latest FF/IE).

So the real question here is... is it even POSSIBLE to animate a change in 'background-size' or am I wasting my time trying?

This topic has been closed for replies.
Correct answer Jon Fritz

The issue you're running into with your transition code above is a fundamental part of the transition property in general. Transitions require there to be values between the first and second settings in order to move smoothly from one to the other.

"Cover" can't transition to "110%" because there are no values between those two settings, so it will simply snap from one to the next, seemingly ignoring the transition code.

3 replies

Brainiac
March 20, 2019

Not really sure what it is you are trying to do but test out the example code below:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Zoom Background</title>

<style>

.zoom-wrapper {

height: 200px;

width: 300px;

overflow: hidden;

}

.zoom {

background-image: url('fruits/apples.jpg');

background-size: cover;

height: 100%;

width: 100%;

transition: all .2s ease-in-out;

}

.zoom:hover {

transform: scale(1.2);

}

</style>

</head>

<body>

<div class="zoom-wrapper">

<div class="zoom">

</div>

</div>

</body>

</html>

Under S.Author
Inspiring
March 20, 2019

osgood_  wrote

Not really sure what it is you are trying to do

Pretty sure you start every comment you leave on my threads with those words I must not be as clear as I intend to be. I'll work on it.

osgood_  wrote

but test out the example code below:

That method requires 2 objects, I'm trying to do it with just one. The <a> tag would be the only object.

I just learned that targeting background-size alone for animation can be done successfully via animate+keyframes, but it's far from smooth compared to the transform:scale (so smooth it's almost relaxing).

So far, there is no other method that will animate 'background-size:cover'. However, as Jon Fritz II pointed out in the comment right after yours, the problem may be more 'cover' than 'background-size'. It would probably work if I use a percentage or fixed values, but I really like the flexibility advantages of 'cover' .

If these are the limitations at hand (at least until someone knee-deep in this stuff corrects us) then I will pick the lane that makes most sense for the UX (even if that means giving up on the zoom-in effect if it means losing the convenience of 'cover' -- it's just a cosmetic enhancement, anyway).

Thanks!

Brainiac
March 21, 2019

https://forums.adobe.com/people/Under+S.  wrote


osgood_   wrote

but test out the example code below:

That method requires 2 objects, I'm trying to do it with just one. The <a> tag would be the only object.

Not sure that using one extra container is really a deal breaker, maybe for you it is though. Seems to do the job I think you were asking for and works smoothly, zoom-in and zoom-out.

So was the final code solution you used post No. 3? That may be helpful to clarify for anyone else who comes across this post.

Under S.Author
Inspiring
March 20, 2019

I was able to do it with 'animation' -- literally nothing else worked for 'background-size'

In case anyone else is ever looking for the method :

a.item:hover,
a.item:focus {
background-size: 104%;
-webkit-animation-name: example; /* Safari 4.0 - 8.0 */
-webkit-animation-duration: .3s; /* Safari 4.0 - 8.0 */
animation-name: example;
animation-duration: .3s;
}

/* Safari 4.0 - 8.0 */
@-webkit-keyframes example {
  0%   {background-size: 100%;}
  100% {background-size: 105%;}
}

/* Standard syntax */
@keyframes example {
  0%   {background-size: 100%;}
  100% {background-size: 105%;}
}

It's not perfect (unlike "transform:scale" the animation here is more jagged) and I haven't gotten it to animate back down to the default state (but I'll figure it out)...

...ultimately however, it's the only method that was able to animate 'background-size' at all.

Jon Fritz
Jon FritzCorrect answer
Adobe Expert
March 20, 2019

The issue you're running into with your transition code above is a fundamental part of the transition property in general. Transitions require there to be values between the first and second settings in order to move smoothly from one to the other.

"Cover" can't transition to "110%" because there are no values between those two settings, so it will simply snap from one to the next, seemingly ignoring the transition code.

Under S.Author
Inspiring
March 20, 2019

https://forums.adobe.com/people/Jon+Fritz+II  wrote

The issue you're running into with your transition code above is a fundamental part of the transition property in general. Transitions require there to be values between the first and second settings in order to move smoothly from one to the other.

"Cover" can't transition to "110%" because there are no values between those two settings, so it will simply snap from one to the next, seemingly ignoring the transition code.

Thanks for the info.

If I have to choose between 'cover' and an animated zoom, I might just stick with 'cover'. The zoom was just a cosmetic nice-to-have, and then I got stubborn about figuring out why I couldn't get it working. Not sure how long it would've taken me to narrow it down to 'cover' without your aid.

Nancy OShea
Adobe Expert
March 20, 2019
Nancy O'Shea— Product User, Community Expert &amp; Moderator
Under S.Author
Inspiring
March 20, 2019

https://forums.adobe.com/people/Nancy+OShea  wrote

See if this helps

CSS Background image size transition - Stack Overflow

Looking at this more closely, it's the same method I'm using. The only difference I see is 1) they seem to feel using 'transition' on the default state is enough (I had it on hover/focus as well because why not) and 2) the number of failsafes they use as backup to 'transition' (for older browsers)

So I went ahead and made both those updates to my code :

a.item {
display: inline-block;
width: 300px;
height: 200px;
background-size: cover;
transition: all 1s;
-webkit-transition: all 1s ;
-o-transition: all 1s ;
-moz-transition: all 1s ;

}
a.item:hover,
a.item:focus {
background-size: 110%;
}

I even slowed the transition down from .5s to 1s in case it was just too fast for me to see but no, it still insta-jumps on FF+IE (no tween animation) Meanwhile, transform:scale DID animate elegantly (but applied to the entire container, when I'm trying to affect only the bg image).

(I wish I could combine the best parts of these two!)

EDIT: Nancy OShea Found the issue! I was using filter:saturate(70%) on this object via another class. Apparently, using a 'filter' of any kind on the default state blocks transition animations (on both IE+FF). Once I removed the filter:saturate(70%) from the object, it animated just fine with the above code.

EDIT(2) I spoke too soon! Filters animate properly once I removed 'saturate' from there. Background-size, however, still does not.