如何在MaterializeCSS中实现Material.io的迷你可展开侧边栏?
问得好!咱们一步步来实现material.io上那种迷你变体侧边栏(包含仅显示图标的收起状态和显示完整文字的展开状态),用HTML、CSS和MaterializeCSS就能搞定,下面是完整方案:
实现核心思路
- 基于Materialize官方的
sidenav组件搭建基础框架 - 通过自定义CSS类控制两种状态:展开状态(默认显示图标+文字)和迷你状态(仅显示图标、隐藏文字)
- 用JavaScript监听切换事件,动态添加/移除自定义类实现状态切换
- 加入平滑过渡动画,让状态切换符合Material Design的动效规范
完整代码示例
HTML结构
先引入Materialize的依赖资源(注意Materialize依赖jQuery,需优先加载):
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- Materialize CSS --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"> <!-- Material Icons --> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <title>迷你变体侧边栏</title> <link rel="stylesheet" href="custom.css"> </head> <body> <!-- 桌面端侧边栏触发按钮 --> <a href="#" data-target="slide-out" class="sidenav-trigger show-on-large"><i class="material-icons">menu</i></a> <!-- 侧边栏主体 --> <ul id="slide-out" class="sidenav sidenav-fixed"> <!-- 侧边栏头部(可选) --> <li> <div class="user-view"> <div class="background"> <img src="https://picsum.photos/300/200"> </div> <a href="#user"><img class="circle" src="https://picsum.photos/100/100"></a> <a href="#name"><span class="white-text name">张三</span></a> <a href="#email"><span class="white-text email">zhangsan@example.com</span></a> </div> </li> <!-- 导航菜单项 --> <li> <a href="#!"> <i class="material-icons">dashboard</i> <span class="nav-text">控制台</span> </a> </li> <li> <a href="#!"> <i class="material-icons">person</i> <span class="nav-text">个人资料</span> </a> </li> <li> <a href="#!"> <i class="material-icons">settings</i> <span class="nav-text">设置</span> </a> </li> <li> <a href="#!"> <i class="material-icons">logout</i> <span class="nav-text">退出登录</span> </a> </li> <!-- 侧边栏内的状态切换按钮 --> <li class="sidenav-toggle-container"> <a href="#" id="toggle-mini"> <i class="material-icons">chevron_left</i> </a> </li> </ul> <!-- 主内容区域 --> <div class="main-content"> <h1>主内容区</h1> <p>滚动页面可以看到侧边栏保持固定位置</p> </div> <!-- jQuery --> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <!-- Materialize JS --> <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script> <script src="script.js"></script> </body> </html>
JavaScript(script.js)
初始化侧边栏并实现状态切换逻辑:
document.addEventListener('DOMContentLoaded', function() { // 初始化Materialize侧边栏 const sidenav = M.Sidenav.init(document.getElementById('slide-out'), { edge: 'left', inDuration: 300, outDuration: 225 }); // 获取切换按钮及相关元素 const toggleBtn = document.getElementById('toggle-mini'); const sidenavEl = document.getElementById('slide-out'); const toggleIcon = toggleBtn.querySelector('.material-icons'); const bodyEl = document.body; // 监听切换按钮点击事件 toggleBtn.addEventListener('click', function(e) { e.preventDefault(); // 切换侧边栏的迷你状态类 sidenavEl.classList.toggle('mini-sidenav'); // 切换body的类,用于调整主内容边距 bodyEl.classList.toggle('mini-sidenav-active'); // 切换图标提示当前状态 toggleIcon.textContent = sidenavEl.classList.contains('mini-sidenav') ? 'chevron_right' : 'chevron_left'; }); // 可选:迷你状态下点击页面其他区域不关闭侧边栏 document.addEventListener('click', function(e) { if (sidenavEl.classList.contains('mini-sidenav') && !sidenavEl.contains(e.target) && !e.target.classList.contains('sidenav-trigger')) { e.stopPropagation(); } }); });
自定义CSS(custom.css)
实现迷你状态样式和平滑过渡:
/* 主内容区域基础样式(适配展开状态侧边栏) */ .main-content { margin-left: 300px; padding: 20px; transition: margin-left 0.3s ease; } /* 迷你状态下的主内容边距调整 */ .mini-sidenav-active .main-content { margin-left: 70px; } /* 侧边栏基础样式 */ .sidenav { width: 300px; transition: width 0.3s ease; overflow: hidden; height: 100vh; } /* 迷你状态的侧边栏样式 */ .sidenav.mini-sidenav { width: 70px; } /* 迷你状态下隐藏导航文字 */ .sidenav.mini-sidenav .nav-text { display: none; } /* 迷你状态下隐藏头部文字信息 */ .sidenav.mini-sidenav .user-view .name, .sidenav.mini-sidenav .user-view .email { display: none; } /* 切换按钮固定在侧边栏底部 */ .sidenav-toggle-container { position: absolute; bottom: 20px; width: 100%; } .sidenav-toggle-container a { display: flex; justify-content: center; } /* 移动端适配:小屏幕自动取消迷你状态 */ @media only screen and (max-width: 992px) { .main-content { margin-left: 0; } .sidenav.mini-sidenav { width: 300px; } .sidenav.mini-sidenav .nav-text, .sidenav.mini-sidenav .user-view .name, .sidenav.mini-sidenav .user-view .email { display: block; } }
关键细节说明
- 状态切换核心:通过
mini-sidenav类控制侧边栏宽度和元素显示/隐藏,同时切换图标提示用户当前状态 - 平滑过渡:给侧边栏的
width和主内容的margin-left添加transition属性,让切换过程自然流畅 - 移动端兼容:在小屏幕上自动恢复侧边栏完整显示,符合响应式设计要求
- 固定侧边栏:使用Materialize的
sidenav-fixed类实现侧边栏随页面滚动固定的效果,和material.io的表现一致
内容的提问来源于stack exchange,提问作者shy_potato
相关产品推荐
相关产品推荐

