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

如何实现div内图片hover时上移循环露出的悬停交互效果

悬停上滑切换效果实现方案

效果通用名称

这类动效没有统一的官方标准命名,前端业内通常称其为悬停上滑切换效果,部分资料也会按实现逻辑称其为溢出裁剪位移动画。你提到的目标站点按钮、菜单项的悬停动效,核心实现逻辑和这个完全一致,只是额外增加了斜切变形、缓动曲线微调的细节。

原有代码问题

  • 事件名写法错误:JS监听鼠标移入事件的事件名是mouseover,你写的onmouseover 多了on前缀还带多余空格,且没有编写鼠标移出后的状态还原逻辑
  • 结构缺失:要实现“当前元素上移移出、相同元素从下方补入”的效果,每个logo容器内需要放置2份相同的logo素材,外层容器必须做溢出隐藏,否则移动过程中的元素会外露
  • 动画逻辑缺失:仅添加类名没有编写对应的CSS过渡、位移规则,无法触发动效

正确实现方案

这个效果不需要编写JavaScript逻辑,纯CSS即可实现,性能比JS事件监听更好,交互稳定性更高。

实现原理

  1. 给每个logo外层容器设置固定高度,添加overflow: hidden属性,把超出容器范围的内容全部裁剪,作为动画的可视窗口
  2. 容器内放置2份完全相同的logo,默认状态下第一份显示在容器可视区域,第二份定位在容器正下方不可见
  3. 鼠标悬停时,两份logo同时向上做位移:第一份向上移出容器可视范围,第二份向上移动到第一份原来的位置,搭配平滑过渡动画即可实现目标效果

完整代码

CSS样式(替换你原有logo相关样式即可)

.logos-container{
    background: #ddd;
}
.logos-container .client-logo{
    width: 8rem;
    height: 3rem; /* 按照logo实际高度调整,必须设置固定高度 */
    position: relative;
    overflow: hidden;
}
.logos-container .client-logo img{
    width: 100%;
    height: 100%;
    object-fit: contain;
    position: absolute;
    left: 0;
    /* 缓动曲线和动画时长可自行调整,当前参数和目标站点效果接近 */
    transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
/* 默认状态:第一层logo在可视区,第二层在容器下方 */
.logos-container .client-logo img:nth-child(1){
    top: 0;
    transform: translateY(0);
}
.logos-container .client-logo img:nth-child(2){
    top: 0;
    transform: translateY(100%);
}
/* 悬停状态:两层logo同时上移100%,完成切换 */
.logos-container .client-logo:hover img:nth-child(1){
    transform: translateY(-100%);
}
.logos-container .client-logo:hover img:nth-child(2){
    transform: translateY(0);
}
.round-logo{
    width: 5rem !important;
}
.rect-logo{
    width: 14rem !important;
}

HTML结构调整

每个.client-logo容器内需要放2份相同的logo图片,修改后结构如下:

<div class="container logos-container d-flex justify-content-between align-items-center flex-wrap px-4 py-3">
    <div class="client-logo">
        <img src="https://cdn.worldvectorlogo.com/logos/nasa-6.svg" alt="NASA">
        <img src="https://cdn.worldvectorlogo.com/logos/nasa-6.svg" alt="NASA">
    </div>
    <div class="client-logo">
        <img src="https://cdn.worldvectorlogo.com/logos/microsoft.svg" alt="Microsoft">
        <img src="https://cdn.worldvectorlogo.com/logos/microsoft.svg" alt="Microsoft">
    </div>
    <div class="client-logo">
        <img src="https://cdn.worldvectorlogo.com/logos/ibm.svg" alt="IBM">
        <img src="https://cdn.worldvectorlogo.com/logos/ibm.svg" alt="IBM">
    </div>
    <div class="client-logo">
        <img src="https://cdn.worldvectorlogo.com/logos/dell-computer.svg" alt="Dell">
        <img src="https://cdn.worldvectorlogo.com/logos/dell-computer.svg" alt="Dell">
    </div>
    <div class="client-logo">
        <img src="https://cdn.worldvectorlogo.com/logos/hp-2.svg" alt="HP">
        <img src="https://cdn.worldvectorlogo.com/logos/hp-2.svg" alt="HP">
    </div>
    <div class="client-logo">
        <img src="https://cdn.worldvectorlogo.com/logos/coca-cola-6.svg" alt="Coca Cola">
        <img src="https://cdn.worldvectorlogo.com/logos/coca-cola-6.svg" alt="Coca Cola">
    </div>
</div>

自定义扩展说明

如果需要通过点击等非悬停事件触发动效,可以把CSS代码中的:hover替换为自定义类名(比如你之前写的.moveup),再通过JS控制类名的添加/移除即可。修正后的JS参考:

const logos = document.querySelectorAll('.client-logo')
logos.forEach(logo => {
  logo.addEventListener('mouseenter', () => logo.classList.add('moveup'))
  logo.addEventListener('mouseleave', () => logo.classList.remove('moveup'))
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 20:09:17