I am trying to scale an element on the Y-axis. The element has a border-radius of 20px. I am following this tutorial on how to scale an element while keeping its border-radius constant. The TLDR is that for the border to remain constant after scaling it, the border-radius has to be scaled as well. This works if you scale it without animating the transition, as shown in the article provided above. However, when animating it, the border-radius looks really bad during the transition.
Below is an example of this. The right side element in the example below is scaled by 2 vertically, and the border-radius is scaled as well to account for this. You can see the border-radius at the top does not remain constant during the animation and it looks quite jarring to my eye. I was wondering if there was a way to make the border-radius remain unchanged throughout the transition.
https://codepen.io/KR1S71AN/pen/qBQbgYR
Here is an example of this live too.
html {
height: 1000px;
}
.single-item {
position: relative;
margin: 0 auto;
width: 40vw;
height: 40vh;
display: inline-block;
}
.single-item::after {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
border-radius: 8vmin;
background: linear-gradient(#000, #f90);
content: '';
transition: transform 0.3s;
transform-origin: top;
}
.hover:hover::after {
border-radius: 8vmin/ 4vmin;
transform: scale(1, 2)
}
<section>
<div class='single-item'></div>
<div class='single-item hover'></div>
</section>
Instead of transform, which actually stretches your element, just change the height.
html {
height: 1000px;
}
.single-item {
position: relative;
margin: 0 auto;
width: 40vw;
height: 40vh;
display: inline-block;
}
.single-item::after {
position: absolute;
border-radius: 8vmin;
background: linear-gradient(#000, #f90);
content: '';
width: 100%;
height: 100%;
transition: height 0.3s;
}
.hover:hover::after {
height: 200%;
}
<section>
<div class='single-item'></div>
<div class='single-item hover'></div>
</section>
If you need to use transforms, the "more performant" (and non-JS) version would be to animate the border-radius as well. It's a bit wonky, but at least it's smooth.
html {
height: 1000px;
}
.single-item {
position: relative;
margin: 0 auto;
width: 40vw;
height: 40vh;
display: inline-block;
}
.single-item::after {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
border-radius: 8vmin;
background: linear-gradient(#000, #f90);
content: '';
transition: transform 0.3s, border-radius 0.3s;
transform-origin: top;
}
.hover:hover::after {
border-radius: 8vmin / 4vmin;
transform: scale(1, 2)
}
<section>
<div class='single-item'></div>
<div class='single-item hover'></div>
</section>