保持元素的边框半径不变的情况下缩放元素

huangapple go评论82阅读模式
英文:

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: &#39;&#39;;
	transition: transform 0.3s;
	transform-origin: top;
}

.hover:hover::after {
  border-radius: 8vmin/ 4vmin;
	transform: scale(1, 2)
}

<!-- language: lang-html -->

&lt;section&gt;
	&lt;div class=&#39;single-item&#39;&gt;&lt;/div&gt;
	&lt;div class=&#39;single-item hover&#39;&gt;&lt;/div&gt;
&lt;/section&gt;

<!-- 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: &#39;&#39;;
  width: 100%;
  height: 100%;
  transition: height 0.3s;
}

.hover:hover::after {
  height: 200%;
}

<!-- language: lang-html -->

&lt;section&gt;
	&lt;div class=&#39;single-item&#39;&gt;&lt;/div&gt;
	&lt;div class=&#39;single-item hover&#39;&gt;&lt;/div&gt;
&lt;/section&gt;

<!-- 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: &#39;&#39;;
    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 -->

&lt;section&gt;
	&lt;div class=&#39;single-item&#39;&gt;&lt;/div&gt;
	&lt;div class=&#39;single-item hover&#39;&gt;&lt;/div&gt;
&lt;/section&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年6月16日 09:28:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76486438.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定