The :disabled pseudo-class matches form controls that are disabled — they cannot be clicked, typed into, or focused.
Set the HTML disabled attribute (or nest the control in a disabled fieldset). Pair with :enabled for the interactive state. Prefer clear muted styles and cursor: not-allowed so the inactive state is obvious.
Baseline · Widely available.
Not deprecated. Core form-state selector. Extremely broad browser support.
Syntax
CSS Syntax
syntax.css
:disabled{ /* declarations */ }
Often typed as input:disabled, button:disabled, or select:disabled.
Fieldset.disabled on the group disables its controls.
Match. Those inputs still match input:disabled.
One switch. Useful for “same as shipping” style forms.
Legend note. Content in legend is not disabled the same way as nested controls.
Edge Cases & Pitfalls
If styles do not apply, check these first.
aria
aria-disabled ≠ :disabled
Only the HTML disabled state matches. Style ARIA-only cases with [aria-disabled="true"].
vs readonly
Disabled vs read-only
Disabled controls skip focus and form submit. Read-only can still focus and often still submit — see :read-only.
div
Not for plain div/span
:disabled targets form controls that support disabled. Custom widgets need classes or ARIA + JS.
a11y
Do not rely on color alone
Combine muted fill with cursor, contrast, and clear labeling so the inactive state is understandable.
fieldset
Disabled fieldset disables children
Descendant controls match :disabled even without their own attribute. Handy for toggling a whole group.
Compatibility
Browser Support
The :disabled pseudo-class is a browser CSS selector. Node.js, Deno, and Bun do not apply it.
✓ Baseline · Widely available
:disabled
Supported in all modern browsers (CSS3-era form selectors). Safe for teaching and production.
100%Core support
Google Chrome1+
Full support
Mozilla Firefox1+
Full support
Apple Safari3.1+
Full support
Microsoft Edge12+
Full support
Opera9+
Full support
Samsung Internet1+
Full support
Internet Explorer9+
Full support
:disabledUniversal
Bottom line: No prefixes. No polyfills. It is not a runtime API.
Remember
Key Takeaways
Role: style form controls that cannot be activated or focused.
Trigger: HTML disabled (or a disabled fieldset).
Opposite: use :enabled for interactive controls.
Tip:aria-disabled alone does not match :disabled.
One line::disabled styles inactive form controls so users can tell what they cannot use.
Frequently Asked Questions
It matches form controls that are disabled — they cannot be activated, edited, or focused. Browsers usually gray them out by default; you can add your own styles.
Controls that support the HTML disabled attribute: input, button, select, textarea, fieldset, optgroup, and option. A control inside a disabled fieldset also matches.
:disabled matches inactive controls. :enabled matches the same kinds of controls when they are interactive (no disabled state).
No. Only the HTML disabled attribute (or being disabled via a disabled fieldset) triggers :disabled. Style aria-disabled with [aria-disabled="true"] instead.
Yes. It is Baseline Widely available and works in every modern browser. It is a CSS selector, not a Node.js or runtime API.
No. Disabled controls are skipped on submit and are usually removed from the tab order. Use readonly if the value must still submit.