CSS Selector for label bound to input
Asked Answered
S

6

47

Is there a way in CSS to select labels bound to input fields (via the for attribute) having the required attribute set? Something like:

label:input[required] {
  ...
}

Currently, I'm adding class="required" to labels and inputs for styling. I now have the HTML5 attribute required="required" in the required input fields. It would be nice to remove the redundant class attributes.

The closest answer I found doesn't use the label element's for attribute, but would require that the label be directly adjacent to the input in the HTML.

Steinmetz answered 16/1, 2010 at 0:44 Comment(0)
M
10

you can use label[for="title"] where "title" is the ID of your input. Example:

<label for="title">Title</label>
<input type="text" id="title" name="title">

css:

label[for="title"] {
  color: blue;
}
Morgen answered 2/11, 2018 at 10:30 Comment(2)
Your answer was very simple and it worked for me. Thanks!Homogeneous
Very helpful! I have no idea where you found that syntax. I’ve never seen it.Allottee
O
9

How about CSS 2 Attribute Selectors It is pretty compatible amongst browsers.

Example:

label[required=required] {
   color: blue;
}
<label required="required" for="one">Label:</label><input name="one" id="one" />

Also check this out.

Offload answered 18/1, 2010 at 21:50 Comment(3)
Apparently questions and answers use formatting, but comments do not. The problem with that suggestion is that the required attribute belongs to the input element, not the label element. <label for="email">E-mail address:</label> <input id="email" type="email" name="email" required="required"/> Also in the CSS, better off just saying: input[required] because the only valid markup is: HTML -> required XHTML -> required="required" required="false" or anything like that is not valid.Steinmetz
Also see: whatwg.org/specs/web-apps/current-work/multipage/…Steinmetz
yeah, required=required is unnecessary. But if then he wants to be able to get all of the label tags attached to inputs that have the required attribute I don't think that is possible. You can get all the inputs @required input[required], but not all the labels unless they are a child node of the input, which is incorrect even in HTML.Offload
E
7

This solution works in most modern browsers:

label > input[required="required"] {
    background: red; 
}
<label for="myField"><input required="required" id="myField" /></label>
Epistaxis answered 25/4, 2012 at 13:19 Comment(4)
I think the OP was asking for a selector that would generically apply to all required elements, to avoid specifying a selector for every element.Deccan
this doesn't work if you are using the recommended way of using label/input (not nesting them)Ideation
The other problem with this approach, or something that does label + input[required] is that you are styling the <input> tag and not the <label>Kibbutznik
Labels are not required to be in any particular position in the dom relative to the input fields. They are coupled via the for attribute which binds to a unique id. A particular example is the use of radio buttons. Labels are typically placed on the right in that case.Steinmetz
K
0

I don't think this can really be accomplished through CSS in the way that the OP wants. CSS just doesn't work that way.

A better approach in my opinion is to step back and look at the big picture. You have a form where some fields are required and some are not. It is a good approach to give the user all the required fields first, or group the required fields together, and keep them clearly separate from the optional fields.

You can create a structure such as

<form>
     <ul class="required_fields">
       <li>
          <label>username</label>
          <input />
       </li>
       <li>
          <label>email</label>
          <input />
       </li>
     </ul
     <ul class="optional_fields">
          ...
     </ul>
 </form>

/* CSS */
.required_fields label {font-weight: bold} 
.required_fields label:after { content: "*"; color: red } /*more styles for labels*/

There are a number of benefits to this approach. You can add and remove items from the 'required' group easily without having to modify each one individually. You can assign the 'required' class as high up the chain as you want. If the form had the 'required' class, then everything in it would be labeled as required. There are fewer places to make changes, if you decided that the 'required' class should be called something else. And in general this approach also helps you organize your forms better. You should not intermingle required and optional fields.

You could take this a step further and have some javascript that will inject the required attribute into the input fields as well.

$(".required_fields input").each(function(){
   this.setAttribute('required', 'required');
});
Kibbutznik answered 19/3, 2014 at 16:3 Comment(2)
That is a rigid requirement and forces a particular design decision. Consider asking for a mailing address. We require address line 1, city, state, zip. You would move address line 2 out of the flow because it is optional? People are familiar with the structure of a mailing address and would want it structured in a standard way.Steinmetz
In that case address line 2 is the exception, and as an exception it should get special treatment. Perhaps a class .not_required that disables the required style. .required_fields label.not_required:after {content: ""}. Seems like a perfect solution of going from the general to the more specific.Kibbutznik
S
0

Well it's not possible in CSS (as I tried) you can easily do it in JS:

let l = document.querySelectorAll('input[required]')
l.forEach(e => {
  e ? e.parentElement.classList.add('required-input') : null;
})

let l = document.querySelectorAll('input[required]')
l.forEach(e => {
  e ? e.parentElement.classList.add('required-input') : null;
})
.required-input label::after {
  content: " *";
  color: red;
}
<div>
  <label for="user">Required</label>
  <input name="user" required/>
</div>
<br>
<div>
  <label for="user">not required</label>
  <input name="user" />
</div>
Synergistic answered 14/1, 2022 at 7:39 Comment(0)
G
0

CSS Level 4 has the has selector which where you can select the wrapping element with a certain condition. In my example I used the required attribute on the input element as condition to add an asterisk after the label text.

div:has(input[required]) > label:after {
  content: "*";
 }
<div>
  <label for"testelement">Label</label>
  <input type="text" id="testelement" name="testelement" required>
</div>
Gerigerianna answered 21/5, 2024 at 9:6 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.