Should I use CSS :disabled pseudo-class or [disabled] attribute selector or is it a matter of opinion?

39,212

Solution 1

Is the attribute selector the modern CSS3 way and the way to go forward?

  • attribute is newer and better

No; actually, attribute selectors have been around since CSS2, and the disabled attribute itself has existed since HTML 4. As far as I know, the :disabled pseudo-class was introduced in Selectors 3, which makes the pseudo-class newer.

  • there's a technical reason to use one over the other

Yes, to some extent.

With an attribute selector, you're relying on the knowledge that the document you're styling makes use of a disabled attribute to indicate disabled fields. Theoretically, if you were styling something that wasn't HTML, disabled fields might not be represented using a disabled attribute, e.g. it might be enabled="false" or something like that. Even future editions of HTML could introduce new elements that make use of different attributes to represent enabled/disabled state; those elements wouldn't match the [disabled] attribute selector.

The :disabled pseudo-class decouples the selector from the document you're working with. The spec simply states that it targets elements that are disabled, and that whether an element is enabled, disabled, or neither, is defined by the document language instead:

What constitutes an enabled state, a disabled state, and a user interface element is language-dependent. In a typical document most elements will be neither :enabled nor :disabled.

In other words, when you use the pseudo-class, the UA automatically figures out which elements to match based on the document you're styling, so you don't have to tell it how. Conversely, the attribute selector would match any element with a disabled attribute, regardless of whether that element actually supports being enabled or disabled, such as div. If you're using one of the many modern frameworks that rely on such non-standard behavior, you may be better served by using the attribute selector.

In terms of the DOM, I believe setting the disabled property on a DOM element also modifies the HTML element's disabled attribute, which means there's no difference between either selector with DOM manipulation. I'm not sure if this is browser-dependent, but here's a fiddle that demonstrates it in the latest versions of all major browsers:

// The following statement removes the disabled attribute from the first input
document.querySelector('input:first-child').disabled = false;

You're most likely going to be styling HTML, so none of this may make any difference to you, but if browser compatibility isn't an issue I would choose :enabled and :disabled over :not([disabled]) and [disabled] simply because the pseudo-classes carry semantics that the attribute selector does not. I'm a purist like that.

Solution 2

It turns out that Internet Explorer 10 and 11 fail to recognize the :disabled pseudoclass on some elements and only works fine with the attribute selector syntax.

#test1:disabled { color: graytext; }
#test2[disabled] { color: graytext; }
<form>
<fieldset id="test1" disabled>:disabled</fieldset>
<fieldset id="test2" disabled>[disabled]</fieldset>
</form>

The code snipped above renders in IE like this:

As long as you're only styling input elements, you should be fine either way. Still it's a good advice to test the final result in all browsers you wish to support.

Solution 3

Apparently, you can only select and style input elements with ":(pseudoclass)" / ":disabled" , but other elements, such as DIVs, must instead use [disabled].

I often run into this issue when writing SCSS / SASS and try to select a disabled element.

See CSS selector for disabled elements

Share:
39,212

Related videos on Youtube

kingfleur
Author by

kingfleur

I help companies and teams turn legacy code into maintainable software. You can see my work on Twitter, my blog, Careers, LinkedIn, BitBucket and GitHub.

Updated on July 05, 2022

Comments

  • kingfleur
    kingfleur almost 2 years

    I'm trying to style a disabled input. I can use:

    .myInput[disabled] { }
    

    or

    .myInput:disabled { }
    

    Is the attribute selector the modern CSS3 way and the way to go forward? I used to use the pseudo-class, but I can't find any info on whether they are the old way and won't be supported or whether they're both equal and you can use whatever you like best.

    I have no need to support older browsers (it's an intranet application), so is it:

    • attribute is newer and better
    • pseudo-class is still the way to go
    • whichever you like best
    • there's a technical reason to use one over the other
    • Camille
      Camille almost 3 years
      I still use both to be sure :disabled, [disabled] {background-color: #eee;}
  • Katana314
    Katana314 over 10 years
    Huh. Never thought of it that way. But it's true that I've used CSS with MXML (Flash UI language) as well as HTML (although the former hardly supported anything useful)
  • Alohci
    Alohci over 8 years
    The effect of the disabled property on the HTML fieldset element should be considered too. In FF and Chrome (but not IE), the disabled state of descendent controls (reflected by :disabled) will applied, though neither the content attribute will be present nor the IDL attribute (property) be true. See jsfiddle.net/UH2S4/12
  • trysis
    trysis over 8 years
    Which version of IE?
  • trysis
    trysis over 8 years
    This does not matter in your example, but attributes like disabled are meant to take their names, the empty string, or nothing, without even the =. Here, instead of putting disabled="true", you would put disabled="disabled" or just disabled. This may be why IE is failing, though I doubt it.
  • chharvey
    chharvey about 8 years
    good answer! could you explain more about how "the UA automatically figures out which elements to match"? for example, working with an independent flavor of XML, how would one specify the elements to select with the :disabled pseudo-class?
  • BoltClock
    BoltClock about 8 years
    @chharvey: I am not sure if you're able to specify enabled/disabled semantics with XSD. It might well be impossible. Sometimes this behavior is built into the browser for the given language (HTML, etc).
  • Saborknight
    Saborknight over 7 years
    I'm running the latest Microsoft Edge (25.10586.672.0) and it works the same as the other browsers. If in doubt, check can I use: caniuse.com/#feat=css-sel3
  • DreamTeK
    DreamTeK over 3 years
    When testing this in Chrome :disabled only seems to work on input elements. Where [disabled] works on everything I tested.
  • BoltClock
    BoltClock over 3 years
    Divs cannot be disabled, so it makes sense that the :disabled pseudo doesn't apply to them. This isn't a fault of CSS but of developers who mistakenly assume they can apply the disabled attribute to just any element.
  • BoltClock
    BoltClock over 3 years
    @DreamTeK: What did you test it with? If you're testing it with divs and other elements that don't normally have a disabled attribute, like VinLucero did, then that's by design, since elements that don't have that attribute don't have enabled/disabled semantics as stated in the quotation. I'll clarify this in my answer.
  • DreamTeK
    DreamTeK over 3 years
    @BoltClock Thanks for the note. I came to this conclusion also. It is obvious when you look into it but an easy error to make when copying or changing element types. Regardless your answer helped the obvious stand out for me. Personally I think it is worth recommending to use the attribute selector as it is a catchall.