Most methods for styling the checkbox element rely on some variation of Ryan Seddon’s “checkbox hack.” Unfortunately, every version of a css-styleable checkbox I have ever seen has one or more problems.
Because the checkbox hack involves hiding the actual checkbox and covering it with something else, it breaks the behavior of the focus outline while navigating the form using the tab key. This matters not just for accessibility, but for anyone who uses the tab key to navigate forms (IOW everyone).
Unlike other css-styleable checkboxes, notice:
—You can tab/shift-tab between the checkboxes
—You get a focus outline, so you know where you are
—The style of the focus outline is the style that is native to the browser you are using (i.e. blurred blue for webkit, dotted black for moz)
—You can check/uncheck using the spacebar
—You can check/uncheck by clicking the mouse on the label as well as the box itself
—Browsers which do not support some variation of the appearance property revert to default checkbox styling
Using the appearance property and then styling with pseudo-selectors was suggested by an article by Danny Markov at:
The appearance property has never been fully implemented by any browser, and is considered
problematic. However, as of December 2016, there is now some talk of instituting a limited form
(appearance:none is all we really need):
This works on:
Mac—Safari, Chrome, Opera
iOS—Safari, Chrome, Opera, Firefox
IOW, it works in everything except desktop Firefox (not tested on Android).
The strange thing about Firefox is that -moz-appearance does not work the same as -webkit-appearance. If -moz-appearance:none is omitted altogether, the default rounded/shaded blue checkbox is used, as expected. But when -moz-appearance:none is included, it does have some effect: it styles the box with a 2px gray inset border, white background, and its own custom checkmark character, but it does allow you to specify your own height and width. In the case of my particular site, I judged that this compromise is still better than the default, and so kept -moz-appearance:none in the css.