satgo1546’s ocean

Any sufficiently primitive magic is indistinguishable from technology.

慢报:popover=hint<dialog closedby=any>现已加入HTML标准

2014−2022
<dialog>
2023−2024
<div popover>
2025?
<div popover=hint><dialog closedby=any>

dialog和popover的现状乱成一锅粥,嫌趁热喝还不够的委员会上周又往锅里倒了点料:popover=hintPR)和closedby=anyPR)。这两个功能已于Chrome 133实装。

功能 浮于页面上方
top layer
焦点不可离开
focus trap
点击外部关闭
light dismiss
同屏上限一个
force-hide
用例
dialog.show() 没用
dialog.showModal() 模态对话框
popover=manual 没用
popover=auto 没用
popover=hint ← 新 没用
<dialog closedby=any> ← 新 弹出式菜单

popover=hint主要是为了解决多个popover=auto同屏只能出现一个的限制,但解决的方式是增加上限到两个——先开auto后开hint的情况可以共存,但多个hint不能共存,多个auto也不能共存,先开hint后开auto也不能共存。

虽然MDN和最初Open UI的explainer皆指出popover的用例包含命令菜单(action menu)和选项菜单(content picker),但是命令菜单应该捕获焦点,选项菜单应该在失去焦点时自动隐藏,popover没有提供这种能力,反而是dialog可以捕获焦点。而现在dialog又获得了点击外部关闭的能力,进一步挤压了popover的就业空间。

语义化语义化语义化无障碍无障碍无障碍

许多讲解dialog和popover的教程对它们的语义化与无障碍特性大做文章。因为效果相似,甚至有人通过无障碍来区分应该使用哪个。

Vasilis van Gemert在The UX of HTML中讲到,如果从链接和表单元素等普通人也能感知得到效果的元素入手,人们就更容易接受语义化确实能带来好处。另一方面,<section>这样的元素不仅显示效果和<div>没有区别,就连屏幕阅读器也不会有什么反应,人们就会对此嗤之以鼻。

如果一个功能只对无障碍设施有影响,那就一定会被滥用。如果两个功能只在无障碍设施上有区别,那就一定会被混淆。这样的功能是标准制定者的失职。

非模态的<dialog>元素除了可以通过脚本开闭以外没有独特性质,这本就可以通过脚本控制display: none来实现。非模态<dialog>存在的意义就像<article><aside>一样,是语义化垃圾。

虽然MDN指出<dialog popover>的存在是合理的,但是它只能作为dialog和popover之一显示,不能兼得两者特性,因此也是垃圾。

要真正贯彻落实无障碍建设,就必须全民受益,效果看得见。模态对话框就做得很好:视觉正常的用户可以看到::backdrop,依赖屏幕阅读器的用户可以听到对话框弹出,使用鼠标和触摸屏的用户点不了盖住的按钮,使用键盘的用户没法把焦点移到别处。每个用户都能感受到这个功能的效果,这样一来,即使不测试,视觉正常的开发者也能猜到屏幕阅读器的呈现效果。如果浏览器为视觉正常的用户也自动生成页内目录,互联网上滥用<h4>的情况想必能得到大幅改善。