non-disabled checkbox being targeted by the :read-only pseudo element

Viewed 158

I'm trying to understand a problem that has been bugging me for a while, now.

I am wondering why checkboxes would be targeted by the pseudo element :read-only, even when not having the disabled attribute.

See the snippet below :

input:read-write + label {
  background-color: green;
}

input:read-only + label {
  background-color: red;
}
<!-- an active ( not disabled ) checkbox -->
<input type="checkbox" id="checkbox" />
<label for="checkbox">the checkbox</label>

<br /> 
<br />

<!-- a disabled text -->
<input type="text" disabled id="text"/>
<label for="text">the text</label>

<br /> 
<br />

<!-- an active ( not disabled ) text -->
<input type="text" id="text-active"/>
<label for="text-active">another text</label>

As you can see, both the checkbox and the first text input are targeted by the input:read-only, even though only the first text input has the disabled attribute.

I've done some research and came across this article on the subject which stated :

:read-only is a CSS pseudo-class selector that matches any element that does not match the :read-write selector.

Naturally I followed with a research on the :read-write pseudo selector and ended up on the mdn web docs page, which stated :

The :read-write CSS pseudo-class represents an element (such as input or textarea) that is editable by the user.

I feel like, since I can toggle the value of the checkbox, it should be considered "editable by the user" ?

I've made some test in some browser, Both Firefox ( 90.0 ) and Brave ( v. 1.27.109 Chromium: 92.0.4515.115 ) seams to have the problem.

I also tested in an old version of chrome ( Version 89.0.4389.90 ) and the behavior was not the same. Both element were unaffected by the :read-only pseudo-element, and the second text field was affected by the read-write pseudo element, even with the disabled attribute. Weird.

Maybe I'm missing something obvious ?

2 Answers

I've found why this behavior is occuring.

According to the HTML standard

The :read-only pseudo-class must match all other HTML elements.

Here, the all other HTML elements refer to the html elements on which the :read-write property does not apply.

On the same page, we can see what define an html element that is :read-write-able.

The :read-write pseudo-class must match any element falling into one of the following categories, which for the purposes of Selectors are thus considered user-alterable:

  • input elements to which the readonly attribute applies, and that are mutable (i.e. that do not have the readonly attribute specified and that are not disabled)

  • textarea elements that do not have a readonly attribute, and that are not disabled

  • elements that are editing hosts or editable and are neither input elements nor textarea elements

The relevent part, here, is input elements to which the readonly attribute applies. If we check the HTML standard page for checkboxes, we can see that the readonly attribute, indeed, does not apply.

The following content attributes must not be specified and do not apply to the element: accept, alt, autocomplete, dirname, formaction, formenctype, formmethod, formnovalidate, formtarget, height, list, max, maxlength, min, minlength, multiple, pattern, placeholder, readonly, size, src, step, and width.

Which makes the checkbox falls into the categories of html elements on which the :read-write property cannot be applied. Hense the behavior of the original question's snippet.

While this does not explain how to bypass the behavior ( see ADITYA's answer ), It explains why it is occuring, which was the part I was originaly interessed in.

As an aditional note, I'm still not sure as why it the background-color was not working of the :read-only element in Chrome 89.

Try this out

input:read-write + label {
  background-color: green;
}

input:disabled + label {
  background-color: red;
}
<input type="checkbox" id="checkbox" />
<label for="checkbox">the checkbox</label>

<br /> 
<br />

<input type="text" disabled id="text"/>
<label for="text">the text</label>

<br /> 
<br />

<input type="text" id="text-active"/>
<label for="text-active">another text</label>

Instead of using read-only you can use disabled in your css

According to your question you need to change the style of a disabled input but as you're using :read-only this means the input which is set to readonly is changed!

input:read-only { background: #121212; color: #fff; }
input:disabled { background: #555; color: #00aeff; }
<input type="text" value="ReadOnly" readonly><br>
<input type="text" value="Disabled" disabled><br>
<input type="text" value="ReadOnly & Disabled" readonly disabled>

Check this WebPage Read more about Readonlys

Conclusion? Well there's a Difference between Read-Only and Disabled inputs.

Related