Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I scale a div without scaling its casted box-shadow in a performant way?

I'm using a transform scaleY animation on a div, to animate its hegiht cheaply, but it doesn't work very well when there is a box-shadow applied to it.

div {
    width: 300px;
    height: 100px;
    transform: scaleY(1);
    transition: all 2000ms;
    transform-origin: 0 0;
    background-color: yellow;
    box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14),
                0 1px 10px 0 rgba(0, 0, 0, 0.12),
                0 2px 4px -1px rgba(0, 0, 0, 0.4);
}
div:hover {
    transform: scaleY(5);
}
<div></div>

jsbin.com demo

You can see the box-shadow gets scaled too. Not only that, but it snaps at the end of the animation, which looks ugly.

Any suggestions on how to keep this a quick 60fps transform animation while not scaling the shadow? Animating the height gets the desired effect but it lags A LOT on mobile.

Already tried

Applying the shadow to a div::after pseudo-element and transforming the div doesn't work as the shadow is also scaled.

like image 402
doplumi Avatar asked Oct 29 '22 21:10

doplumi


1 Answers

You'd have to use another element here. Using transform on element affects its children and :after, :before pseudo elements. Shadow has to be in element above in order for this to work using transform. You could try using scaleY(1) and scale(-X) in pseudo selectors but that would not be reliable.

div {
    width: 300px;
    height: 100px;
    
    z-index: 1;
    position: relative;
    box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14),
                0 1px 10px 0 rgba(0, 0, 0, 0.12),
                0 2px 4px -1px rgba(0, 0, 0, 0.4);
}
div span {
    transform: scaleY(1);
    transition: all 2000ms ease;
    transform-origin: 0 0;
    background-color: yellow;
    display: block; 
    width: 300px; height: 100px;
} 
div:hover span {
    transform: scaleY(5);
}
<div><span></span></div>
like image 99
Loji Avatar answered Nov 15 '22 05:11

Loji