Better way to make disabled variants of the components

Sahil Garg
3 min readOct 5, 2023

--

When creating large projects or ones where you need full customization, it is usually a good practice to recreate the basic UI components according to the design system of the project. When creating these basic UI components, we usually create a disabled variant of button, input etc… These are usually styled by adding another class and then styling that class according to the design system and then disabling the click-handler and removing the cursor: pointer; from it and optionally using cursor: not-allowed;. And for this, we repeat the same code again and again or need to create a mixin (if using a SCSS). What if I tell you that there’s an easier way to style the disabled state of the elements together without needing to redefine the same styles again and again… Well, that’s exactly what we will be going to look in this article.

Toggling the disabled state of the element

Instead of disabling the click handler or removing it depending on the disabled variant, use the disabled HTML attribute which gets toggled based on the variant.

<button onclick="clickHandler()" disabled={variant === 'disabled'}>
Hello world
</button>

Here, if the variant prop passed is disabled then the disabled attribute will be set to true, else false is passed to disabled and the button won’t be disabled.

HTML’s disabled Boolean attribute, which will communicate a form control as semantically being disabled, change its styling to reflect its state and suppress all functionality along with disallowing the element's value from participating in form submission

The disabled attribute can be applied to other elements as well such as inputs and textarea the same was as applied to the button.

Styling the disabled state

CSS provides a pseudo-selector for selecting the disabled state of an element, :disabled. When used with * we can select the disabled state of all the elements.

Usually in a design system, we have a fixed background, foreground and border color for disabled state and the hover state of the button is disallowed. Hence, it is more convenient and non-repetitive to write the disabled styles together for all the elements in the root stylesheet. Still if there are any styles which are specific to an element, they can be specified in their own components and the common ones in the root.

Example:

/* global.css */

*:disabled {
background: gray;
color: #fff;
cursor: not-allowed;
}

Improving accessibility of the disabled state

To improve the accessibility of the disabled state of the element, aria labels are of crucial importance. The aria-disabled attribute, when set to true, indicates that the element upon which it is set and all of its focusable descendants are meant to be in the disabled state. This declaration will inform people using assistive technologies, such as screen readers, that such elements are not meant to be editable or otherwise operable.

Example:

<button disabled aria-disabled="true">Hello world</button>

And in toggle-able form:

<button disabled={variant === 'disabled'} aria-disabled={variant === 'disabled'}>
Hello world
</button>

But note that the state of being disabled applies to the element with aria-disabled=“true” and all of its focusable descendants such as input, button etc… Hence, when applying aria-disabled=“true” care must be taken to not apply it to containers with focusable elements as children in which you do not want disabled state.

Conclusion

These disabled attribute and pseudo-selector were launched with the initial versions of the browsers and have stayed here for a long time yet their use has decreased according to caniuse.com. These bring in more accessibility when combined with the aria labels compared to the traditional approach of using JS, pointer-events: none; or making separate .disabled classes.

If you came this long, you must have liked the post. I highly recommend you to follow to never miss learning new and unknown things in the domain of web development. You can always unfollow if you don’t like it in the future.

Let’s get connected on linkedin: https://www.linkedin.com/in/sahil2004/
I post such amazing content there as well.

--

--

Sahil Garg

Helping aspiring developers become better in the web dev game!