Mickael Caruso
Mickael Caruso

Reputation: 9461

How to target label element based on input element's dynamic class?

HTML

<label for="email">Email</label>
<input type="text" name="email"></input>

The class attribute of the email input element may change, like if the user enters an invalid email format. I only want that label to change to red when the input it's for gets the class "invalid".

In fact, I want ALL my labels with a for attribute to be "invalid aware" of their assigned input elements.

CSS Attempt:

label[for=*.invalid]{
     color: red;
}

The above is probably incorrect because I might have to specify a specific form element by name.

Upvotes: 1

Views: 4012

Answers (2)

Michael Benjamin
Michael Benjamin

Reputation: 371629

Option 1

If you're adding a dynamic class to the input element (.invalid), why not add a class to the label element, as well? This would simplify the styling of the label when the input fails validation.

Option 2

I understand that changing the label color to red highlights an error to the user. In this option you still highlight an error to the user, but in a slightly different way. The CSS :valid and :invalid pseudo-classes represent form and input elements that validate or fail to validate. These pseudo-classes style the input not the label.

Option 3

This option involves the sibling and attribute selectors. You would have to reverse the order of your label and input in the HTML (but this doesn't have to change the appearance on the screen; see below).

HTML

<input type="text" name="email" class="invalid"></input>
<label for="email">Email</label>

CSS

input[class="invalid"] + label { color: red; }

Changing the visual order of elements with CSS Flexbox

Despite the order of elements in the DOM, you can still change the visual order of elements with CSS Flexbox. So if you didn't want to put the label after the input for the sake of appearance there's an easy workaround: Wrap the input and label in a flexbox and use the order property to arrange their display order.


A few side notes...

  • HTML5 provides an input type="email"‌, which you may want to consider instead of type="text". One benefit being that when mobile devices see type="email" they often launch an e-mail-friendly keyboard.

  • Second, the input element is a void element. No closing tag required. You can safely remove the </input>.

  • Lastly, the for attribute associates a label element with a matching ID. In your code, you would need to add id="email" to your input for the label click feature to work.

Upvotes: 3

Quentin
Quentin

Reputation: 943979

The for attribute has to match the id (not the name, not the class) of the associated input.

In order to change the label based on a feature of the input you need to either:

  • Use combinators to draw a connection between the two elements (which is impossible when the label precedes the input) or
  • Use JavaScript to modify the label (e.g. by adding a class).

Upvotes: 2

Related Questions