Forms and CSS Accessibility
Style forms and interactive controls while preserving keyboard usability, focus visibility, contrast, semantics, and user preferences.
Accessible Form Controls
Form controls should remain recognizable, keyboard accessible, and readable. Styling should not remove browser affordances without providing an equivalent accessible alternative.
Labels should be associated semantically in HTML, while CSS handles visual presentation.
.field {
display: grid;
gap: 0.5rem;
}
input,
textarea,
select {
width: 100%;
padding: 0.75rem 1rem;
border: 1px solid #94a3b8;
border-radius: 0.5rem;
font: inherit;
}
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
outline: 3px solid #2563eb;
outline-offset: 2px;
}- Do not remove focus indicators without replacing them.
- Use
font: inheritto make form controls match surrounding typography.
Why is `:focus-visible` important for form accessibility?
Keyboard Focus
Keyboard users need to know which element currently has focus. A strong focus indicator should have sufficient contrast and should not depend exclusively on color.
Avoid using outline: none globally. If the default outline is replaced, the replacement should remain clearly visible.
a:focus-visible,
button:focus-visible {
outline: 3px solid currentColor;
outline-offset: 4px;
}- Never remove keyboard focus visibility without replacement.
- Focus indicators should be obvious and high contrast.
What is a major accessibility problem with `outline: none` without an alternative?
Contrast and Color
Text and important UI components should have sufficient contrast against their backgrounds. Color should not be the only mechanism for communicating meaning because users may have color-vision deficiencies or different display conditions.
Use icons, labels, patterns, position, or other visual cues alongside color when necessary.
.field--error input {
border-color: #b91c1c;
}
.field--error .message {
color: #991b1b;
font-weight: 600;
}- Do not rely on color alone.
- Test contrast for text and important controls.
Why should color not be the only way to communicate an error?