请求开发者反馈:可自定义选择

多年来,开发者一直反映,设置 <select> 元素等表单控件的样式是他们最头疼的问题,我们一直在努力寻找解决方案。虽然这项工作很复杂,并且花了很长时间才完成,但我们即将推出这项功能。可自定义的 select 元素已正式进入 WHATWG第 2 阶段,在跨浏览器方面备受关注,您可以通过 Chrome Canary 130 测试原型。

欢迎试用并向我们提供反馈

检查您安装的 Chrome Canary 是否已更新到版本 130,以及实验性 Web 平台功能标志是否处于启用状态。如需启用此标志,请在地址栏中输入 chrome://flags,然后启用 #experimental-web-platform-features。然后,您应该能够看到本帖中的 CodePen 演示。或者,您也可以查看此 Codepen 集合,在一个位置查看所有这些示例。

您可以使用此表单提供有关该功能的反馈。只需 3 分钟即可完成!

我们来深入了解可自定义的 select API 的功能,该 API 基于现有的 HTML select 标记。

选择启用新版 <select>

如需选择启用新行为,请在页面内选择按钮和选择选择器上使用 CSS appearance 属性。如需选择启用,请在 <select> 元素和 ::picker(select) 上设置 appearance: base-select

::picker(select) 是用户代理提供的新伪元素,仅适用于已使用 appearance: base-select 选择启用新行为的 <select> 元素。此选择器伪元素是指由基本选择按钮触发的弹出式菜单。您可以同时选择启用这两项功能,如以下代码所示:

select,
::picker(select) {
  appearance: base-select;
}

您可以选择仅启用页内按钮,但不能仅启用选择器弹出式窗口而不启用页内按钮。仅在将 appearance: base-select 应用于 <select> 后才会创建 ::picker(select)

现在,您可以自定义选择元素了。新的可自定义选择器附带一些默认样式,这些样式在不同浏览器和操作系统中看起来都一样。下面是 macOS 版 Chrome 中默认自定义选择器与现有选择器的对比:

右侧可自定义选择项的默认用户代理样式。此价格可能会发生变化,我们非常期待收到您的反馈。
基本选择器与可自定义选择器的演示。

拆解各个部分

显示选择器各个部分的示意图。

进入新的可自定义选择模式后,您现在可以使用的新元素包括: - selectedoption:反映当前选定的选项的内部 HTML。 - option::before:包含一个对勾标记,用于指示当前选定的选项是默认的无障碍功能提供程序(此项可能会发生变化)。 - ::picker(select):包含可自定义选择器内 button 以外的所有内容的弹出式菜单。

您可以为选择器的任何部分设置样式。例如,您可以在 <option> 元素中添加任意非交互式内容,为用于打开选择下拉菜单的页面内按钮设置样式,并为选项下拉菜单(::picker(select))设置样式。

您还可以设置 button 的样式、自行提供箭头指示器,以及在任何元素内和周围添加任意内容。除了添加内容之外,您还可以隐藏任何这些新元素和默认样式。例如,如果您不希望在选项的 ::before 伪元素中显示指示器对勾标记,请使用以下 CSS。

/* Remove the default checkmark from the selected option */
option::before {
 display: none;
}

虽然选择器中可以包含无限数量的元素,但浏览器会将 <button> 元素之外的所有内容归入 ::picker(select) 伪元素,该伪元素的行为类似于锚定到按钮的弹出式窗口。此 <button> 会切换 ::picker(select)。直接位于选择器内的选项和其他元素将提升到 ::picker(select),或者您也可以提供自己的封装容器以进行样式设置。此封装容器也将放置在 ::picker(select) 伪元素内。

<select>
  <button>
    <selectedoption></selectedoption>
  </button>
  // Everything else that will go into the ::picker(select) popover
</select>

新的可自定义 <select> 使用弹出式窗口锚点定位功能。它是基于这两项底层技术构建的。这意味着,选择器中的下拉选项列表会充当一个悬停窗口,该悬停窗口锚定到用于打开选择器的触发器按钮。

您可以使用锚点定位来设置此 ::picker(select) 弹出式窗口的样式(包括将其锚定到其他元素)。这种内容模型还意味着,顶层动画样式可与选项列表搭配使用,以对进入和退出效果进行动画处理。

增强现有 <select> 元素

之前,Chrome 团队一直在研究 <selectlist> 元素的概念。本文介绍的是该功能经过重新设计,以便重复使用现有的 <select> 元素。

重复使用现有 <select> 元素的主要优势之一是能够逐步增强基本 HTML 元素。与全新元素相比,重复使用 <select> 仍会在您的页面上呈现有意义的内容。以下示例展示了自定义选择器与用户在不受支持的浏览器中看到的内容的对比:

option 中的所有文本内容均以选择元素的后备版本呈现。

基本样式

更改可能非常简单,例如更改选择元素的视觉样式。例如,更新按钮样式、悬停和聚焦样式,或选择选项的背景。选择启用 appearance: base-select 后,您可以将任何 CSS 应用于所选部分。

使用默认按钮更改选择器的各个部分的样式。

如需自定义箭头指示器,请在选择器中添加您自己的按钮和箭头。

<select>
  <button>
    <selectedoption></selectedoption>
    <span>
      // Arrow here
    </span>
  </button>
  // Everything else that will go into the ::picker(select) popover
</select>

然后,设置箭头的样式:

/* style the arrow */
button span {
  /* arrow styles */
  transition: rotate 0.2s;
}

/* adjust arrow styles when the picker is open */
select:open button span {
  rotate: -180deg;
}

选项中的复杂内容

您还可以进一步扩展,在 <select> 内的 <option> 元素中添加字符串以外的内容并为其设置样式。一个基本示例是在下拉菜单中在国家/地区名称旁边添加国旗图片。为此,请在选项文本旁边添加一个图片元素。

<option value="france">
  <img src="img/flag_of_france.svg" alt="" />
  <span>France</span>
</option>
带有国旗的国家/地区选择器。

更复杂的示例可能包括个人资料照片、姓名和其他信息,以帮助您决定在下拉菜单中选择哪个项目。

<option value="eur">
    <img src="euro-flag.png" alt="" />
    <div class="currency">
      <div class="currency-short">EUR</div>
      <div class="currency-long">Euro</div>
    </div>
    <div class="symbol" aria-hidden="true">€</div>
</option>
货币选择器的屏幕截图。

为所选选项设置样式

您可能希望所选选项在所选状态下的显示方式与在下拉菜单中的显示方式不同。例如,在 Gmail 界面中,为节省空间,系统会在用户选择某个选项后移除标签。为此,您需要钩入 <selectedoption> 元素以设置样式。<option> 包含以下所有标记:

 <option value="reply-all">
    <img class="material-symbol"  src="material-symbol-reply.png">
    <span class="text">Reply all</span>
  </option>

现在,对 <selectedoption> 内的 .text 应用 display: none,以隐藏文本内容并仅显示图标:

selectedoption .text {
  display: none;
}
Gmail 风格的选择,其中包含一个代表所选选项的图标。

互动选项

完全控制 ::picker(select) 的样式,在此之前的演示的基础上,使其在悬停和聚焦时具有交互性。在此演示中,新的 calc-size() 函数用于在选择器上方悬停或选择器包含焦点可见的选项时,让选择器的宽度从显示图标变为显示选项的完整宽度。

/* base styles when picker is open but not interacted with */
::picker(select) {
  width: var(--icon-width);
  transition: width 0.5s;
}

/* animate the text in on hover & focus */
::picker(select):hover,
select:has(option:focus-visible)::picker(select) {
  /*  auto width!  */
  width: calc-size(auto, size + 0.5rem);
}
交互式 Gmail 风格选择,在悬停或聚焦时逐步显示内容。

限制和无障碍功能说明

能力越大,责任也就越大。为确保内容可访问,此功能有一些限制。

  • 除了 <option> 元素之外,<select> 中还不允许放置任何互动(可聚焦)元素,例如按钮或其他元素。目前,建议的内容模型仅允许使用 <div><span><option><optgroup><img><svg><hr> 元素。
  • 分屏按钮目前处于实验阶段,我们正在努力制定一项无障碍解决方案。

随着这些体验的无障碍功能逐渐完善,内容模型预计也会扩展,变得更加灵活。

总结

我们很高兴看到此功能在工作组和标准机构的推动下不断发展,并在积极构建原型并评估此功能的形态时分享我们的进展。如果您遇到了运行不正常的情况,请告诉我们!

虽然此功能仍在开发中,但我们非常期待您通过简短的反馈表单提供反馈。

感谢您参与我们的工作,帮助我们确保一切顺利,让用户更轻松地在 Web 上构建无障碍的自定义表单控件!