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

如何实现平滑侧边栏鼠标悬停交互动画效果

侧边悬停导航跟随动画实现方案

这个交互用原生Web技术即可实现,不需要引入第三方动画库,核心是通过JS获取鼠标悬停元素的位置,驱动绝对定位的高亮块移动,配合CSS过渡实现平滑效果。


核心逻辑拆解

  • 导航容器固定在视口右侧,默认收起为窄条仅展示汉堡图标,鼠标移入时平滑拉宽展示完整导航文字
  • 导航容器内部放置一个绝对定位的高亮指示块,默认透明隐藏
  • 监听每个导航项的鼠标移入事件,实时计算当前悬停项相对于导航容器的偏移位置、自身高度,同步给高亮指示块
  • 鼠标移出整个导航区域时,高亮块平滑淡出回到初始隐藏状态
  • 所有尺寸、位置、颜色、透明度变化都通过CSS transition实现,保证动画流畅无卡顿

完整实现代码

HTML 结构

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>侧边导航交互动画</title>
</head>
<body>
    <nav class="side-nav">
        <!-- 汉堡菜单按钮 -->
        <div class="nav-toggle">
            <div class="toggle-bar"></div>
            <div class="toggle-bar"></div>
            <div class="toggle-bar"></div>
        </div>
        <!-- 导航项容器 -->
        <div class="nav-links">
            <!-- 跟随移动的高亮指示块 -->
            <div class="nav-indicator"></div>
            <a href="#" class="nav-item">work</a>
            <a href="#" class="nav-item">about</a>
            <a href="#" class="nav-item">pricing</a>
        </div>
    </nav>
    <script src="script.js"></script>
</body>
</html>

CSS 样式

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* 侧边导航基础样式 固定在右侧 */
.side-nav {
    position: fixed;
    right: 0;
    top: 0;
    height: 100vh;
    width: 70px;
    background: #efefef;
    display: flex;
    flex-direction: column;
    align-items: center;
    transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    overflow: hidden;
    z-index: 999;
}

/* 鼠标移入导航区域 展开宽度 */
.side-nav:hover {
    width: 120px;
}

/* 汉堡按钮样式 */
.nav-toggle {
    width: 100%;
    padding: 22px 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    cursor: pointer;
}

.toggle-bar {
    width: 34px;
    height: 4px;
    background: #121212;
    border-radius: 2px;
}

/* 导航项容器 */
.nav-links {
    position: relative;
    width: 100%;
    flex: 1;
    display: flex;
    flex-direction: column;
    padding: 20px 0;
}

/* 高亮指示块 绝对定位不干扰正常交互 */
.nav-indicator {
    position: absolute;
    left: 8px;
    right: 8px;
    height: 0;
    border-radius: 6px;
    background: #121212;
    opacity: 0;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    pointer-events: none;
}

/* 导航项样式 */
.nav-item {
    position: relative;
    width: 100%;
    padding: 18px 0;
    text-align: center;
    text-decoration: none;
    color: #121212;
    font-weight: 700;
    font-size: 1.3rem;
    text-transform: lowercase;
    transition: color 0.3s ease;
    z-index: 1;
}

/* 导航项悬停时文字反色 显示在高亮块上层 */
.nav-item:hover {
    color: #ffffff;
}

JS 逻辑

// 获取需要操作的DOM节点
const sideNav = document.querySelector('.side-nav');
const navIndicator = document.querySelector('.nav-indicator');
const navItems = document.querySelectorAll('.nav-item');

// 遍历所有导航项 绑定鼠标移入事件
navItems.forEach(item => {
    item.addEventListener('mouseenter', (e) => {
        const currentItem = e.currentTarget;
        // 获取元素相对于视口的位置信息
        const itemRect = currentItem.getBoundingClientRect();
        const navRect = sideNav.getBoundingClientRect();
        // 动态更新高亮块的位置和尺寸
        navIndicator.style.opacity = '1';
        navIndicator.style.height = `${itemRect.height}px`;
        navIndicator.style.top = `${itemRect.top - navRect.top}px`;
    })
})

// 鼠标移出整个导航区域时 隐藏高亮块
sideNav.addEventListener('mouseleave', () => {
    navIndicator.style.opacity = '0';
})

实现说明

  • 高亮块添加pointer-events: none属性,鼠标事件可以直接穿透到下层的导航项,不会出现交互阻断
  • 所有动画使用CSS过渡实现,由浏览器渲染层优化处理,比JS逐帧修改样式的性能表现更好
  • 导航项位置通过JS实时计算获取,后续增删导航项不需要额外修改逻辑代码,适配性更强
  • 所有动画的缓动函数、时长保持统一,视觉上不会有节奏割裂的感觉

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 05:33:16