Simplifying Form Styles With `accent-color`
I don’t know about you, but I love it when new CSS properties arrive that make our daily lives as developers simpler and enable us to remove a whole lot of redundant code.
aspect-ratio is one such property (recently eliminating the need for the padding hack).
accent-color just might be the next.
Let’s take checkboxes. In every browser, these are styled differently by the user agent stylesheet (responsible for the browser’s default styles).
Historically there hasn’t been any real way to style these inputs. Instead, many web developers resort to a well-known hack, which involves visually (but accessibly) hiding the input itself, then styling a pseudo-element on the label. (All this applies to radio buttons too.)
A pretty cool feature is that the browser will automatically determine the best color for the checkmark to ensure sufficient color contrast, using its own internal algorithms. That means no extra code styling is required to ensure our checkboxes are as accessible as they can be.
In the following demo, we’re applying two different accent colors. If you view this in Chrome, you should see that the checkmark of the one on the left is white, while the one on the right is black. Browsers use different algorithms for this, so you may experience different results in Chrome versus Firefox.
We can use
color-scheme to ensure that our checkboxes take on a light or dark style according to preference. Setting it on the root element in our CSS ensures that it applies to the whole page:
color-scheme: light dark;
This expresses the color schemes in order of preference. Alternatively we could implement it using a meta tag in our HTML:
<meta name="color-scheme" content="light dark">
This is actually preferable, as it will be read by the browser immediately before the CSS file is parsed and executed — therefore could help us avoid a flash of unstyled content (FOUC).
In our rainbow checkbox demo, you might notice that the browser also adjusts the color of some of the checkmarks when we switch the color scheme, while still maintaining sufficient contrast. Pretty cool!
color-scheme affects the user agent styles. If we use it without providing other background color or text color styles for the page, the default colors of the page will be inverted if the user selects a dark color scheme — so the default background color will be black, and the text color will be white. In practice, it’s quite likely we’ll want to override these with CSS. We can use
color-scheme alongside the
prefers-color-scheme media query. In this demo, I’m using
prefers-color-scheme to set the text color only when a dark scheme is preferred.
See the Pen accent-color with color-scheme by Michelle Barker.
color-scheme can also be set on individual elements, which is useful if there are some areas in our design that we want to retain a specified color scheme, regardless of whether light or dark mode is toggled. In this demo, we have a form with a dark background even when the overall color scheme is light. We can specify a dark color scheme, to ensure our checkboxes are styled with a dark color at all times:
See the Pen accent-color – showing two different colours by Michelle Barker.Limitations
As mentioned, there are several elements that are not currently affected by
accent-color, for which this functionality would be useful. Another consideration is that we’re currently limited to only styling the checked state of the checkbox or radio button — aside from using
color-scheme, which has some effect on the checkbox border, but doesn’t allow for full customization. It would be great to be able to style the border color and thickness for the input in its unchecked state or implement even more custom styling, such as changing the overall shape, but we’re not quite there yet. At the very least, allowing the checkbox border to inherit the body text color would be preferable.
It would also be useful to be able to extend the use of
accent-color to other elements beyond forms, such as video controls. Currently for a developer to create custom controls entails a significant amount of work in order to re-create the accessibility of native ones. This excellent article by Stephanie Stimac details the work being done by Open UI to standardize UI elements in order to make it easier for developers to style them.
An alternative way to style a checkbox or radio button is to hide default styling with
-webkit-appearance: none and replace it with a background image. (See this demo.) Modern browsers support this pretty well, but it has its limitations when compared to the first method of using a pseudo-element (described at the start of this article), as we can’t directly manipulate the background image with CSS (e.g. changing its color or opacity), or transition the image.
The CSS Paint API — part of the Houdini set of CSS APIs — opens up more options for customization, allowing us to pass in custom properties to manipulate a background image. Check out this lovely demo (and accompanying worklet) by Matteo. Support is currently limited to Chromium browsers.
We should take care to provide accessible focus styles when using hiding the default appearance of form controls. An advantage of
accent-color is that it doesn’t hide the browser defaults, preserving accessibility.
accent-color is currently supported in the latest versions of Chrome and Edge. It can be enabled in Firefox with the
layout.css.accent-color.enabled flag, and is due to be supported in the next release. Unfortunately, there is no Safari support at present. That’s not to say you can’t start using it right away — browsers that don’t support
accent-color will simply get the browser defaults, so it works great as progressive enhancement.
We’ve mostly talked about checkboxes and radio buttons here, as they’re among the most common form elements requiring customization. But
accent-color has the potential to provide quick and easy styling for many of our form elements, especially where extensive customization isn’t needed, as well as allowing the browser to pick the best options for accessibility.
Some resources on
color-scheme, and styling form inputs:
- MDN documentation
- CSS Tricks guide to accent-color
- Web.dev: CSS accent-color
- Web.dev: Improved dark mode with color-scheme
- Modern CSS: Custom CSS Styles for Form Inputs and Text Areas
- Modern CSS: Pure CSS Custom Styled Radio Buttons