英文:
Scaling an element while keeping its border radius constant
问题
我正在尝试在Y轴上缩放一个元素。该元素具有20像素的边框半径。我正在按照这个教程的步骤来缩放元素,同时保持其边框半径不变。简而言之,要使边框在缩放后保持不变,边框半径也必须进行缩放。如果您不使用过渡动画来缩放它,那么在提供的文章中已经有示例。但是,在进行动画过渡时,边框半径在过渡期间看起来非常不自然。
以下是一个示例。下面示例中的右侧元素垂直缩放了2倍,并且边框半径也进行了相应的缩放。您可以看到顶部的边框半径在动画过渡期间并没有保持不变,这对我的眼睛来说看起来很不协调。我想知道是否有办法在整个过渡期间使边框半径保持不变。
https://codepen.io/KR1S71AN/pen/qBQbgYR
以下是一个实际示例。
<!-- 开始代码段: js 隐藏: false 控制台: true babel: false -->
<!-- 语言: lang-css -->
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)
}
<!-- 语言: lang-html -->
<section>
<div class='single-item'></div>
<div class='single-item hover'></div>
</section>
<!-- 结束代码段 -->
英文:
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.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
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)
}
<!-- language: lang-html -->
<section>
<div class='single-item'></div>
<div class='single-item hover'></div>
</section>
<!-- end snippet -->
答案1
得分: 3
只需更改高度而不是使用transform,它实际上会拉伸您的元素。
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%;
}
如果您需要使用transforms,"更高性能"(且无需JS)的版本是同时动画化border-radius。这有点奇怪,但至少很平滑。
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);
}
英文:
Instead of transform, which actually stretches your element, just change the height.
<!-- begin snippet: js hide: true console: true babel: false -->
<!-- language: lang-css -->
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%;
}
<!-- language: lang-html -->
<section>
<div class='single-item'></div>
<div class='single-item hover'></div>
</section>
<!-- end snippet -->
Edit
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.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
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)
}
<!-- language: lang-html -->
<section>
<div class='single-item'></div>
<div class='single-item hover'></div>
</section>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论