☰
Metro UI CSS D-Menu 组件实战指南:从下拉菜单到多级子菜单的完整实现
2026/10/7 2:34:04 网站建设 项目流程
  • 前端
  • UI组件

【免费下载链接】Metro-UI-CSS

A progressive front-end framework for creating high-performance responsive reactive web applications!

项目地址:https://gitcode.com/gh_mirrors/me/Metro-UI-CSS
点击查看免费下载

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-radius4px4px菜单圆角

这些变量在 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展示快捷键提示);
  • 为所有可交互元素提供可见的聚焦状态。

工程实践层面,还应注意:

  1. 菜单项文案保持简洁清晰;
  2. 用.divider分隔相关功能组;
  3. 图标风格保持一致以增强视觉识别;
  4. 为高频操作为配置.hotkey快捷键提示;
  5. 控制嵌套子菜单的层数,避免结构过深;
  6. 留意菜单定位,防止被视口边缘裁切——默认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!

项目地址:https://gitcode.com/gh_mirrors/me/Metro-UI-CSS
点击查看免费下载
上一篇:Blender UV编辑终极神器:UvSquares插件3分钟快速入门指南
下一篇:IronClaw 密封循环框架 ironclaw_agent_loop:执行器生命周期、密封策略组合与可恢复状态架构解析

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询