汉堡菜单滑入动画侧边栏超屏,存在横向滚动及滑出失效问题
问题修复方案
核心问题分析
- 横向滚动条:侧边栏通过
translate:100%移出屏幕,但浏览器仍会计算其水平占位,加上html/body未限制水平溢出,导致滚动条出现。 - 滑出动画失效:JS中通过
sidebar.style.opacity判断状态,但初始opacity是CSS类定义的,并非内联样式,导致判断逻辑错误,无法触发滑出动画。
1. 解决横向滚动条
给html和body添加overflow-x: hidden,隐藏水平方向超出视口的内容:
html, body { min-height: 100dvh; max-width: 100dvw; padding: 0; margin: 0; overflow-x: hidden; /* 新增:隐藏水平溢出 */ }
2. 修复滑出动画逻辑
改用CSS类切换控制侧边栏状态,避免内联样式判断的问题:
第一步:更新CSS,添加激活状态类
.sidebar { opacity: 0; transition: translate 0.5s ease-in, opacity 0.5s ease-in; /* 同时过渡两个属性 */ text-align: center; margin: 0; padding: 0; right: 0%; z-index: 1; position: absolute; translate: 100%; top: 0%; background-color: rgb(27, 27, 27); color: white; width: 300px; min-height: 100dvh; } /* 新增:侧边栏激活状态 */ .sidebar.active { opacity: 1; translate: 0; }
第二步:简化JS逻辑,切换类即可
function hamburguer_menu() { const sidebar = document.querySelector('.sidebar') // 切换active类,自动触发CSS过渡动画 sidebar.classList.toggle('active') }
3. 可选优化:汉堡按钮图标切换
给按钮添加菜单/关闭图标的切换效果,提升交互体验:
function hamburguer_menu() { const sidebar = document.querySelector('.sidebar') const menuIcons = document.querySelectorAll('.botao_hamburguer .material-symbols-outlined') sidebar.classList.toggle('active') // 切换图标显示状态 menuIcons.forEach(icon => { icon.style.display = icon.style.display === 'none' ? 'inline' : 'none' }) }
完整代码示例
HTML
<body> <heading id="layout_bar"> <h1 id="logo"><a href=""><span class="bigger">B</span>e<span class="bigger">B</span>etter</a></h1> <button type="button" onclick="hamburguer_menu()" id="botao_hamburguer" class="botao_hamburguer"> <span class="material-symbols-outlined icon-branco">menu</span> <span class="material-symbols-outlined icon-branco" style="display: none;">close</span> </button> </heading> <aside class="sidebar"> <ul style="list-style-type: none;"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> </ul> </aside> </body>
CSS
html, body { min-height: 100dvh; max-width: 100dvw; padding: 0; margin: 0; overflow-x: hidden; } #layout_bar { background-color: black; height: var(--heading_height); display: flex; flex-direction: row; justify-content: space-between; align-items: center; box-shadow: #000000a1 1px 0px 9px 0px; } .botao_hamburguer { background-color: pink; /* transparent; */ border: none; z-index: 2; } .sidebar { opacity: 0; transition: translate 0.5s ease-in, opacity 0.5s ease-in; text-align: center; margin: 0; padding: 0; right: 0%; z-index: 1; position: absolute; translate: 100%; top: 0%; background-color: rgb(27, 27, 27); color: white; width: 300px; min-height: 100dvh; } .sidebar.active { opacity: 1; translate: 0; }
JS
function hamburguer_menu() { const sidebar = document.querySelector('.sidebar') const menuIcons = document.querySelectorAll('.botao_hamburguer .material-symbols-outlined') sidebar.classList.toggle('active') menuIcons.forEach(icon => { icon.style.display = icon.style.display === 'none' ? 'inline' : 'none' }) }
内容的提问来源于stack exchange,提问作者Player Kay64
相关产品推荐
相关产品推荐

