英文:
Width transition from 0 to auto on hover
问题
我正在尝试在悬停后显示图标的按钮。
现在,当您在悬停状态下停留约2秒时,按钮似乎卡住了。
有人能修复这个问题吗?并尝试使它更流畅吗?
.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?
<!-- 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>span {
margin: 10px;
}
<!-- language: lang-html -->
<div class="button">
<div class="button-icon-container">icon</div>
<div class="button-text-container"><span>test</span></div>
</div>
<!-- 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: "big-magic-number"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 -->
<div class="button">
<span class="button-icon">❤️</span>
<div class="button-slide">
<div class="button-slide-inner"><span>Heart space</span></div>
</div>
</div>
<!-- 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>span {
margin: 10px;
}
<!-- language: lang-html -->
<div class="button">
<div class="button-icon-container">icon</div>
<div class="button-text-container"><span>test</span></div>
</div>
<!-- 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论