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:
The :disabled CSS pseudo-class represents any disabled element. An element is disabled if it can't be activated (selected, clicked on, typed into, etc.) or accept focus. The element also has an enabled state, in which it can be activated or accept focus.
A pseudo-class is used to define a special state of an element. For example, it can be used to: Style an element when a user mouses over it. Style visited and unvisited links differently.
Pseudo-classes are CSS classes used to define the state of an element. They target elements that can't be targeted with combinators or simple selectors like id or class. They are used to select elements based on their attributes, states, and relative position.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With