Go back to home page of Unsolicited Advice from Tiffany B. Brown

Troubleshooting Chrome's An invalid form control is not focusable error

If you see an error similar to the one below in Chrome's Developer Tools console, check your CSS.

An invalid form control with name='field1' is not focusable.

This error can be triggered when two conditions are met:

  1. the checkbox or radio button field is required, but not selected on submission; and
  2. the form control is neither visible nor displayed.

In other words, make sure this form control doesn't have a display: none or visibility: hidden declaration. Both of these properties and values can prevent elements from receiving focus. Chrome, in particular, will attempt to focus on a required form field when its value is missing.

Sometimes you don't want an element to be focusable. For example, items in a closed or collapsed sub-menu don't need to be focusable unless the menu is open. But if a form element is visible, it should also be focusable and navigable with a keyboard.

Why would you want to hide a form control in the first place? It's necessary for creating custom checkbox and radio button controls. But as you may have gathered by reading this post, which method you use to hide that control can also prevent keyboard input and trigger an error in Chrome.

So what to do instead?

Firefox, Safari, and Chrome support the appearance property, with a vendor prefix. Setting appearance to none retains the form control's behavior, but resets its appearance.

[type=checkbox] {
    -webkit-appearance: none;
       -moz-appearance: none;
            appearance: none;
}

For Internet Explorer, however, we need another approach. Using opacity: 0 is a good choice here. It hides the element visually while keeping it focusable. Keep in mind that you'll also need to absolutely position the element. Without positioning, the element will still take up space, but be invisible.

[type=checkbox] {
    opacity: 0;
    position: absolute;
}

In most modern browsers, transform is also an option. With transform, we don't need to use a wrapping element, as with clip/clip-path. Use a scale transform with a very small value (e.g. transform: scale(.01)), or use a translation transform that places the element off screen.

Get CSS Master

Did you learn something from this blog post? You might like the latest edition of CSS Master. It contains several nuggets of CSS joy like this one. Buy now from SitePoint