I want to disable a label
when the input
element associated with it is disabled. Here is my code:
<!-- TODO: Gray this label out initially. -->
<label id="spacesPerIndentLabel">Spaces per indent: 4</label>
<br>
<input id="spacesPerIndent" type="text" disabled>
I can't figure out how to make the label disabled. I tried putting disabled
on the label, but had no luck because label
isn't an element that supports disabled
. I also thought of selecting
label + input:disabled { ... }
but that would select the disabled input
instead of the label
. After some further research I found out that CSS has no "previous sibling" selector (like +
is the "next sibling" selector).
I want to disable a label
when the input
element associated with it is disabled. Here is my code:
<!-- TODO: Gray this label out initially. -->
<label id="spacesPerIndentLabel">Spaces per indent: 4</label>
<br>
<input id="spacesPerIndent" type="text" disabled>
I can't figure out how to make the label disabled. I tried putting disabled
on the label, but had no luck because label
isn't an element that supports disabled
. I also thought of selecting
label + input:disabled { ... }
but that would select the disabled input
instead of the label
. After some further research I found out that CSS has no "previous sibling" selector (like +
is the "next sibling" selector).
-
1
You can still add
disabled
to your<label>
, you'd just have to style it with CSS, eglabel[disabled] { opacity: 0.4; }
– Phil Commented Jan 21, 2018 at 22:57 -
@Phil Oh, I tried using
label:disabled
instead of[disabled]
. I'll try your suggestion, thanks. Why do you think:disabled
didn't work? – James Ko Commented Jan 21, 2018 at 23:01 -
Because the
:disabled
pseudo-class only works on elements that support thedisabled
property.[disabled]
is using an attribute selector – Phil Commented Jan 21, 2018 at 23:03
5 Answers
Reset to default 3You could use css flexbox to position your elements.
https://jsfiddle/c1d81r8b/4/
HTML:
<div class="container">
<input id="test1" type="text">
<label for="test1">Test 1 label</label>
</div>
<br>
<br>
<div class="container">
<input id="test2" type="text" disabled>
<label for="test2">Test 2 label</label>
</div>
CSS:
.container {
display: flex;
flex-direction: column;
}
.container label {
order: 1;
}
.container input {
order: 2;
}
.container input[disabled] + label {
background: grey;
}
This lets your use CSS to set the order the elements are displayed in, and allows you to use the sibling selector.
See https://caniuse./#feat=flexbox for browser support notes.
If you're happy to add extra attributes or classes to your <label>
elements, you can use CSS to style them appropriately. For example
<label disabled id="spacesPerIndentLabel">Spaces per indent: 4</label>
<!-- or -->
<label class="disabled" id="spacesPerIndentLabel">Spaces per indent: 4</label>
your CSS could look like
label.disabled, label[disabled] {
opacity: .4;
}
First of all the markup of your label
is not patible with the standard i.e it has not the for
attribute. See this or at least it should wrap its element.
So first, your HTML should be something like the following:
<label id="spacesPerIndentLabel" for="spacesPerIndent">Spaces per indent: 4</label>
<br>
<input id="spacesPerIndent" type="text" disabled>
Then using javascript we will add class to each label that its for element is disabled like the following:
labels = document.getElementsByTagName('label');
for (i = 0; i < labels.length; i++){
forId = labels[i].attributes.for.value
if (document.getElementById(forId).attributes.disabled){
labels[i].className = 'dis'
}
}
Checkout this DEMO
If you're happy with putting a wrapper around your input and label that uses position relative, and positioning your label absolutely, you can try this method:
CSS:
.container {
position: relative;
padding-top: 1.1em;
}
.container label {
position: absolute;
left: 0;
top: 0;
}
.container input[disabled] + label {
background: grey;
}
HTML:
<div class="container">
<input id="test1" type="text">
<label for="test1">Test 1 label</label>
</div>
<div class="container">
<input id="test2" type="text" disabled>
<label for="test2">Test 2 label</label>
</div>
JSFiddle: https://jsfiddle/c1d81r8b/3/
Essentially this just places the label after your inputs so they can be targeted with the sibling selector, but then positions them before it. The 1.1em
padding top on the container is what makes space for the label to sit - adjust this to match your label font size and any required padding/margins there.
Note that this will not be appropriate if your label text needs to wrap at any point - so use with caution.
Nowadays you can do the following (if you have a future release date/only need to support new browsers):
<label>
Hello
<input type="text" disabled />
</label>
input:disabled {
background: lightgray;
}
label:has(:disabled) {
color: lightgray;
}