- 前端
- UI组件
【免费下载链接】Metro-UI-CSS
A progressive front-end framework for creating high-performance responsive reactive web applications!
D-Menu 是 Metro UI CSS 框架中用于构建下拉菜单、上下文菜单与多级导航的核心组件。它以语义化的<ul>/<li>/<a>结构为基础,通过d-menu类与data-role="dropdown"属性的组合,即可快速实现带图标、快捷键、禁用项、分隔线与嵌套子菜单的完整菜单系统。读完本文,你将掌握 D-Menu 的全部 HTML 用法、插件参数、API 方法、事件体系与 CSS 变量定制方式,并能结合框架源码理解其定位与自动适配视口的底层原理。
组件定位与依赖
D-Menu 组件默认使用absolute 定位,专为下拉菜单场景设计。它可以独立使用(作为静态菜单列表),也可以与下拉功能结合,通过data-role="dropdown"属性变成可展开/收起的下拉菜单。该组件依赖以下模块:
- Metro UI Core:框架核心运行时;
- Dom:DOM 操作与事件绑定基础;
- Dropdown 组件:提供下拉展开、收起、点击外部关闭等交互能力(对应 source/components/dropdown/ 目录)。
在源码层面,D-Menu 的入口文件 index.js 仅导入同名样式,真正的交互逻辑全部由 Dropdown 组件(dropdown.js)承载,样式则由 d-menu.less 定义。理解这一分工,是后续排障与定制的前提。
基本菜单:五分钟上手
最简菜单
不依赖任何 JavaScript 初始化,仅靠 CSS 即可渲染一个静态菜单列表:
<ul class="d-menu"> <li><a href="#">Menu Item 1</a></li> <li><a href="#">Menu Item 2</a></li> <li><a href="#">Menu Item 3</a></li> </ul>图标、标题与快捷键
每个菜单项由<a>内嵌三个可选子元素构成:.icon(图标)、.caption(主标题)、.hotkey(快捷键提示):
<ul class="d-menu"> <li><a href="#"> <span class="icon mif-home"></span> <span class="caption">Home</span> <span class="hotkey">Ctrl+H</span> </a></li> <li><a href="#"> <span class="icon mif-cog"></span> <span class="caption">Settings</span> </a></li> </ul>从 d-menu.less 的源码可以看出其内部排版逻辑:菜单项<a>使用display: flex; align-items: center,.icon绝对定位于左侧(left: 8px; top: 5px; width/height: 16px),.hotkey通过margin-left: auto推挤到行的最右端,从而形成“左图标—中标题—右快捷键”的经典菜单布局。若菜单不含图标,可给<ul>追加.no-icon类,此时<a>的内边距会自动收窄(padding: 4px 10px)。
禁用项
给<li>添加.disabled类即可禁用菜单项:
<ul class="d-menu"> <li><a href="#">Enabled Item</a></li> <li class="disabled"><a href="#">Disabled Item</a></li> </ul>在样式上,.disabled会设置cursor: default与pointer-events: none,并强制文字颜色为--d-menu-item-color-disabled;在交互上,dropdown.js 还会为.disabled元素拦截 click 事件的默认行为与冒泡,确保点击不会触发菜单关闭或跳转。
分隔线
使用空的.divider列表项在菜单组之间插入分隔线:
<ul class="d-menu"> <li><a href="#">Item 1</a></li> <li><a href="#">Item 2</a></li> <li class="divider"></li> <li><a href="#">Item 3</a></li> </ul>.divider在 d-menu.less 中表现为height: 1px的水平线,颜色取--d-menu-divider-color,且不响应鼠标事件(pointer-events: none),避免误触发悬停高亮。
嵌套子菜单与定位控制
子菜单即嵌套下拉
在<li>内放置一个带data-role="dropdown"的嵌套<ul class="d-menu">,父级<a>加上.dropdown-toggle类,即可形成多级菜单:
<ul class="d-menu"> <li><a href="#">Item 1</a></li> <li> <a href="#" class="dropdown-toggle">Submenu</a> <ul class="d-menu"><!-- Right-aligned menu --> <ul class="d-menu place-right"> <!-- Menu items --> </ul> <!-- Right-aligned submenu --> <ul class="d-menu"> <li> <a href="#" class="dropdown-toggle">Submenu</a> <ul class="d-menu place-right"><ul class="d-menu">// Get the dropdown plugin instance const menu = Metro.getPlugin('#myMenu', 'dropdown'); // Open the menu menu.open(); // Close the menu menu.close(); // Toggle the menu menu.toggle();源码中open/close分别委托给_open/_close内部方法,toggle()则依据isOpen状态决定调用方向(dropdown.js)。也可使用Metro.makePlugin('#myDropdown', 'dropdown', { openMode: "down" })进行编程式初始化并同时传入参数。
事件体系
| 事件 | 说明 |
|---|---|
onDrop | 下拉菜单打开时触发 |
onUp | 下拉菜单关闭时触发 |
onDropdownCreate | 下拉创建完成后触发 |
事件可通过 data 属性绑定全局回调(data-on-drop="myHandler"),或在初始化参数中传入onDrop: function(){...}形式。源码层面,_open完成后依次触发open与drop事件,_close完成后依次触发close与up事件(dropdown.js),onDropdownCreate则在_create中触发dropdown-create事件时被调用。
用 CSS 变量定制菜单皮肤
D-Menu 的全部配色与圆角均由 CSS 变量控制,在浅色(默认)与暗色(.dark-side作用域)两套取值间自动切换:
| 变量 | 默认(浅色) | 暗色模式 | 说明 |
|---|---|---|---|
--d-menu-border-color | #e9e9e9 | #404959 | 菜单边框颜色 |
--d-menu-divider-color | #e9e9e9 | #404959 | 分隔线颜色 |
--d-menu-background | #ffffff | #2b2d30 | 菜单背景色 |
--d-menu-color | #191919 | #ffffff | 菜单文字颜色 |
--d-menu-item-color | #191919 | #dbdfe7 | 菜单项文字颜色 |
--d-menu-item-color-disabled | #ccc | #a8a8a8 | 禁用项文字颜色 |
--d-menu-item-color-hover | #000000 | #ffffff | 悬停项文字颜色 |
--d-menu-item-background-hover | #e8e8e8 | #1e1f22 | 悬停项背景色 |
--d-menu-dropdown-toogle-color | #191919 | #ffffff | 子菜单展开箭头图标颜色 |
--d-menu-shadow-color | #e1e1e1 | #191919 | 菜单阴影颜色 |
--d-menu-border-radius | 4px | 4px | 菜单圆角 |
这些变量在 d-menu.less 的:root与.dark-side块中定义,.d-menu的选择器直接引用var(--d-menu-*),因此在任意元素上覆盖变量即可局部换肤:
/* Custom styling for a specific menu */ .custom-menu { --d-menu-background: #f0f8ff; --d-menu-item-color: #0066cc; --d-menu-item-background-hover: #e6f2ff; --d-menu-item-color-hover: #0044aa; --d-menu-border-radius: 8px; }将.custom-menu类与d-menu同时作用于<ul>即可生效。此外,源码中还额外定义了--d-menu-title-color(菜单标题文字色)与.menu-title类——该标题项左侧显示文本、右侧自动延伸一条分隔线,可用于为菜单分区命名。
CSS 类速查
基础类
.d-menu— 下拉菜单的主类
定位类
.place-right— 菜单右对齐.place-right-{breakpoint}— 指定断点下的响应式右对齐.open-left— 子菜单向左展开
状态类
.open— 标记菜单处于打开状态(元素初始化时若带有此类,框架会在创建后自动展开,见 dropdown.js).disabled— 禁用菜单项.divider— 菜单项之间的分隔线
元素类
.caption— 菜单项文本容器.hotkey— 快捷键文本容器.icon— 菜单项图标容器.dropdown-toggle— 标记该菜单项带有子菜单
全局配置默认值
可通过Metro.dropdownSetup为所有下拉菜单设置全局默认参数,在页面脚本早期调用即可:
Metro.dropdownSetup({ align: "right", noClose: true, duration: 100 });源码中该方法会将传入对象合并进DropdownDefaultConfig(dropdown.js),之后创建的每个下拉实例都以该配置为默认值。此外,框架还支持通过全局变量globalThis.metroDropdownSetup在组件加载前注入配置(dropdown.js),适合在引入框架脚本时同步设定。
无障碍与最佳实践
为保证可访问性与可用性,官方文档建议:
- 使用语义化 HTML 结构(
<ul>、<li>、<a>)承载菜单,天然支持屏幕阅读器; - 为下拉菜单补充恰当的 ARIA 属性;
- 确保键盘导航可用(菜单项本身是可聚焦的链接,配合
.hotkey展示快捷键提示); - 为所有可交互元素提供可见的聚焦状态。
工程实践层面,还应注意:
- 菜单项文案保持简洁清晰;
- 用
.divider分隔相关功能组; - 图标风格保持一致以增强视觉识别;
- 为高频操作为配置
.hotkey快捷键提示; - 控制嵌套子菜单的层数,避免结构过深;
- 留意菜单定位,防止被视口边缘裁切——默认
openMode: "auto"已内置视口适配,若仍溢出可配合.place-right、.open-left或断点定位类手动校正。
参考示例与进一步探索
仓库中的 examples/d-menu.html 提供了一个完整的 IDE 风格右键菜单示例:包含图标(mif-codepen)、快捷键(Ctrl+F12、Alt+Shift+F12)、禁用项、.dropdown-toggle子菜单与.divider分隔线,展示了 D-Menu 在真实工具类产品中的典型形态,可作为直接复制改造的起点。想深入定制交互行为,可继续阅读 dropdown.js 与 dropdown.less 的全部实现。
- 前端
- UI组件
【免费下载链接】Metro-UI-CSS
A progressive front-end framework for creating high-performance responsive reactive web applications!
相关推荐
Metro UI CSS 水平菜单 h-menu 组件完全指南:导航栏构建、下拉子菜单与主题定制
Metro UI CSS 水平菜单 h menu 组件完全指南:导航栏构建、下拉子菜单与主题定制 h menu(Horizontal Menu)是 Metro
前端UI组件RSUITE 多级导航菜单实战:从 `Nav.Menu` 下拉菜单到嵌套子菜单的完整指南
RSUITE 多级导航菜单实战:从 Nav.Menu 下拉菜单到嵌套子菜单的完整指南 本指南以 rsuite 官方文档中"Multi level navigat
前端UI组件Ariakit Menu 组件实战指南:从 WAI-ARIA 菜单模式到可访问下拉菜单的实现
Ariakit Menu 组件实战指南:从 WAI ARIA 菜单模式到可访问下拉菜单的实现 Ariakit 的 Menu 是一套完整实现 WAI ARIA M
UI组件前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考