实现带动画效果的响应式滑动侧边栏菜单
问题原因
你当前代码通过display: none/display: block控制元素显隐,该属性不支持CSS过渡效果,因此无法实现滑入、淡入淡出类动画。我们只需要把显隐逻辑改为 类名控制状态+transform/opacity属性过渡,就能实现所有需求,还能保证菜单、按钮动画时长完全同步。
原有HTML结构不需要做任何调整,直接替换CSS、JS对应部分即可生效。
实现代码
1. 修改后的CSS代码
保留你原有样式中导航项样式、hover效果、图片透明度等不涉及显隐动画的部分,把和定位、显隐相关的代码替换为以下内容:
/* 统一动画时长,所有动画元素共用保证同步 */ :root { --menu-anim-duration: 0.4s; } /* 菜单按钮容器统一固定定位,和内部图片位置重合 */ #openmenuicon, #closemenuicon { position: fixed; top: 85%; left: calc(50% - 32px); transition: opacity var(--menu-anim-duration) ease, visibility var(--menu-anim-duration) ease; } #openmenuicon { z-index: 295; opacity: 1; visibility: visible; } #openmenuicon.hidden { opacity: 0; visibility: hidden; } #closemenuicon { z-index: 305; opacity: 0; visibility: hidden; } #closemenuicon.visible { opacity: 1; visibility: visible; } /* 桌面端侧边栏:右侧滑入 */ @media only screen and (min-width: 769px) { #sidebar { position: fixed; width: 250px; height: 100%; right: 0; top: 0; padding-top: 0; background-color: rgba(15, 15, 15, 0.8); overflow: auto; z-index: 200; /* 初始状态:移出屏幕右侧,隐藏 */ transform: translateX(100%); visibility: hidden; transition: transform var(--menu-anim-duration) ease, visibility var(--menu-anim-duration) ease; } #sidebar.active { transform: translateX(0); visibility: visible; } #footerbackground { display: none; z-index: 5; } } /* 移动端侧边栏:底部滑入,footer无动画显隐 */ @media only screen and (max-width: 768px) { #sidebar { position: fixed; width: 100%; height: 413px; left: 0; bottom: 0; background-color: rgba(15, 15, 15, 0.8); overflow: auto; z-index: 200; /* 初始状态:移出屏幕底部,隐藏 */ transform: translateY(100%); visibility: hidden; transition: transform var(--menu-anim-duration) ease, visibility var(--menu-anim-duration) ease; } #sidebar.active { transform: translateY(0); visibility: visible; } #footerbackground { display: none; position: absolute; top: 115%; padding-top: 84px; height: 330px; bottom: 0; width: 100%; background-color: rgb(15, 15, 15); z-index: 5; } #footerbackground.show { display: block; } #navclosetransp { opacity: 0; } } /* 横屏小屏的按钮位置偏移保持原有逻辑 */ @media only screen and (orientation: landscape) and (max-width: 1024px) { #openmenuicon, #closemenuicon, #navmenutransp, #navmenutransp:hover, #navmenutranspbackground, #navmenutranspbackground2, #navclosetransp, #navclosetranspbackground { top: 78%; } } /* 原有导航项、按钮hover效果等其余样式全部保留即可 */
注意:需要把原有CSS中
#navmenutransp、#navmenutranspbackground、#navmenutranspbackground2、#navclosetransp、#navclosetranspbackground这几个图片元素上的position: fixed、top: 85%、left: calc(50% - 32px)属性删除,因为现在按钮父容器已经统一完成定位,避免定位冲突导致按钮位置偏移。
2. 修改后的JS代码
替换原有所有菜单相关JS逻辑即可:
// 全局标记菜单状态,无需每次读取DOM判断 let isMenuOpen = false; function multipleMenu() { isMenuOpen = !isMenuOpen; toggleSidebar(); swapButtons(); toggleFooterbackground(); } function toggleSidebar() { const sidebar = document.getElementById("sidebar"); sidebar.classList.toggle("active", isMenuOpen); } function swapButtons() { const openBtn = document.getElementById("openmenuicon"); const closeBtn = document.getElementById("closemenuicon"); openBtn.classList.toggle("hidden", isMenuOpen); closeBtn.classList.toggle("visible", isMenuOpen); } function toggleFooterbackground() { const footerBg = document.getElementById("footerbackground"); // 仅移动端处理footer显隐,桌面端默认隐藏 if (window.innerWidth <= 768) { footerBg.classList.toggle("show", isMenuOpen); } }
效果说明
- 桌面端点击按钮,侧边栏从右侧慢速滑入,打开按钮同步淡出、关闭按钮同步淡入,所有元素动画时长完全一致;再次点击触发反向动画收回菜单、切回打开按钮
- 宽度≤768px的小屏设备下,侧边栏自动改为从屏幕底部滑入,
#footerbackground元素无动画直接显示/隐藏,符合需求 - 所有动画通过CSS过渡实现,性能更优,不会出现元素显隐跳动的问题
- 如果需要调整动画速度,只需要修改
--menu-anim-duration变量的数值即可,数值越大滑入速度越慢
内容的提问来源于stack exchange,提问作者slidebar
相关产品推荐
相关产品推荐

