在悬停时展开带有动画的按钮

Posted

技术标签:

【中文标题】在悬停时展开带有动画的按钮【英文标题】:On hover expand the button with animation 【发布时间】:2020-09-23 21:22:48 【问题描述】:

我在 bootstrap-vue 中创建了一个按钮,最初在其上显示一个右箭头图标,当悬停在上面时,它会扩展一些文本,一切正常,除了我的图标和文本相互粘连,所以我试图把一些边距,同时扩展按钮以在文本和图标之间添加一些空间,但是在悬停时,它会以一些小故障或不太顺利地关闭按钮,因为它试图回到无边距状态。 我的代码如下,实时代码在CodeSandbox

我的问题是有没有一种方法可以使 CSS 变得平滑?

<template>
<div>
    <b-card>
      <template v-slot:footer>
        <b-button id="buttonId" size="sm" pill variant="outline-info">
          <b-icon icon="arrow-right-circle" variant="danger"></b-icon>
          <span>View details</span>
        </b-button>
      </template>
    </b-card>
  </div>
</template>

<script>
export default ;
</script>

<style>
button span 
  max-width: 0;
  -webkit-transition: max-width 1s;
  transition: max-width 0.5s;
  display: inline-block;
  vertical-align: top;
  white-space: nowrap;
  overflow: hidden;

button:hover span 
  max-width: 7rem;
  margin-left: 0.3rem

</style>

【问题讨论】:

【参考方案1】:

虽然 Kamil 的解决方案非常聪明,但我发现如果您快速将鼠标悬停在按钮上而不让动画完成,您会看到奇怪的“弹出”,因为分隔符仅在 0.5 秒延迟后消失。

我尝试改用按钮和 span 的填充来实现类似的结果。

new Vue(
  el: '#app'
)
.details-button 
  padding-right: 0px !important; /* Remove default padding */


.details-button span 
  max-width: 0;
  display: inline-flex;
  white-space: nowrap;
  transition: max-width 0.5s, padding-right 0.45s; /* Transition width and padding to avoid "popping" */
  overflow: hidden;
  padding-left: 5px; /* Add default button padding */


.details-button:hover span, .details-button:focus span 
  max-width: 100px; /* how far the text can expand, adjust based on content */
  padding-right: 10px !important; /* Adds spacing on the right of the text when expanded */
<link href="https://unpkg.com/bootstrap@4.5.0/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/bootstrap-vue@2.15.0/dist/bootstrap-vue.css" rel="stylesheet" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue@2.15.0/dist/bootstrap-vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue@2.15.0/dist/bootstrap-vue-icons.js"></script>

<div id="app" class="p-5">
  <b-card>
    <template v-slot:footer>
      <b-btn class="details-button" size="sm" pill variant="outline-info">
        <b-icon icon="arrow-right-circle" variant="danger"></b-icon>
        <span>Read more</span>
      </b-btn>
    </template>
  </b-card>
</div> 

【讨论】:

没想到,它更流畅,因为这一切都发生在一个过渡中,您需要维护的代码更少。【参考方案2】:

编辑

查看Hiws解决方案,它需要的代码更少,不需要额外的元素,效果很完美。

原答案

查看this fork of your CodeSandbox。

基本上,您可以创建一个分隔图标和文本的跨度,而不是在文本上添加边距

<b-button id="buttonId" size="sm" pill variant="outline-info">
  <b-icon icon="arrow-right-circle" variant="danger"></b-icon>
  <span class="separator"/>
  <span class="text">View details</span>
</b-button>

然后玩一点 CSS(我已经评论了所有更改的内容)

button .text  /* added class to distinct between text and separator */
  max-width: 0;
  transition: max-width 0.5s;
  display: inline-block;
  vertical-align: top;
  white-space: nowrap;
  overflow: hidden;


button:hover .text  /* as above */
  max-width: 7rem;
  transition-delay: 0.1s; /* The transition must wait until separator expands itself */


button .separator 
  display: inline-block;  /* Default span's display type is `inline` which ignored width changes */
  width: 0;               /* Initially it's hidden */
  transition: width 0.1s; /* Probably you will want to adjust this setting. The important part is, keep it in sync with transition-delay on .text  */
  transition-delay: 0.5s; /* Wait until .text .text 'shrinking' has ended. This is overridden if the button is hovered. Ofc keep it in sync with .text transition-duration */


button:hover .separator 
  width: 0.3em;             /* that's the 'margin' width */
  transition-delay: unset;  /* If the button is hovered, we don't want to wait with the transition at all. */

时间可以改进,但整体机制很好。

【讨论】:

试试Hiws解决方案,看起来更好更简单

以上是关于在悬停时展开带有动画的按钮的主要内容,如果未能解决你的问题,请参考以下文章

使用 :after 元素对按钮的悬停效果 - 当鼠标超出按钮尺寸时动画出来

如何通过将鼠标悬停在同一页面上的图像上来触发 CSS 动画按钮

CSS3菜单展开,悬停消失

JS动画在悬停时旋转

在悬停按钮 CSS 动画后面放置正确格式的图像

动画按钮从一个点到另一个点