鼠标悬停时宽度从0过渡到自动

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

Width transition from 0 to auto on hover

问题

我正在尝试在悬停后显示图标的按钮。

现在,当您在悬停状态下停留约2秒时,按钮似乎卡住了。

有人能修复这个问题吗?并尝试使它更流畅吗?

GIF: 鼠标悬停时宽度从0过渡到自动

.button {
  width: fit-content;
  height: fit-content;
  padding: 10px 15px;
  background-color: #323232;
  color: white;
  border-radius: 10px;
  align-items: center;
  justify-content: center;
  display: flex;
  cursor: pointer;
  position: relative;
  border: 1px solid #bdc3c7;
}

.button-text-container {
  order: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  overflow: hidden;
  width: 0;
  transition-duration: 1s;
  transition-property: max-width;
  transition-timing-function: ease-in-out;
  font-size: 1.5em;
  width: fit-content;
  max-width: 0;
}

.button-icon-container {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px;
  font-size: 1.6em;
}

.button:hover .button-text-container {
  max-width: 1275px;
}

.button-text-container>span {
  margin: 10px;
}
<div class="button">
  <div class="button-icon-container">icon</div>
  <div class="button-text-container"><span>test</span></div>
</div>
英文:

I'm trying to make the button that shows icon after hovering.

Now, the button seems to be stuck in hover when you stay ~2sec in hover state

Can anyone fix this? And try to make it smoother?

GIF: 鼠标悬停时宽度从0过渡到自动

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-css -->

.button {
  width: fit-content;
  height: fit-content;
  padding: 10px 15px;
  background-color: #323232;
  color: white;
  border-radius: 10px;
  align-items: center;
  justify-content: center;
  display: flex;
  cursor: pointer;
  position: relative;
  border: 1px solid #bdc3c7;
}

.button-text-container {
  order: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  overflow: hidden;
  width: 0;
  transition-duration: 1s;
  transition-property: max-width;
  transition-timing-function: ease-in-out;
  font-size: 1.5em;
  width: fit-content;
  max-width: 0;
}

.button-icon-container {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px;
  font-size: 1.6em;
}

.button:hover .button-text-container {
  max-width: 1275px;
}

.button-text-container&gt;span {
  margin: 10px;
}

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

&lt;div class=&quot;button&quot;&gt;
  &lt;div class=&quot;button-icon-container&quot;&gt;icon&lt;/div&gt;
  &lt;div class=&quot;button-text-container&quot;&gt;&lt;span&gt;test&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;

<!-- end snippet -->

答案1

得分: 4

使用CSS grid 来动画化auto高度/宽度

在将动画转换为max-width/height: "big-magic-number"unit;时的问题在于数字是魔法的。在定义的过渡期间返回到0需要时间。

使用max-width / max-height过渡走马灯是有缺陷的,设计上存在问题。

将宽度动画化为*"auto"*的解决方案:

更好的解决方案是使用CSS grid,如this answer中所解释的,基本上动画从0fr过渡到1fr

.button {
  display: inline-flex;
  align-items: center;
  padding: 10px 15px;
  background-color: #323232;
  color: white;
  border-radius: 10px;
  cursor: pointer;
  border: 1px solid #bdc3c7;
}

.button-slide {
  display: grid;
  grid-template-columns: 0fr;
  transition: grid-template-columns 0.4s ease-in-out;
  white-space: nowrap;
}

.button:hover .button-slide {
  grid-template-columns: 1fr;
}

.button-slide-inner {
  overflow: hidden;
}
<div class="button">
  <span class="button-icon">❤️</span>
  <div class="button-slide">
    <div class="button-slide-inner"><span>Heart space</span></div>
  </div>
</div>

总结一下,使用grid-template-columns来动画化*"宽度", 使用grid-template-rows来动画化"高度"*.

英文:

Animate auto height/width using CSS grid

The problem in animating to max-width/height: &quot;big-magic-number&quot;unit; lies exactly in the number being magic and big. Takes time to revert to 0 during a defined transition period.

Transitioning a carousel using max-width / max-height is flawed and broken by design.

Animate width to "auto" solution:

A better solution would be using CSS grid as explained in this answer, where basically the animation transitions from 0fr to 1fr

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-css -->

.button {
  display: inline-flex;
  align-items: center;
  padding: 10px 15px;
  background-color: #323232;
  color: white;
  border-radius: 10px;
  cursor: pointer;
  border: 1px solid #bdc3c7;
}

.button-slide {
  display: grid;
  grid-template-columns: 0fr;
  transition: grid-template-columns 0.4s ease-in-out;
  white-space: nowrap;
}

.button:hover .button-slide {
  grid-template-columns: 1fr;
}

.button-slide-inner {
  overflow: hidden;
}

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

&lt;div class=&quot;button&quot;&gt;
  &lt;span class=&quot;button-icon&quot;&gt;❤️&lt;/span&gt;
  &lt;div class=&quot;button-slide&quot;&gt;
    &lt;div class=&quot;button-slide-inner&quot;&gt;&lt;span&gt;Heart space&lt;/span&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

<!-- end snippet -->

To recap, use grid-template-columns to animate "width", and grid-template-rows to animate "height".

答案2

得分: 2

问题出在这一行:

max-width: 1275px;

基本上,在过渡期间发生的事情是基于设置的持续时间(在你的情况下是1秒),过渡属性值会不断变化。所以在你的情况下,max-width 从0变化到1275在1秒的时间段内。

如果过渡过早结束,也就是说,在1秒之前你把鼠标移出了,就会发生反向过渡,也就是 max-width 从那个时刻的任意值(比如说700)逐渐减小到0,所用的时间和从0变为700的持续时间相同。这个时间会比1秒短,因为你提前结束了它。

因为在你的代码中,视觉上的变化只在最初的短暂时期内可见,你会觉得你在元素内部停留的时间越长,你会得到越多的“延迟”体验。

你可以通过将过渡属性从 max-width 改为 width 来可视化 max-width 的变化。

.button-text-container {
  /* ... */
  transition-property: width;
  /* ... */
}

所以,解决方案是不要过渡 max-width(我不知道你为什么要使用它),也不要使用魔术数字,而是使用一个更好的解决方案,比如 这个

英文:

The problem is with this line:

max-width: 1275px;

Basically, what happens during transitions is based on the set duration (in your case, 1s), the transition property value keeps changing. So in your case, max-width gets changed from 0 to 1275 over 1s period.

If the transition ends prematurely, that is, if you move your mouse out before 1s, the reverse transition happens, that is, max-width starts decreasing from whatever value at that point (say, 700) to 0 over the exact same duration that changed it from 0 to 700. It will be less than 1s because you ended it prematurely.

And because in your code, the visual change is only visible for the initial brief duration, you think you experience that the more you have your mouse inside the element, the more "delay" you get.

You can visualize what's happening to max-width by changing your transition property from max-width to width.

<!-- begin snippet: js hide: true console: true babel: false -->

<!-- language: lang-css -->

.button {
  width: fit-content;
  height: fit-content;
  padding: 10px 15px;
  background-color: #323232;
  color: white;
  border-radius: 10px;
  align-items: center;
  justify-content: center;
  display: flex;
  cursor: pointer;
  position: relative;
  border: 1px solid #bdc3c7;
}

.button-text-container {
  order: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  overflow: hidden;
  width: 0;
  transition-duration: 1s;
  transition-property: width;
  transition-timing-function: ease-in-out;
  font-size: 1.5em;
  width: fit-content;
  width: 0;
}

.button-icon-container {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px;
  font-size: 1.6em;
}

.button:hover .button-text-container {
  width: 1275px;
}

.button-text-container&gt;span {
  margin: 10px;
}

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

&lt;div class=&quot;button&quot;&gt;
  &lt;div class=&quot;button-icon-container&quot;&gt;icon&lt;/div&gt;
  &lt;div class=&quot;button-text-container&quot;&gt;&lt;span&gt;test&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;

<!-- end snippet -->

So, the solution is to not transition max-width (I don't know why you used it) and use magic numbers but instead, use a better solution like this.

huangapple
  • 本文由 发表于 2023年7月13日 15:58:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76677151.html
匿名

发表评论

匿名网友

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

确定