概览
尽可能使用按钮切换菜单。以下是使用 Bootstrap 按钮的示例:
<button class="btn-solid theme-primary" type="button" data-bs-toggle="menu" aria-expanded="false">
Toggle menu
</button>
<div class="menu">
<a class="menu-item" href="#">Menu item 1</a>
<a class="menu-item" href="#">Menu item 2</a>
<a class="menu-item" href="#">Menu item 3</a>
</div>菜单是可切换的、上下文相关的叠加层,用于显示链接列表及更多内容。它们通过包含的 Bootstrap 菜单 JavaScript 插件实现交互功能。它们通过点击切换,而不是通过悬停切换;这是一个有意的设计决定。
菜单是基于第三方库 Floating UI 构建的,该库提供动态定位和视口检测。使用包含 Floating UI 的 bootstrap.bundle.min.js / bootstrap.bundle.js,或通过 导入映射 单独引入 Floating UI。不过,在导航栏中菜单不会使用 Floating UI 进行定位,因为不需要动态定位。
示例
虽然 <button> 是菜单切换的推荐控件,但可能会有需要使用 <a> 元素的情况。如果使用,我们建议添加 role="button" 属性,以便向辅助技术(如屏幕阅读器)适当地传达控件的用途。
使用 按钮组 创建分割按钮菜单,当点击辅助按钮时显示菜单。
<a class="btn-solid theme-primary" href="#" role="button" data-bs-toggle="menu" aria-expanded="false">
Toggle menu
</a>
<div class="menu">
<a class="menu-item" href="#">Menu item 1</a>
<a class="menu-item" href="#">Menu item 2</a>
<a class="menu-item" href="#">Menu item 3</a>
</div>
<div class="btn-group">
<button type="button" class="btn-solid theme-secondary">Split</button>
<button type="button" class="btn-solid theme-secondary menu-toggle-split" data-bs-toggle="menu" aria-expanded="false">
<svg class="bi" width="16" height="16" aria-hidden="true"><use href="#chevron-expand" /></svg>
<span class="visually-hidden">Toggle menu</span>
</button>
<div class="menu">
<a class="menu-item" href="#">Action</a>
<a class="menu-item" href="#">Another action</a>
<a class="menu-item" href="#">Something else here</a>
<hr class="menu-divider">
<a class="menu-item" href="#">Separated link</a>
</div>
</div>深色菜单
通过在切换元素或其父元素上添加data-bs-theme="dark",选择更暗的菜单以匹配深色导航栏或自定义样式。
<div data-bs-theme="dark">
<button class="btn-solid theme-secondary" type="button" data-bs-toggle="menu" aria-expanded="false">
Menu button
</button>
<div class="menu">
<a class="menu-item active" href="#">Action</a>
<a class="menu-item" href="#">Another action</a>
<a class="menu-item" href="#">Something else here</a>
<hr class="menu-divider">
<a class="menu-item" href="#">Separated link</a>
</div>
</div>并将其用于导航栏:
<nav class="navbar" data-bs-theme="dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<ul class="navbar-nav">
<li class="nav-item" data-bs-theme="dark">
<button class="btn-solid theme-secondary" data-bs-toggle="menu" aria-expanded="false">
Menu
</button>
<div class="menu">
<a class="menu-item" href="#">Action</a>
<a class="menu-item" href="#">Another action</a>
<a class="menu-item" href="#">Something else here</a>
</div>
</li>
</ul>
</div>
</nav>半透明菜单
模糊并饱和菜单的背景,以使用 .menu-translucent 创建半透明效果。
<button class="btn-solid theme-secondary" type="button" data-bs-toggle="menu" aria-expanded="false">
Menu button
</button>
<div class="menu menu-translucent">
<a class="menu-item active" href="#">Active menu item</a>
<a class="menu-item" href="#">Menu item</a>
<a class="menu-item" href="#">Menu item</a>
<a class="menu-item" href="#">Menu item</a>
<a class="menu-item" href="#">Menu item</a>
<hr class="menu-divider">
<a class="menu-item theme-danger" href="#">Danger menu item</a>
</div>职位安排
在切换元素上使用 data-bs-placement 来控制菜单出现的位置。
- 物理位置:
top,bottom,left,right— 无论文本方向如何,方向固定。 - 逻辑位置:
start,end— 根据从右到左(RTL)自动翻转。在从左到右(LTR)模式下,start变为left,end变为right。在 RTL 模式下,它们交换。
所有布局都支持-start和-end对齐修饰符(例如,bottom-start,end-end)。
<button class="btn-solid theme-primary" type="button" data-bs-toggle="menu" data-bs-placement="bottom-start" aria-expanded="false">
Toggle menu
</button>
<div class="menu">
<button class="menu-item" type="button">Action</button>
<button class="menu-item" type="button">Another action</button>
<button class="menu-item" type="button">Something else here</button>
</div>响应式
使用响应式前缀在不同的断点更改位置。语法是 breakpoint:placement,其中断点可以是 sm、md、lg、xl 或 2xl。多个断点可以在单个属性中组合,使用空格分隔。
例如,data-bs-placement="bottom-start md:bottom-end lg:end-start"将会:
- 显示菜单于
bottom-start在小屏幕上(默认) - 切换到
bottom-end在md断点 - 切换到
right-start在lg断点
<button class="btn-solid theme-secondary" type="button" data-bs-toggle="menu" data-bs-placement="bottom-start md:bottom-end" aria-expanded="false">
Bottom start → md:bottom-end
</button>
<div class="menu">
<a class="menu-item" href="#">Action</a>
<a class="menu-item" href="#">Another action</a>
</div>
<button class="btn-solid theme-secondary" type="button" data-bs-toggle="menu" data-bs-placement="bottom lg:right" aria-expanded="false">
Bottom → lg:right
</button>
<div class="menu">
<a class="menu-item" href="#">Action</a>
<a class="menu-item" href="#">Another action</a>
</div>
<button class="btn-solid theme-secondary" type="button" data-bs-toggle="menu" data-bs-placement="top-end md:right-start xl:bottom-start" aria-expanded="false">
Multi-breakpoint
</button>
<div class="menu">
<a class="menu-item" href="#">Action</a>
<a class="menu-item" href="#">Another action</a>
</div>调整浏览器窗口大小以查看在不同断点上的位置变化。
菜单项
你可以使用 <a> 或 <button> 元素作为菜单项。
我们在文档示例中使用工具类来显示菜单,但在你自己的使用中并不强制要求。
<div class="menu show position-static">
<button class="menu-item" type="button">Action</button>
<button class="menu-item" type="button">Another action</button>
<button class="menu-item" type="button">Something else here</button>
</div>你也可以使用 .menu-text 创建非交互式菜单项。可以随意使用自定义 CSS 或文本工具进行进一步样式化。
<div class="menu show position-static">
<span class="menu-text">Menu item text</span>
<a class="menu-item" href="#">Action</a>
<a class="menu-item" href="#">Another action</a>
<a class="menu-item" href="#">Something else here</a>
</div>活跃
在菜单中的项目添加 .active 以将其样式设置为活动选择。要向辅助技术传达活动状态,请使用 aria-current 属性——对于当前页面使用 page 值,或对于集合中的当前项目使用 true 值。
<div class="menu show position-static">
<a class="menu-item" href="#">Regular link</a>
<a class="menu-item active" href="#" aria-current="true">Active link</a>
<a class="menu-item" href="#">Another link</a>
</div>残疾
在菜单中的项目上添加.disabled以将它们样式化为禁用。
<div class="menu show position-static">
<a class="menu-item" href="#">Regular link</a>
<a class="menu-item disabled" aria-disabled="true">Disabled link</a>
<a class="menu-item" href="#">Another link</a>
</div>变体
你可以使用 theme- 前缀将主题颜色应用到菜单项。
<div class="menu show position-static">
<a class="menu-item theme-primary" href="#">Primary link</a>
<a class="menu-item theme-secondary" href="#">Secondary link</a>
<a class="menu-item theme-success" href="#">Success link</a>
<a class="menu-item theme-danger" href="#">Danger link</a>
</div>
<div class="menu show position-static">
<a class="menu-item active theme-primary" href="#">Primary link</a>
<a class="menu-item active theme-secondary" href="#">Secondary link</a>
<a class="menu-item active theme-success" href="#">Success link</a>
<a class="menu-item active theme-danger" href="#">Danger link</a>
</div>图标
直接将 .menu-item-icon 添加到 <svg> 以向菜单项添加图标槽。
<div class="menu show position-static">
<button class="menu-item" type="button">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="menu-item-icon fg-3" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M4 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 5a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-1h1v1a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h1v1z"/>
</svg>
Copy
</button>
<button class="menu-item" type="button">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="menu-item-icon fg-3" viewBox="0 0 16 16">
<path d="M3.5 3.5c-.614-.884-.074-1.962.858-2.5L8 7.226 11.642 1c.932.538 1.472 1.616.858 2.5L8.81 8.61l1.556 2.661a2.5 2.5 0 1 1-.794.637L8 9.73l-1.572 2.177a2.5 2.5 0 1 1-.794-.637L7.19 8.61zm2.5 10a1.5 1.5 0 1 0-3 0 1.5 1.5 0 0 0 3 0m7 0a1.5 1.5 0 1 0-3 0 1.5 1.5 0 0 0 3 0"/>
</svg>
Cut
</button>
<hr class="menu-divider">
<button class="menu-item theme-danger" type="button">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="menu-item-icon" viewBox="0 0 16 16">
<path d="M6.5 1h3a.5.5 0 0 1 .5.5v1H6v-1a.5.5 0 0 1 .5-.5M11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3A1.5 1.5 0 0 0 5 1.5v1H1.5a.5.5 0 0 0 0 1h.538l.853 10.66A2 2 0 0 0 4.885 16h6.23a2 2 0 0 0 1.994-1.84l.853-10.66h.538a.5.5 0 0 0 0-1zm1.958 1-.846 10.58a1 1 0 0 1-.997.92h-6.23a1 1 0 0 1-.997-.92L3.042 3.5zm-7.487 1a.5.5 0 0 1 .528.47l.5 8.5a.5.5 0 0 1-.998.06L5 5.03a.5.5 0 0 1 .47-.53Zm5.058 0a.5.5 0 0 1 .47.53l-.5 8.5a.5.5 0 1 1-.998-.06l.5-8.5a.5.5 0 0 1 .528-.47M8 4.5a.5.5 0 0 1 .5.5v8.5a.5.5 0 0 1-1 0V5a.5.5 0 0 1 .5-.5"/>
</svg>
Delete
</button>
</div>描述
使用 .menu-item-content 创建弹性列布局,使用 .menu-item-description 在主标签下显示次要文本。
<div class="menu show position-static">
<button class="menu-item" type="button">
<span class="menu-item-content">
Publish now
<small class="menu-item-description">Make this page visible immediately</small>
</span>
</button>
<button class="menu-item" type="button">
<span class="menu-item-content">
Schedule
<small class="menu-item-description">Set a future publish date</small>
</span>
</button>
</div>已选择
将 .selected 添加到 .menu-item 以指示当前选择。
<button class="btn-solid theme-secondary" type="button" data-bs-toggle="menu" aria-expanded="false">Select status</button>
<div class="menu">
<button class="menu-item selected" type="button">
<div class="menu-item-content">
Selected menu item
<small class="menu-item-description">Currently visible to users</small>
</div>
<svg class="menu-item-check" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 16 16"><path d="m2 7 4 5 8-8"/></svg>
</button>
<button class="menu-item" type="button">
<div class="menu-item-content">
Default menu item
<small class="menu-item-description">Not yet published</small>
</div>
<svg class="menu-item-check" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 16 16"><path d="m2 7 4 5 8-8"/></svg>
</button>
</div>
<button class="btn-solid theme-secondary" type="button" data-bs-toggle="menu" aria-expanded="false">Select status</button>
<div class="menu">
<button class="menu-item" type="button">
Default menu item
<svg class="menu-item-check" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 16 16"><path d="m2 7 4 5 8-8"/></svg>
</button>
<button class="menu-item selected" type="button">
Selected menu item
<svg class="menu-item-check" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 16 16"><path d="m2 7 4 5 8-8"/></svg>
</button>
<button class="menu-item" type="button">
Default menu item
<svg class="menu-item-check" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 16 16"><path d="m2 7 4 5 8-8"/></svg>
</button>
</div>菜单内容
标题
在任何菜单中添加标题以标记操作的部分。
<div class="menu show position-static">
<a class="menu-item" href="#">Action</a>
<a class="menu-item" href="#">Action</a>
<h6 class="menu-header">Menu header</h6>
<a class="menu-item" href="#">Another action</a>
</div>分隔线
用分隔线将相关的菜单项分组。
<div class="menu show position-static">
<a class="menu-item" href="#">Action</a>
<a class="menu-item" href="#">Another action</a>
<a class="menu-item" href="#">Something else here</a>
<hr class="menu-divider">
<a class="menu-item" href="#">Separated link</a>
</div>文本
将任何自由形式的文本放在带有文本的菜单中,并使用 margin 和 padding 工具。请注意,你可能需要额外的尺寸样式来限制菜单宽度。
<div class="menu show position-static p-3 fg-2"
style="--bs-menu-min-width: 240px;">
<p>
Some example text that’s free-flowing within the menu.
</p>
<p class="mb-0">
And this is more example text.
</p>
</div>表格
在菜单中放置一个表单,或将其变成一个菜单,并使用 margin 和 padding 工具来为其提供所需的负空间。
<div class="menu show position-static"
style="--bs-menu-min-width: 300px;">
<form class="d-flex flex-column gap-3 p-3">
<div>
<label for="exampleMenuFormEmail1" class="form-label">Email address</label>
<input type="email" class="form-control" id="exampleMenuFormEmail1" placeholder="email@example.com">
</div>
<div>
<label for="exampleMenuFormPassword1" class="form-label">Password</label>
<input type="password" class="form-control" id="exampleMenuFormPassword1" placeholder="Password">
</div>
<div class="form-field">
<input type="checkbox" id="checkLabel" class="check" />
<label for="checkLabel">Example new checkbox</label>
</div>
<div class="vstack gap-2">
<button type="submit" class="btn-solid theme-primary">Sign in</button>
<a class="theme-secondary" href="#">New around here? Sign up</a>
<a class="theme-secondary" href="#">Forgot password?</a>
</div>
</form>
</div>可滚动菜单
将 --bs-menu-max-height 和 --bs-menu-overflow-y 自定义属性分配给菜单高度以限制其高度并启用滚动。
<div class="menu show position-static" style="--bs-menu-max-height: 145px; --bs-menu-overflow-y: auto;">
<button class="menu-item" type="button">Item 1</button>
<button class="menu-item" type="button">Item 2</button>
<button class="menu-item" type="button">Item 3</button>
<button class="menu-item" type="button">Item 4</button>
<button class="menu-item" type="button">Item 5</button>
<button class="menu-item" type="button">Item 6</button>
<button class="menu-item" type="button">Item 7</button>
<button class="menu-item" type="button">Item 8</button>
</div>你也可以使用 .menu-scrollable 类使菜单可滚动。这假设了一般安全的最大高度为 80dvh 并为你设置了溢出处理。
子菜单
使用 .submenu 包装类创建嵌套菜单。子菜单支持悬停和点击激活、键盘导航以及视口感知定位。在小屏幕上(低于 576px),子菜单会堆叠在父菜单上,并带有返回按钮,而不是向侧边展开。
将一个 .menu-item 触发器和一个嵌套的 .menu 包裹在一个 .submenu 元素中。
<button class="btn-solid theme-secondary" type="button" data-bs-toggle="menu" aria-expanded="false">
Submenus
</button>
<div class="menu">
<div class="submenu">
<button class="menu-item" type="button">File</button>
<div class="menu">
<a class="menu-item" href="#">New</a>
<a class="menu-item" href="#">Open</a>
<a class="menu-item" href="#">Save</a>
</div>
</div>
<div class="submenu">
<button class="menu-item" type="button">Edit</button>
<div class="menu">
<a class="menu-item" href="#">Cut</a>
<a class="menu-item" href="#">Copy</a>
<a class="menu-item" href="#">Paste</a>
</div>
</div>
<div class="submenu">
<button class="menu-item" type="button">View</button>
<div class="menu">
<a class="menu-item" href="#">Zoom In</a>
<a class="menu-item" href="#">Zoom Out</a>
</div>
</div>
<hr class="menu-divider">
<a class="menu-item" href="#">Preferences</a>
</div>嵌套
子菜单可以嵌套多层。每一层都会向侧面展开,当视口空间不足时会改变方向。
<button class="btn-solid theme-secondary" type="button" data-bs-toggle="menu" aria-expanded="false">
Multi-level menu
</button>
<div class="menu">
<a class="menu-item" href="#">Level 1 action</a>
<div class="submenu">
<button class="menu-item" type="button">Level 1 submenu</button>
<div class="menu">
<a class="menu-item" href="#">Level 2 action</a>
<div class="submenu">
<button class="menu-item" type="button">Level 2 submenu</button>
<div class="menu">
<a class="menu-item" href="#">Level 3 action A</a>
<a class="menu-item" href="#">Level 3 action B</a>
</div>
</div>
<a class="menu-item" href="#">Another level 2</a>
</div>
</div>
<a class="menu-item" href="#">Another level 1</a>
</div>菜单选项
使用 data-bs-offset 或 data-bs-reference 来更改菜单的位置。偏移量是与触发元素的距离(以像素为单位)。参考元素是用于参考菜单的元素。
<div class="d-flex">
<div class="me-1">
<button type="button" class="btn-solid theme-secondary" data-bs-toggle="menu" aria-expanded="false" data-bs-offset="10,20">
Offset
</button>
<div class="menu">
<a class="menu-item" href="#">Action</a>
<a class="menu-item" href="#">Another action</a>
<a class="menu-item" href="#">Something else here</a>
</div>
</div>
<div class="btn-group">
<button type="button" class="btn-solid theme-secondary">Reference</button>
<button type="button" class="btn-solid theme-secondary menu-toggle-split" data-bs-toggle="menu" aria-expanded="false" data-bs-reference="parent">
<svg class="bi" width="16" height="16" aria-hidden="true"><use href="#chevron-expand" /></svg>
<span class="visually-hidden">Toggle Menu</span>
</button>
<div class="menu">
<a class="menu-item" href="#">Action</a>
<a class="menu-item" href="#">Another action</a>
<a class="menu-item" href="#">Something else here</a>
<hr class="menu-divider">
<a class="menu-item" href="#">Separated link</a>
</div>
</div>
</div>自动关闭行为
默认情况下,单击菜单内部或外部时,菜单会关闭。你可以使用 autoClose 选项来更改菜单的此行为。
无论autoClose设置如何,当焦点位于菜单(其切换按钮或项目)内时,按下Esc会关闭菜单并将焦点返回到切换按钮。
<div class="btn-group">
<button class="btn-solid theme-secondary" type="button" data-bs-toggle="menu" data-bs-auto-close="true" aria-expanded="false">
Default menu
</button>
<div class="menu">
<a class="menu-item" href="#">Menu item</a>
<a class="menu-item" href="#">Menu item</a>
<a class="menu-item" href="#">Menu item</a>
</div>
</div>
<div class="btn-group">
<button class="btn-solid theme-secondary" type="button" data-bs-toggle="menu" data-bs-auto-close="inside" aria-expanded="false">
Clickable inside
</button>
<div class="menu">
<a class="menu-item" href="#">Menu item</a>
<a class="menu-item" href="#">Menu item</a>
<a class="menu-item" href="#">Menu item</a>
</div>
</div>
<div class="btn-group">
<button class="btn-solid theme-secondary" type="button" data-bs-toggle="menu" data-bs-auto-close="outside" aria-expanded="false">
Clickable outside
</button>
<div class="menu">
<a class="menu-item" href="#">Menu item</a>
<a class="menu-item" href="#">Menu item</a>
<a class="menu-item" href="#">Menu item</a>
</div>
</div>
<div class="btn-group">
<button class="btn-solid theme-secondary" type="button" data-bs-toggle="menu" data-bs-auto-close="false" aria-expanded="false">
Manual close
</button>
<div class="menu">
<a class="menu-item" href="#">Menu item</a>
<a class="menu-item" href="#">Menu item</a>
<a class="menu-item" href="#">Menu item</a>
</div>
</div>无障碍访问
WAI ARIA 标准定义了一个实际的 role="menu" 小部件,但这仅适用于触发操作或功能的类似应用程序的菜单。ARIA 菜单只能包含菜单项、复选菜单项、单选按钮菜单项、单选按钮组和子菜单。
另一方面,Bootstrap 的菜单被设计为通用的,可适用于各种情况和标记结构。例如,可以创建包含额外输入和表单控件的菜单,如搜索栏或登录表单。因此,Bootstrap 不会期望(也不会自动添加)任何 role 和 aria- 为真而需要的属性 咏叹调 菜单。作者将必须自己包含这些更具体的属性。
子菜单触发器是一个例外。Bootstrap 添加了 aria-haspopup="true" 给每个人 .submenu > .menu-item 包装一个嵌套的 .menu,并保持 aria-expanded 在子菜单打开和关闭时同步操作它。设置 aria-expanded 只有在子菜单必须默认展开时才自己操作。
键盘导航
菜单包括内置的键盘支持,用于导航菜单项。
| 键 | 操作 |
|---|---|
↓ / ↑ | 导航到下一个/上一个菜单项 |
→ | 进入子菜单(在从右到左布局中为 ←) |
← | 退出子菜单并返回上级菜单(在从右到左布局中为 →) |
Enter / Space | 激活聚焦项或打开子菜单 |
Esc | 关闭菜单 |
Home / End | 跳转到第一个/最后一个菜单项 |
Tab | 移动焦点并关闭菜单 |
CSS
变量
菜单在.menu上使用本地 CSS 变量以实现实时自定义。CSS 变量的值由每个组件独有的 Sass map生成,并应用于上述类。
$menu-tokens: defaults(
(
--menu-zindex: var(--z-menu),
--menu-gap: .125rem,
--menu-min-width: 10rem,
--menu-padding-x: .25rem,
--menu-padding-y: .25rem,
--menu-spacer: .125rem,
--menu-font-size: var(--font-size-sm),
--menu-color: var(--fg-body),
--menu-bg: var(--bg-body),
// --menu-border-color: var(--border-color-translucent),
// --menu-border-radius: var(--radius-7),
// --menu-border-width: var(--border-width),
--menu-box-shadow: var(--box-shadow-lg),
// --menu-max-height: none,
--menu-divider-bg: var(--border-color-translucent),
--menu-divider-margin-y: .125rem,
--menu-divider-margin-x: .25rem,
--menu-item-color: var(--menu-color, var(--fg-body)),
--menu-item-hover-color: var(--menu-color, var(--fg-body)),
--menu-item-hover-bg: var(--bg-1),
--menu-item-active-color: var(--primary-contrast),
--menu-item-active-bg: var(--primary-bg),
--menu-item-disabled-color: var(--fg-3),
--menu-item-gap: .5rem,
--menu-item-padding-x: .75rem,
--menu-item-padding-y: .25rem,
--menu-item-border-radius: var(--radius-5),
--menu-icon-size: 1rem,
--menu-description-font-size: var(--font-size-xs),
--menu-check-color: currentcolor,
--menu-header-color: var(--fg-3),
--menu-header-padding-x: .75rem,
--menu-header-padding-y: .25rem,
--menu-transition-property: "opacity, transform, display",
--menu-transition-duration: .15s,
--menu-transition-timing: var(--transition-timing-overlay),
),
$menu-tokens
);
菜单项至少包含一个未在 .menu 上设置的变量。这允许你在 Bootstrap 使用回退值的情况下提供一个新值。
--bs-menu-item-border-radius
用法
通过数据属性或JavaScript,菜单插件通过切换来切换隐藏内容(菜单) .show 关于……的课程 .menu. 这个 data-bs-toggle="menu" 该属性被用于在应用程序级别关闭菜单,因此最好始终使用它。
在触控设备上,打开菜单会添加空白 mouseover 处理程序到其直接子节点 <body> 元素。这个公认的丑陋的解决方法是为了规避一个问题而必须的 iOS 事件委托中的怪癖,否则会阻止在菜单外的任何地方点击触发关闭菜单的代码。一旦菜单关闭,这些额外的空 mouseover 处理器已被移除。
通过数据属性
在链接或按钮上添加data-bs-toggle="menu"以切换菜单。
| 属性 | 描述 |
|---|---|
data-bs-toggle="menu" | 在触发器上初始化菜单并连接全局关闭行为。 |
<button type="button" data-bs-toggle="menu" aria-expanded="false">
Menu trigger
</button>
<div class="menu">
...
</div>
通过 JavaScript
无论你是通过 JavaScript 调用菜单还是使用 data-api,菜单的触发元素都必须具有 data-bs-toggle="menu"。
通过 JavaScript 调用菜单:
const menuElementList = document.querySelectorAll('[data-bs-toggle="menu"]')
const menuList = [...menuElementList].map(menuToggleEl => new bootstrap.Menu(menuToggleEl))
要以编程方式打开、关闭或切换菜单,请从触发元素(带有 data-bs-toggle="menu" 的元素)获取其实例,然后调用相应的方法:
const menuToggleEl = document.querySelector('#myMenuToggle')
const menu = bootstrap.Menu.getOrCreateInstance(menuToggleEl)
menu.show()
menu.hide()
menu.toggle()
依赖项
如果你从源代码构建 Bootstrap 的 JS,菜单插件需要以下 JavaScript 文件:
| 文件 | 描述 |
|---|---|
js/src/menu.ts | 主菜单组件 |
js/src/base-component.ts | 基础组件类 |
js/src/dom/data.ts | 元素数据存储 |
js/src/dom/event-handler.ts | 事件处理工具 |
js/src/dom/manipulator.ts | 数据属性操作 |
js/src/dom/selector-engine.ts | DOM选择器工具 |
js/src/util/config.ts | 配置基类 |
js/src/util/floating-ui.ts | 响应式布局工具 |
js/src/util/index.ts | 核心实用功能 |
@floating-ui/dom | 第三方定位库 |
选项
由于选项可以通过数据属性或 JavaScript 传递,你可以将选项名称附加到 data-bs-,就像在 data-bs-animation="{value}" 中一样。确保在通过数据属性传递选项时,将选项名称的大小写类型从“camelCase”更改为“kebab-case”。例如,使用 data-bs-custom-class="beautifier" 而不是 data-bs-customClass="beautifier"。
所有组件都支持一个保留的数据属性 data-bs-config,该属性可以以 JSON 字符串的形式存放简单的组件配置。当一个元素具有 data-bs-config='{"delay":0, "title":123}' 和 data-bs-title="456" 属性时,最终的 title 值将是 456,并且单独的数据属性将覆盖在 data-bs-config 上给定的值。此外,现有的数据属性也可以存放像 data-bs-delay='{"show":0,"hide":150}' 这样的 JSON 值。
最终的配置对象是data-bs-config、data-bs-和js object合并的结果,其中最新提供的键值会覆盖其他键值。
| 名称 | 类型 | 默认 | 描述 |
|---|---|---|---|
autoClose | 布尔值,字符串 | true | 配置菜单的自动关闭行为:
|
boundary | 字符串,元素 | 'clippingParents' | 菜单的溢出约束边界(仅适用于 shift 中间件)。默认情况下它是 clippingParents 并且可以接受一个 HTMLElement 引用(仅通过 JavaScript)。有关更多信息,请参阅 Floating UI 的 交接文件. |
container | 字符串,元素,布尔值 | false | 在显示时将菜单附加到特定元素。使用 'body' 或者 true 附加到文档主体,这有助于逃脱容器 overflow: hidden隐藏时,菜单会移回到原来的位置。 |
display | string | 'dynamic' | 默认情况下,我们使用 Floating UI 进行动态定位。使用以下方法可以禁用它 static. |
offset | 数组,字符串,函数 | [0, 2] | 菜单相对于其目标的偏移量。你可以在数据属性中传递一个以逗号分隔值的字符串,例如: data-bs-offset="10,20"当使用函数来确定偏移量时,它会以一个包含位置、参考以及浮动矩形的对象作为第一个参数进行调用。触发元素的 DOM 节点作为第二个参数传入。该函数必须返回一个包含两个数字的数组:[skidding, distance]。欲了解更多信息,请参阅 Floating UI 的文档。 补偿文件. |
floatingConfig | null,对象,函数 | null | 要更改 Bootstrap 的默认 Floating UI 配置,请参阅 Floating UI 的配置当使用函数来创建 Floating UI 配置时,它会被一个包含 Bootstrap 默认 Floating UI 配置的对象调用。它帮助你使用并合并默认配置与自己的配置。该函数必须返回一个用于 Floating UI 的配置对象。 |
placement | string | 'bottom-start' | 菜单的放置。物理放置位置: 'top', 'bottom', 'left', 'right'. 逻辑位置(支持从右到左): 'start', 'end'。所有支持对齐修饰符: -start, -end. 支持响应式前缀,如 'bottom-start md:end'. |
reference | 字符串,元素,对象 | 'toggle' | 菜单的参考元素。接受以下值 'toggle', 'parent', 一个 HTMLElement 引用或提供对象 getBoundingClientRect. 有关更多信息,请参阅 Floating UI 的 虚拟元素文档. |
strategy | string | 'absolute' | 菜单的定位策略。使用 'absolute' 用于默认定位,或 'fixed' 转义包含...的容器 overflow: hidden. 有关更多信息,请参阅 Floating UI 的 战略文件. |
submenuTrigger | string | 'both' | 子菜单如何触发。使用 'click' 仅用于点击, 'hover' 仅用于悬停,或 'both' 用于点击和悬停激活。 |
submenuDelay | number | 100 | 在鼠标移出子菜单时关闭子菜单前的延迟毫秒数。为向子菜单的斜向鼠标移动提供宽限期。 |
使用带有 floatingConfig 的函数
const menu = new bootstrap.Menu(element, {
floatingConfig(defaultBsFloatingConfig) {
// const newFloatingConfig = {...}
// use defaultBsFloatingConfig if needed...
// return newFloatingConfig
}
})
方法
| 方法 | 描述 |
|---|---|
dispose | 销毁元素的菜单。(移除 DOM 元素上的存储数据) |
getInstance | 静态方法,允许你获取与 DOM 元素关联的菜单实例,你可以这样使用它: bootstrap.Menu.getInstance(element). |
getOrCreateInstance | 静态方法,返回与 DOM 元素关联的菜单实例,或者在未初始化的情况下创建一个新的菜单实例。你可以这样使用它: bootstrap.Menu.getOrCreateInstance(element). |
hide | 隐藏给定导航栏或标签导航的菜单。 |
show | 显示给定导航栏或标签页导航的菜单。 |
toggle | 切换给定导航栏或标签页导航的菜单。 |
update | 更新元素菜单的位置。 |
事件
所有菜单事件都会在切换元素上触发,然后向上传递。因此,你也可以在.menu的父元素上添加事件监听器。hide.bs.menu和hidden.bs.menu事件具有一个clickEvent属性(仅当原始事件类型为click时),其中包含点击事件的事件对象。
| 事件类型 | 描述 |
|---|---|
hide.bs.menu | 当调用 hide 实例方法时立即触发。 |
hidden.bs.menu | 当菜单已完成隐藏且 CSS 过渡完成后触发。 |
show.bs.menu | 当调用 show 实例方法时立即触发。 |
shown.bs.menu | 当菜单已显示给用户且 CSS 过渡完成后触发。 |
const myMenu = document.getElementById('myMenu')
myMenu.addEventListener('show.bs.menu', event => {
// do something...
})