跳到主要内容
FormFlow

Safari 27 让原生 select 可自定义

Safari 27.0 于 9 月 16 日发布,带来可自定义样式的原生 select 和用于屏幕阅读器播报的 ariaNotify()。本文说明这对嵌入他人页面的表单意味着什么,以及它不决定什么。

本文由机器翻译。 阅读英文原文

A dark plate titled 'The native select grows up.' showing an open select with Choose one, Option A and Option B, and a callout reading ariaNotify() for the announced change.

Safari 27.0 于 2026 年 9 月 16 日发布。Apple 的发布说明列出构建版本 27.0 (20625.1.29),适用于 iOS 27、iPadOS 27、visionOS 27、macOS 27、macOS 26 和 macOS Sequoia。Web Standards 于 9 月 17 日发布的摘要统计了 83 项新功能。

这次发布广而不深:重写的 ES 模块加载器、亚像素级内联布局、无需开启的滚动锚定、service worker 静态路由 API,以及一长串无障碍修复。83 项功能中有两项决定了嵌入他人页面的表单可以假设什么:一个可以自定义样式的原生 select,以及一种不依赖实时区域的消息播报方式。

原生 select 现在可以自定义样式

select 元素一直是最难定制样式、也最常被替换的控件。可自定义 select 改变了这笔账。应用 appearance: base-select 会把元素切换到新的用户代理默认样式,并解锁其余能力。

select,
select::picker(select) {
  appearance: base-select;
}
  • ::picker(select) 瞄准弹层本身,::picker-icon 瞄准它的箭头。

  • ::checkmark 瞄准选中行上的标记。

  • selectedcontent 决定收起状态的控件为当前选项显示什么,因此摘要可以是标记,而不只是标签的副本。

  • option 现在可以包含 HTML,因此一个选项可以带图标或两行标签。

这些都没有取代控件本身。它仍然是真正的表单控件:键盘导航、屏幕阅读器语义、表单提交、约束校验和 change 事件都照常工作。用 div 重建的下拉菜单会丢弃这一切,再重建一个更差的版本。而选择 base-select 不会。

ariaNotify():不需要实时区域

Apple 的发布说明新增了对 ariaNotify API 的支持,它把文本排入队列,让屏幕阅读器播报,而不需要 ARIA 实时区域。对表单来说,这补上了一个具体的缺口。实时区域只在内容变化时发声,所以重复同一句话的错误摘要在第二次既不产生变化,也不产生播报。ariaNotify() 排队的是消息本身。

风险在于音量。播报不是校验消息。如果嵌入的表单在每次字段变化时都播报,屏幕阅读器用户会听到持续的旁白,然后离开页面。只播报用户必须处理的事:点按发送后第一个无效字段、没有成功送达的提交、刚刚打开的步骤。

嵌入表单该测什么

  • 收起状态下的 select 在长选项列表中的表现,浅色和深色模式都要看。

  • select 在生成组件自身布局中、宽 320px 时的表现。

  • 错误摘要只播报一次,而不是两次。

  • forced-colors 模式,因为 base-select 自带默认样式。

FormFlow 的生成组件渲染原生 HTML 表单控件,因此 Safari 的新默认样式可以不经我们做任何改动就影响到嵌入的表单。本文没有在 Safari 27 上验证生成组件,我们也不会暗示验证过。如果你要嵌入表单,请先在你支持的 Safari 版本中渲染它,再依赖默认外观。

这不决定什么

Safari 发布可自定义 select 并不意味着它已可互操作。Web Standards 的摘要说,新的默认设计已提交 CSS 工作组继续完善,而完全一致的起点取决于其他浏览器更新各自的实现。在 Safari 27 里看起来正确的样式,同一天在另一个引擎里可能看起来是错的。

ariaNotify() 是浏览器的增补,不是表单标准。它不决定哪些播报合适,也不取代标签、带 legend 的 fieldset,或字段旁的可见错误。

这里没有任何内容是 FormFlow 对 Safari 27 的支持声明,也没有改变嵌入表单在不提供这些功能的 Safari 版本中的行为。嵌入表单提交到的 POST 约定,请阅读 API 参考。