CSS accent-color

发布于 大漠

Web 开发者都有一个相同的共识,要在 HTML 表单元素上定制 UI 风格,相对而言是较为困难的。很多时候,开发者都是通过别的方式来的绕开原生表单控件的使用,比如使用非表单元素来模拟表单控件。这样做的唯一目的就是让表单控件能在各平台上达到相同的 UI 风格。这样做虽然能让表单控件 UI 风格达到一致性,但也会给我们的工作增加很多额外的工作量,除此之外,也会导致表单控件元素状态的样式被丢弃,以及内置的可访问性功能也会丧失。也就是说,要完全重现浏览器提供的功能,可能比你想要承担的工作要多。

如果说,能够直接有相应的 CSS 属性让开发者操作表单控件 UI是不是事情就会简单地多,开发者也可以从此避开用非表单控件元素来让表单控件更具个性化 UI。虽然到目前为止,我们还无法直接做到这一点,但 CSS 也在这方面做出很多的改变,比如说,我们现在可以直接使用 CSS 来控制表单元素的重点颜色(Accent Color),一种典型的明亮的颜色。这也就是我们今天要介绍的 CSS 的 accent-color 属性!

accent-color 简介

accent-color 属性是 CSS Basic User Interface Module Level 4 功能模块中 “美化控件”(Styling Widgets)中的一个属性。最早接触到这个属性是今年2月看到 @Adam Argyle 发的推

从这条推特的信息,知道使用 CSS 的 accent-color 可以用来给设置表单控件的高亮(重点颜色),并且可以让支持的终端达到一致的效果:

到目前为止,只有Chromium 93+ 和 Firefox 92+ 浏览器支持 accent-color属性

accent-color 使用

accent-color 使用非常简单,我们可以通过下面这几行代码,就可以定制化表单的控件颜色:

:root {
    accent-color: deeppink;
}

@media (prefers-color-scheme: dark) {
    :root {
        accent-color: hsl(328 100% 65%);
    }
}

上面示例展示了,accent-color属性和color-scheme一起使用的效果,允许开发者同时给亮色和深色元素着色。

有关于color-scheme属性更详细的介绍,可以阅读《系统偏好设置的那些事儿》一文。

通过上面的示例,我们对 accent-color 有了一个初体验。接下来,花点时间来探讨accent-color属性。

CSS 规范是这样描述 accent-color属性的

The accent-color CSS property allows the author to specify the accent color for user-interface controls generated by the element.

大致意思是:“accent-color属性允许开发者为该元素生成的用户界面控件指定重音色(高亮色)”。该属性语法规则:

accent-color: auto | <color>

其中auto是其初始值,代表一个 UA 选择的颜色,如果有的话,它应该与平台的重点颜色相匹配。也就是说,表单控件的重点颜色会根据客户端来着色。

另外一个值是<color>数据类型值,即 CSS 颜色中指定的值(有关于CSS颜色更多的介绍,可以阅读《图解CSS:CSS颜色》一文)。当accent-color的值为<color>值时,表示指定<color>作为accent-color的颜色,即指定表单控件重点颜色:

UA(客户端)应该使用指定的accent-color来绘制该元素的控制件的任何部分,否则就会用重点颜色进行美化。UA必须为控件的可读性保持对比,为了做到这一点,可以调整颜色的亮度或明度,或者在控件的其他部分进行颜色替换(例如,将叠加的字形从使用color切换到background-color)。它还可以为渐变色等生成颜色的变化,以使控件与平台上的重点颜色的使用惯例相匹配。

前面示例也向大家展示了 accent-color 的使用。简单地说,accent-color 可以简单地像下面这样使用:

:root {
    accent-color: hotpink
}

也可以将accent-color和 《系统偏好设置的那些事儿》一文提到的color-scheme结合使用:

:root {
    --color-accent: #ffcc00;
}

@media (prefers-color-scheme: dark) {
    :root {
        --color-accent: #880088;
    }
}

body {
    accent-color: var(--color-accent);
}

你可以按下面的方式来切换主题(亮色和暗色的切换):

你将看到亮色和暗色两个色系下的效果:

可用 accent-color 的元素

HTML中定义了很多种不同类型的表单控件,比如我们熟悉的inputselecttextarea等:

但到目前为止,只有四种表单控件可以通过accent-color属性对控件高亮颜色进行着色。这四种类型表单控件分别是:复选框(input type="checkbox"单选按钮(input type="radio"滑块(input type="range"进度条(progress。另外,@Adam Argyle 提供了常见表单控件使用 accent-color 属性测试用例,在这个测试用例中,支持accent-color 的控件可以看到重点颜色不再是系统默认的,比如accent-color的值为rgb(255, 0, 210)时效果:

我把示例搬到 Codepen 上:

点击示例顶部的颜色选择器,你可以看到accent-color改变之后,对应的复选框,单选按钮,滑块和进度条重点颜色的变化:

再来看一个简单的示例,使用accent-colorcolor-theme,为复选框、单选按钮、滑块和进度条为亮色和暗色设置不同的高亮着色:

.accented {
    accent-color: deeppink;
}

[color-scheme="dark"] .accented {
    accent-color: hsl(328 100% 80%);
}

[color-scheme="light"] {
    color-scheme: light;
}

[color-scheme="dark"] {
    color-scheme: dark;
}

fieldset[color-scheme="dark"] {
    background: Canvas;
    color: white;
}

保证着重色对比度

accent-color给控件设置着重色时可能会造成颜色对比度达不到 Web 可访问性的要求,即颜色对比度。换句话说,为了防止无法访问的元素存在,使用accent-color的浏览器需要确定一个合格的对比色,与自定义的着重色一起使用。下面是一张截图,展示了 Chrome 94(左)和Firefox 92 Nightly(右)在算法上的不同

从上图中可以看出,最重要的一点是要相信浏览器。提供一个品牌色,并相信它将为你做出明确的选择。

给更多的元素设置着重色

你可能会想,有没有办法为更多的控件着重色。庆幸的是,还是有一定方法可以的。比如我们可以给 焦点环选中文本高亮列表标记(::marker箭头指示器(仅Webkit)滚动条指示器(仅Firefox)

html { 
    --color-accent: hotpink;
    scrollbar-color: hotpink Canvas;
}

:root { 
    accent-color: var(--color-accent); 
}

:focus-visible { 
    outline-color: var(--color-accent); 
}

::selection { 
    background-color: var(--color-accent); 
}

::marker { 
    color: var(--color-accent); 
}

:is(
    ::-webkit-calendar-picker-indicator,
    ::-webkit-clear-button,
    ::-webkit-inner-spin-button, 
    ::-webkit-outer-spin-button
) {
    color: var(--color-accent);
}

小结

虽然 accent-color 还没有得到所有平台的支持,甚至支持的元素也还有限,但这是一种希望。在未来,我们可以为控件设置你想要的颜色,同时也能保持控件的可访问性。我想,不久的将来会得到更多平台的支持,更多元素上使用 accent-color 就可以设置高亮(或着重)色。