The disabled attribute in HTML allows developers to disable an element, making it unable to be interacted with or changed by the user. When an element is disabled, it appears grayed out and does not respond to mouse clicks or key presses.
Setting the disabled attribute is easy to do with JavaScript, allowing interactivity and dynamic disabling of elements. Here‘s an in-depth guide on how to set the disabled attribute with JavaScript.
The Basics of the Disabled Attribute
The disabled attribute is a boolean attribute in HTML, meaning it can have only two values: true or false. When present at all, even without a value assigned, it will evaluate to true.
For example:
<input type="text" disabled>
This input is disabled.
To enable an element, the disabled attribute must be removed entirely:
<input type="text">
Now the input functions normally.
The disabled attribute can be applied to:
- Input fields like text, checkbox, radio, buttons, etc.
- Select dropdowns
- Textareas
- Fieldsets
- Buttons
- Optgroups inside select fields
When applied, these elements appear grayed out and do not respond to user interaction. The attribute essentially "disables" the element.
Accessibility Considerations
When disabling elements, ensure they remain perceivable and focusable for assistive technologies like screen readers:
- Don‘t set visibility: hidden – This removes from accessibility tree
- Don‘t position off screen – Still focusable but not visible
- Use CSS to show disabled visual style only
Disabled elements should convey state to all users. Don‘t compromise accessibility.
Setting Disabled with JavaScript
The easiest way to set the disabled attribute on an element is by using the .setAttribute() method.
setAttribute() Syntax
element.setAttribute(name, value);
name: The name of the attribute being set, in this case "disabled".value: The value to assign to the attribute, in this case "true" or "false".
To disable an element:
element.setAttribute(‘disabled‘, ‘true‘);
To enable an element:
element.removeAttribute(‘disabled‘);
Let‘s look at some practical examples.
Disable an Input
To disable an <input> element:
// Get input element
let input = document.getElementById("my-input");
// Disable it
input.setAttribute(‘disabled‘, ‘disabled‘);
Or more simply:
input.disabled = true;
Disable a Button
To disable a <button>:
let button = document.querySelector("#my-button");
button.setAttribute(‘disabled‘, ‘‘);
We can pass an empty string instead of a boolean, and it evaluates to true.
Disable Multiple Elements
To disable multiple elements, select them then loop through:
// Get array of elements
let items = document.querySelectorAll(".item");
// Loop and disable
items.forEach(function(item) {
item.setAttribute(‘disabled‘, ‘‘);
});
This disables all elements with class "item".
Disable All Inputs
To disable all inputs in a form:
let inputs = document.querySelectorAll("input");
inputs.forEach(input => {
input.disabled = true;
});
This can create a "pause" effect while submitting a form.
Persisting Disabled State on Reload
The disabled state will reset when the page reloads or refreshes.
To persist it, store in session or local storage:
let input = document.querySelector("input");
// On disable
input.disabled = true;
localStorage.setItem(‘inputDisabled‘, true);
// On reload
let isDisabled = localStorage.getItem(‘inputDisabled‘);
if (isDisabled) {
input.disabled = true;
}
Now state persists across page loads.
Session storage only lasts until tab is closed. Local storage persists after browser restart. Use as appropriate.
Disabling Groups of Elements
Along with individual elements, you may want to disable groups of elements in a form or section. There are a couple useful techniques for this:
Fieldset and Legend
Wrap elements in a <fieldset> with <legend>:
<form>
<fieldset id="my-fieldset">
<legend>Personalia</legend>
<label for="name">Name: </label>
<input type="text" id="name">
<label for="age">Age: </label>
<input type="text" id="age">
</fieldset>
</form>
Disable with:
let fieldset = document.getElementById("my-fieldset");
fieldset.disabled = true;
This greys out the entire <fieldset> and its contents, disabling everything inside.
Wrapper Div
Alternatively, wrap elements in a <div>, then disable:
<form>
<div id="my-section">
<label for="name">Name: </label>
<input type="text" id="name">
etc...
</div>
</form>
let section = document.getElementById("my-section");
section.setAttribute(‘disabled‘, ‘‘);
This greys out the <div> contents.
Disable Table Rows
Tables can contain input elements we want to disable too:
<table>
<tr>
<td><input type="text"></td>
etc...
</tr>
</table>
Disable with:
let rows = document.querySelectorAll("tr");
rows.forEach(row => {
row.disabled = true;
});
This disables all rows, greying out cell contents.
Toggling Enabled/Disabled States
A common need is to toggle between enabled and disabled states.
For example, disabling a submit button until all required fields are filled out.
Here‘s a simple pattern that toggles state on any element:
let button = document.getElementById("my-button");
function toggleDisabled() {
if (button.disabled) {
button.removeAttribute(‘disabled‘);
} else {
button.disabled = true;
}
}
toggleDisabled(); // Toggle state
Call this in event handlers to update whenever state should change.
Here toggling based on an input value:
let input = document.querySelector("input");
input.addEventListener("keyup", function() {
if (input.value == "") {
button.disabled = true;
} else {
button.removeAttribute(‘disabled‘);
}
});
This pattern can toggle any elements in response to user interactions.
Toggle Multiple Elements
We can also toggle multiple elements in a batch:
let toggleElements = elements => {
elements.forEach(element => {
if (element.disabled) {
element.disabled = false;
} else {
element.disabled = true;
}
});
}
Pass a node list to enable/disable all contents:
let items = document.querySelectorAll(".item");
toggleElements(items);
This provides a reusable batch toggle function.
Disabling vs. Hiding Elements
A alternative to disabling elements is to hide them with display: none;.
However, hiding elements can cause accessibility issues for screen readers and keyboard navigation. Disabling is preferable for accessibility.
Pros of Disabling:
- Conveys disabled/unavailable state
- Elements still in document flow, maintaining structure
- Works for screen readers / keyboards
Cons of Hiding:
- Elements removed from document flow
- Not perceivable by assistive technology
- State not conveyed visually on page
So generally elements should be disabled rather than hidden if possible.
Testing Disabled Elements
When elements are disabled, we need to check:
- Visual style – Shown as disabled?
- Unable to interact – No response to clicks/presses
- Not submitted – Excluded in form data
- ARIA attributes –
aria-disabledreflects state
Some testing approaches:
- Manual testing – Click around in browsers and devices
- Automated browser testing – Scripted clicks/submits
- Accessibility scanning – Tools to scan for issues
- Screen reader testing – Ensure readable by narrators
This ensures disabled elements are properly implemented and provides a good user experience.
Styling Disabled Elements
Disabled elements are grayed out by default in browsers. To customize styling, target the [disabled] attribute:
input:disabled {
opacity: 0.5;
background: #eee;
}
Some common styles include:
- Lower opacity
- Gray text color
- Background color change
We can also style the enabled state:
input:enabled {
border: 1px solid blue;
}
This is removed on disable.
Certain elements like <button> and <fieldset> are automatically stylized by the browser. Limited restyling is allowed.
Using CSS variables, we can set common disabled styles in one place:
:root {
--disabled-opacity: 0.5;
--disabled-bg: #eee;
}
input:disabled {
opacity: var(--disabled-opacity);
background: var(--disabled-bg);
}
Now disabled style is configurable.
According to a 2021 survey by Chrome Developers:
- 97.67% of browsers support the
[disabled]attribute - 2.2% do not support or only partially support
- 0.13% of users remained on non-supporting browsers
So disabled styling is very reliable across modern browsers. Legacy browser support may differ.
Use Cases for Disabling Elements
There are many practical use cases where disabling elements is useful:
- Disabling submit button until a form is valid
- Disabling inputs until a previous step is complete
- Greying out expired content like out-of-stock options
- Toggling access to settings or options
- Prevent use during async operations like fetching data
- Feature availability based on user permissions
- Deprecating functionality while keeping UI intact
- Simplifying forms by only showing relevant fields
- Wizard workflows across multiple steps
And many more. It acts as a simple gateway controlling element usage.
Here are some examples in real applications:
eCommerce – Disable add to cart button if:
- Item out of stock
- Invalid quantity entered
- Incompatible product options selected
Refresh button disables until new results available.
Travel Sites – Disable date picker if:
- Return date before departure
- Traveler count exceeds rooms available
Calendar greys out expired promo dates.
Accounting Apps – Disable reconcile button unless:
- Transactions balance
- All receipts added
- Numbers validate
Lock fields based on user permissions.
Social Networks – Disable post button if:
- Message blank
- Image exceeds size limit after compression
- Captcha not verified
The use cases are unlimited.
Disabled vs. Read-only
The readonly attribute is similar in that it prevents changes to an input field. However there are some differences:
- Disabled elements cannot be focused, selected or changed
- Read-only elements maintain a normal enabled appearance, disabled is greyed out
- Read-only value can still be copied or queried, disabled cannot
- Disabled elements are not submitted with form data
UX Tradeoffs
Disabled
- Conveys state clearly
- Total restriction from interaction
Readonly
- Maintains "active" element appearance
- Allows select and copy of value
So consider whether total interaction needs to be prevented (disabled) or just value changes (readonly).
disabled vs aria-disabled
The aria-disabled attribute conveys disabled state to assistive technology when visible style doesn‘t match true state.
For example, a custom styled button:
<button disabled style="opacity: 1;">Submit</button>
Looks enabled but isn‘t. We can add:
<button disabled style="opacity: 1;" aria-disabled="true">Submit</button>
Now screen readers will announce disabled correctly.
Keep visual style and accessible state aligned when feasible. ARIA augments when styles are customized.
Framework Implementations
Disabled functionality can be added to elements in frameworks like React, Angular and Vue as well:
React – Set disabled on elements like:
<button disabled={isDisabled}>Submit</button>
<input
disabled={formInvalid}
/>
Toggle state dynamically via props.
Angular – Use directive:
<input
[disabled]="!formValid"
>
Bind to a component property.
Vue – Use data binding:
<button :disabled="submitting">
Submit
</button>
Disables when submitting is true.
All frameworks support simple data binding for disabled state.
Server-side Implementation
When an initial disabled state needs to be sent from the server, add the attribute to server-rendered elements:
// Node.js Express backend
let formDisabled = true;
res.render(‘page‘, {
formDisabled
});
<!-- EJS template -->
<form disabled="<%= formDisabled %>">
... elements
</form>
This renders the form disabled from the start.
Django, Rails, PHP etc can render disabled from the backend as well.
In Summary
The disabled attribute provides an easy way to toggle element interactivity in HTML forms and interfaces. Using JavaScript, we can set this attribute dynamically based on any conditions or logic checks needed.
Combined with CSS custom styling and event handlers, we can create robust interfaces that display availability clearly and prevent mistakes or confusion. Setting disabled with JavaScript is a valuable tool for any frontend developer working on interactive sites.


