跳到内容
+

模态框

Modal 组件允许你创建对话框、弹出框、灯箱和其他强制用户在继续之前采取操作的元素。

简介

Modal 是一个实用组件,它将其子组件渲染在背景幕布的前面。这允许你创建一个元素,用户必须与之交互才能在父应用程序中继续操作。

Modal 是一个较低级别的构造,用于以下 Material UI 组件中

组件

import { Modal } from '@mui/base/Modal';

以下演示展示了如何创建和样式化一个基本的模态框。点击打开模态框查看其行为

自定义

嵌套模态框

以下演示展示了如何在另一个模态框内嵌套一个模态框

过渡

你可以使用过渡组件为模态框的打开和关闭状态添加动画效果,只要该组件满足以下要求

  • 是 Modal 的直接子级后代
  • 具有一个 in prop——这对应于打开/关闭状态
  • 当进入过渡开始时调用 onEnter 回调 prop
  • 当退出过渡完成时调用 onExited 回调 prop

Modal 内置支持 react-transition-group

你也可以将 react-spring 与 Modal 一起使用,但这需要额外的自定义配置

性能

Modal 的内容在未打开时会被卸载。这意味着每次打开时都需要重新挂载。

如果你的 Modal 内部渲染了开销很大的组件树,并且你想要优化交互响应性,你可以通过启用 keepMounted prop 来更改此默认行为。

如果你想让模态框的内容对搜索引擎可用(即使在模态框关闭时),你也可以使用 keepMounted prop。

以下演示展示了如何应用此 prop 来保持模态框挂载

与任何性能优化一样,keepMounted prop 不一定能解决你所有的问题。在实施此 prop 之前,请探索其他可能的性能瓶颈,你可以在这些瓶颈上做出更显著的改进。

服务端模态框

React 不支持服务器端的 createPortal() API。

要显示在服务器上渲染的模态框,你需要使用 disablePortal prop 禁用 portal 功能,如下面的演示所示

局限性

溢出布局偏移

模态框在打开时通过在相关的滚动容器上设置 overflow: hidden 作为内联样式来禁用页面滚动,这会隐藏滚动条,从而影响页面布局。为了补偿此偏移并避免布局偏移,模态框还在滚动容器上设置了 padding 属性(正常情况下约为 15px)。

这可能会在使用 position: fixedposition: sticky 元素的场景下产生布局偏移。你需要在这些元素上添加 .mui-fixed 类名,以便模态框在禁用滚动时可以添加 CSS padding 属性。

<Box sx={{ position: 'sticky', right: 0, top: 0, left: 0 }} className="mui-fixed">

焦点陷阱

如果焦点试图逸出,模态框会将焦点移回组件的主体。

这样做是为了辅助功能,但它可能会给你的用户带来问题。

如果用户需要与页面的另一部分进行交互——例如,在父应用程序中打开模态框时与聊天机器人窗口进行交互——你可以使用 disableEnforceFocus prop 禁用默认行为。

Hook

import useModal from '@mui/base/unstable_useModal';

useModal hook 允许你将 Modal 的功能应用于完全自定义的组件。它返回要放置在自定义组件上的 props,以及表示组件内部状态的字段。

Hooks 不支持 slot props,但它们支持 customization props

以下演示展示了如何使用 useModal hook 构建与上面 组件 部分中找到的相同的 Modal

按下 Enter 键开始编辑

如果你使用 ref 来存储对根元素的引用,请将其传递给 useModalref 参数,如上面的演示所示。它将与 hook 内部使用的 ref 合并。

无障碍访问

有关无障碍访问最佳实践的完整详细信息,请参阅 关于对话框(模态框)模式的 WAI-ARIA 指南

  • 所有交互元素都必须具有 可访问的名称。使用 aria-labelledby="id..." 为你的 Modal 组件提供一个可访问的名称。你也可以使用 aria-describedby="id..." 来提供 Modal 的描述

    <Modal aria-labelledby="modal-title" aria-describedby="modal-description">
      <h2 id="modal-title">My Title</h2>
      <p id="modal-description">My Description</p>
    </Modal>
    
  • 遵循 WAI-ARIA 创作实践,以帮助你根据 Modal 的内容将初始焦点设置在最相关的元素上。