You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue+TailwindCSS实现隐藏项滑入时其他元素右移效果求助

问题描述

我有一个横向元素栏,希望其中一个元素默认隐藏,当鼠标悬停父容器时,该元素从左侧滑入,同时其他元素向右移动腾出位置。目前尝试使用负边距隐藏元素,但出现元素仍占位但显示空白的问题。

理想效果:

  • 默认状态:无左侧隐藏项显示,所有元素靠左排列
  • 悬停状态:隐藏项滑入,其他元素自动右移适配,且所有元素宽度未知

未悬停状态:
未悬停状态

悬停状态:
悬停状态

请问如何基于TailwindCSS结合Vue实现该最优效果?

当前尝试的代码:

<div class="sticky top-2 bg-gray-100 p-1 rounded-full shadow-sm hover:shadow-md inline-block opacity-90 hover:opacity-100 group overflow-hidden" v-show="!hideMe">
  <ul class="relative">
    <template v-for="item in props.items" :key="item.id">
      <li class="inline-block">
        <template v-if="item.hidden">
          <button @click="scrollTo(item)"
            class="transition-all -ml-[100%] group-hover:ml-0 py-1 px-2 text-sm text-gray-600 hover:text-white hover:bg-gray-400 rounded-full" >
            <component :is="item.icon" class="inline-block w-5 h-5 mr-1 -mt-0.5"/>
            <div class="inline-block">{{ item.name }}</div>
          </button>
        </template>
        <template v-else>
          <button @click="scrollTo(item)"
            class="py-1 px-2 text-sm text-gray-600 hover:text-white hover:bg-gray-400 rounded-full" >
            <component :is="item.icon" class="inline w-5 h-5 mr-1 -mt-0.5"/>{{ item.name }}
          </button>
        </template>
      </li>
    </template>
  </ul>
</div>
解决方案

之前用负边距-ml-[100%]的问题在于,元素本身仍占据宽度空间,只是视觉上被移出容器,导致出现空白占位。要实现无占位的隐藏+滑入效果,可通过弹性布局配合transform变换来实现,具体修改如下:

修改后的代码

<div class="sticky top-2 bg-gray-100 p-1 rounded-full shadow-sm hover:shadow-md inline-block opacity-90 hover:opacity-100 group overflow-hidden" v-show="!hideMe">
  <!-- 改用flex布局,自动适配元素宽度变化 -->
  <ul class="flex gap-1">
    <template v-for="item in props.items" :key="item.id">
      <li class="whitespace-nowrap"> <!-- 防止按钮内容换行,保证宽度计算准确 -->
        <template v-if="item.hidden">
          <button 
            @click="scrollTo(item)"
            class="transition-all duration-300 origin-left scale-x-0 opacity-0 group-hover:scale-x-100 group-hover:opacity-100 py-1 px-2 text-sm text-gray-600 hover:text-white hover:bg-gray-400 rounded-full"
          >
            <component :is="item.icon" class="inline-block w-5 h-5 mr-1 -mt-0.5"/>
            <span class="inline-block">{{ item.name }}</span>
          </button>
        </template>
        <template v-else>
          <button 
            @click="scrollTo(item)"
            class="py-1 px-2 text-sm text-gray-600 hover:text-white hover:bg-gray-400 rounded-full transition-all duration-300"
          >
            <component :is="item.icon" class="inline-block w-5 h-5 mr-1 -mt-0.5"/>
            <span class="inline-block">{{ item.name }}</span>
          </button>
        </template>
      </li>
    </template>
  </ul>
</div>

关键修改说明

  1. 父级<ul>改用flex布局:替换原relative属性,flex布局会让子元素自动横向排列,隐藏项展开时自动调整所有元素位置,完美适配未知宽度的元素。
  2. 隐藏项过渡逻辑:
    • 默认状态:scale-x-0(宽度收缩为0,不占据布局空间)、opacity-0(完全透明)、origin-left(以左侧为缩放原点,保证滑入方向正确)
    • 悬停状态:group-hover:scale-x-100(恢复原宽度)、group-hover:opacity-100(恢复可见)
    • 添加transition-all duration-300让过渡动画更平滑
  3. <li>添加whitespace-nowrap:避免按钮内文字换行,确保元素宽度计算精准。

备选位移滑入方案

若偏好位移而非缩放的滑入效果,可改用translate配合宽度控制:

<button 
  @click="scrollTo(item)"
  class="transition-all duration-300 translate-x-[-100%] w-0 opacity-0 group-hover:translate-x-0 group-hover:w-auto group-hover:opacity-100 py-1 px-2 text-sm text-gray-600 hover:text-white hover:bg-gray-400 rounded-full overflow-hidden"
>
  <component :is="item.icon" class="inline-block w-5 h-5 mr-1 -mt-0.5"/>
  <span class="inline-block">{{ item.name }}</span>
</button>

此方案默认状态下通过w-0让元素宽度为0,translate-x-[-100%]让元素向左移出,hover时恢复宽度与位置,同样实现无占位的滑入效果。

内容的提问来源于stack exchange,提问作者PixelPaul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 13:08:23