为什么需要将对话模态放置为身体的最后一个直接子代?[Accessibility,a11y]

问题描述

我正在研究如何在 React 中建立可访问的对话框模式。

我几乎没有消息来源建议将模式作为DOM的直接子代放置在DOM树的末尾 例如:https://assortment.io/posts/accessible-modal-component-react-portals-part-1 (请查找When rendered,the Modal is appended to the end of document.body.。)

我的问题是..为什么?这会带来什么好处? 如果我没记错的话,那么其中的一些消息来源就意味着,屏幕阅读器将以这种方式忽略身体的其他孩子,从而使用户不必专注于不需要的元素。

如果这是原因,这是建议的唯一方法吗? 我的想法是简单地将用户“诱捕”到模态内部,而不让他们专注于模态之外的其他任何事物。 我的想法是,如果用户位于模态的第一个或最后一个元素上并尝试前进或后退,他们仍将专注于模态的第一个或最后一个元素。使用JS。

因此,回到主要问题,为什么我应该将模式作为DOM的直接子代?谢谢!

解决方法

不一定是直接后代,您只需要将模式与其他内容分开 以便在打开模式时隐藏所有内容

这是您情况的详细说明: http://web-accessibility.carnegiemuseums.org/code/dialogs/

<body>
<!--    Add aria-hidden="true" if there is at least one pop-up window (Modal) -->
    <div class="page" aria-hidden="true">
        ...
    </div>
    <div class="dynamic-place">
        <div hidden role="dialog" aria-describedby="" aria-labelledby=""></div>
        <div hidden role="dialog" aria-describedby="" aria-labelledby=""></div>

        <!-- Only one active modal per page: -->
        <div role="dialog" aria-describedby="" aria-labelledby="">
            Active modal
        </div>
    </div>
</body>

,但您也可以执行以下操作: 要给除模式窗口aria-hidden = true以外的所有元素,没有人会强迫您将所有内容包装在一个块中(如第一个示例中所示),这只是一个简化此任务的建议

<body>
    <div aria-hidden="true">
        ...
    </div>
    <main aria-hidden="true">
        ...
    </main>
    <footer aria-hidden="true">
        ...
    </footer>

    <div class="dynamic-place">
        <div hidden role="dialog" aria-describedby="" aria-labelledby=""></div>
        <div hidden role="dialog" aria-describedby="" aria-labelledby=""></div>

        <!-- Only one active modal (opened) per page: -->
        <div role="dialog" aria-describedby="" aria-labelledby="">
            Active modal
        </div>
    </div>
</body>