`用来在窄屏时挡住主内容区。折叠的核心就两招:要么用CSS的`transform: translateX(-100%)`把侧栏推出视口,要么用`width: 0`配合`overflow: hidden`把它挤没。前者动画更流畅,后者会破坏内部布局,所以主流方案都是前者。 ```html
``` CSS部分,侧栏默认`transform: translateX(-100%)`,加个`.open`类就归零。过渡用`transition: transform 0.3s ease`。遮罩层默认`opacity: 0`且`pointer-events: none`,打开时反过来。这里有个小坑——如果侧栏里放了`position: sticky`的子元素,父级`transform`会破坏它的固定效果,所以折叠后想要内部滚动条正常,得给侧栏单独设`overflow-y: auto`。 JS那边,别只会绑`click`事件。我见过有人把按钮和遮罩各绑一个监听器,结果遮罩出现时点击自己也会触发关闭,得靠`event.target`判断。更省事的写法是事件委托:给整个`document`绑一个`click`,判断`e.target`是否落在侧栏或按钮内,否则就收起。但这样有个副作用——如果侧栏内部有下拉菜单,点开菜单时也会误触关闭。所以最稳妥的,还是给按钮绑toggle,给遮罩绑单独的关闭,两者互不干扰。 ```javascript const sidebar = document.getElementById('sidebar'); const overlay = document.getElementById('overlay'); const btn = document.getElementById('toggleBtn'); btn.addEventListener('click', () => { sidebar.classList.toggle('open'); overlay.classList.toggle('show'); }); overlay.addEventListener('click', () => { sidebar.classList.remove('open'); overlay.classList.remove('show'); }); ``` 真正考验人的是响应式。桌面端侧栏可以常驻,只有窄屏才折叠。那就在媒体查询里设个断点,比如`min-width: 768px`时让侧栏始终`transform: none`,同时隐藏按钮和遮罩。但别忘了一件事——如果用户从手机旋转到横屏,侧栏还是折叠状态,得用`matchMedia`在断点切换时重置状态,否则会出现侧栏卡在中间的半开半合状态。 还有个细节容易被忽略:折叠后主内容区要不要跟着动?有些设计是侧栏覆盖在内容上,有些是推挤内容。前者适合移动端,后者适合桌面端。如果你要推挤效果,就得给主容器加`margin-left`过渡,侧栏宽度变化时同步调整。这个方案对性能要求高,频繁触发重排,最好用`will-change: margin-left`提示浏览器。 最后说点我自己的观察。很多人为了炫技,给折叠加了一堆弹性动画和延迟,结果用户点按钮后要等半秒才看到反应。折叠栏的核心是“快”——用户要么想快速找到导航,要么想快速回到内容区。我自己的习惯是`transition-duration`控制在0.2秒以内,超过0.3秒就感觉拖沓。还有,别把关闭按钮放在侧栏右上角的小叉号上,那位置拇指够不着。放底部或遮罩点击关闭,才是真顺手。 写这个功能,别一上来就套什么框架。原生JS加几十行CSS,比引入个jQuery插件或Vue组件轻量得多。那些组件库为了通用性,塞了一堆用不上的参数,最后你调样式的时间比写代码还长。自己写,虽然糙,但每个像素都心里有数。