51

I would like the labels for my form elements to be greyed out if the input is disabled and am not able to get it to work for text inputs. I have tried the following:

input:disabled {
    background:#dddddd;
}

input:disabled+label{color:#ccc;}

<input type='checkbox' disabled id='check1'>
<label for='check1'>Check</label>
<br>
<label for='text1'>Text</label>
<input type='text' id='text1' disabled>

Js Fiddle

The styling works for the checkbox label, but not the text label. Are checkboxes the only input types that let you style their labels via css?

I testing with Firefox.

mjr
  • 1,963
  • 4
  • 20
  • 21
  • 7
    `input:disabled+label` means that the label is immediately AFTER the input. In your HTML, the label comes BEFORE the text input. (but there's no CSS for "before".) – andi Oct 14 '13 at 14:36
  • 1
    well that's no fun. Thank you. – mjr Oct 14 '13 at 14:38
  • You should use javascript or your templating engine to add and remove a `"disabled"` class to the `label` elements. It shouldn't be any difficult since having disabled elements already imply you are using some sort of programming with the forms. – OdraEncoded Oct 14 '13 at 14:52

6 Answers6

69

Based on the comment made by @andi:

input:disabled+label means that the label is immediately AFTER the input. In your HTML, the label comes BEFORE the text input. (but there's no CSS for "before".)

He's absolutely right. But that shouldn't stop us being able to solve the problem with a little trickery!

First step: swap the HTML elements order so that the <label> appears after the <input>. This will allow the styling rules to work as desired.

Then for the fun bit: use CSS to position the labels for text inputs on the left hand side!

input:disabled {
  background: #dddddd;
}

input:disabled+label {
  color: #ccc;
}

input[type=text]+label {
  float: left;
}
<input type="checkbox" disabled="disabled" id="check1">
<label for="check1">Check</label>
<br />
<input type="text" id="text1" disabled="disabled">
<label for="text1">Text</label>
<br />
<input type="checkbox" id="check2">
<label for="check2">Check</label>
<br />
<input type="text" id="text2">
<label for="text2">Text</label>
gvee
  • 16,732
  • 35
  • 50
  • 2
    `input[type=radio]:disabled+label` works like a sharm! – sentenza Jan 26 '16 at 09:59
  • 1
    unluckily its not working when ` – Kornel Dylski Mar 01 '17 at 12:52
  • 1
    You could also use a container with display:flex and the order property on the inputs and labels to switch them in the UI. – Chris Smith Oct 17 '17 at 09:17
  • @KornelDylski you can use `` instead of ``. – ANeves Oct 23 '18 at 16:01
  • 1
    If you're going to have to change the html you might as well wrap the input and the label in a div as mentioned in another answer. Using float: left; will be confusing if you forget why you did that, may have unintended effects (especially if you change things later), and the css will stop working if you put anything in between. – cesoid Dec 04 '20 at 15:23
6

This selector input:disabled+label{color:#ccc;} targets label elements that are placed after an input element that is disabled

In this snippet the label is after a disabled input, so the label element is gray

<input type='checkbox' disabled id='check1'>
<label for='check1'>Check</label>

In this case, the label is before the input so the selector does not apply to it

<label for='text1'>Text</label>
<input type='text' id='text1' disabled>

Possible solution would be to wrap your elements in an extra div and apply a class name to the div, something like this

<div class='disabled'>
    <input type='checkbox' disabled id='check1'>
    <label for='check1'>Check</label>
</div>
<div class='disabled'>
    <label for='text1'>Text</label>
    <input type='text' id='text1' disabled>
</div>

And then you can write your css like this

.disabled label {
    color: #ccc;
}
Dejan
  • 501
  • 5
  • 13
  • 3
    This seems a much more sensible option than the other answers of ordering the label before input and then using css to reverse, such a hack just makes code confusing. – Paul Taylor Jan 31 '18 at 21:42
4

You can use atribute selectors in CSS, example https://jsfiddle.net/8pp6mpp5/1/

Html

<label disabled="disabled">Hola Mundo!</label></br>
<label>Hola Mundo!</label>`

CSS

label[disabled="disabled"]{
    background-color: #AAA;
}
AlexVMM
  • 126
  • 4
  • 10
    The form control element is disabled, not the label (the disabled attribute is not allowed on the label itself). – Matt Coarr Jan 09 '18 at 14:55
  • i suggest adding this to your style: `cursor: default;` otherwise, the label still shows a hand as cursor – rubo77 Apr 26 '20 at 13:22
  • great workaround, if the label is **not directly after the input tag in the code**. This is what I tried at first, but it didn't work. This solution adds the missing idea! But since "disabled" is not allowed in the label tag I would use another custoim tag like `label_disable="disabled"` – rubo77 Apr 26 '20 at 13:24
  • Or better use an extra class instead like `class="label_disabled"`. (Sure, this solution only works, if you create the page yourself e.g. with PHP) – rubo77 Apr 26 '20 at 13:38
3

You can also use floats and always put the label after the input Demo

You will have to wrap it in a span (or any other element really).

HTML :

<span>
    <input type='checkbox' disabled id='check1'>
    <label for='check1'>Check</label>
</span>
<br>
<span>
    <input type='text1' id='text1' disabled>
    <label for='check'>Text</label>
</span>

CSS :

span {
    display: inline-block;
    overflow: hidden;
}

input {
    float: right;
}

label {
    float: left;
}

input:disabled {
    background:#dddddd;
}

input + label {
    float: none;
}

input:disabled + label {
    color:#ccc;
}
OneOfOne
  • 95,033
  • 20
  • 184
  • 185
1

If you want to leave your labels before your inputs and lighten your label, you can use the :has pseudo-class and ~ sibling selector:

label:has(~ :is([disabled],[readonly])) {
    color: rgba(0,0,0,0.54); /* or opacity: .5; */
}
Todd Hale
  • 480
  • 8
  • 15
0

I had the same issue: make a read-only input EXACTLY like label, I add a set of css styles to the input to get to that goal:

<input readonly class="inputLikeLabel" value="${myBean.property}"></input>

And in CSS:

.inputLikeLabel {
    background-color: #ffffff;
    text-align: center;
    border: none;
    cursor: none;
    pointer-events: none;
}

By the css style, the input has a white background with no border, no mouse cursor and no click event...similar to label by the end !

Shessuky
  • 1,846
  • 21
  • 24