user12815489
user12815489

Reputation:

Focusing on an input and change the label style

I want to change label color when focusing on .input

<label>This is a label</label>
<input class="input" placeholder="Placeholder"/>

Definetely selecting .input:focus + label won't work because label goes first. So, I've tried to do it as label + .input:focus but I know it doesn't work either.

.search {
  padding: 0 5px;
  margin: 12px 0;
  width: 300px;
  height: 25px;
  background: white;
  border: 1px solid black;
  line-height: 25px;
  color: gray;
}


/* This is what I want to modify */

.input:focus+label {
  color: #f00;
}

.input https://stackoverflow.com/posts/65970655/edit#{
  padding: 0 5px;
  margin: 7.5px 0;
  border: 2px solid black;
  z-index: 2;
  width: 300px;
  height: 25px;
  background: transparent;
}

.input:focus {
  outline: red;
  border: 2px solid red;
}
<h2> This what I want to modify</h2>
<label>This is a label</label>
<input class="input" placeholder="Placeholder" />

<br>

<h2>Changing the order does work </h2>
<input class="input" placeholder="Placeholder" />
<label>This is a label</label>

Upvotes: 0

Views: 82

Answers (2)

Joe
Joe

Reputation: 948

If you are able to edit the HTML:

Put the label after the input and do:

CSS:

.input:focus ~ label {
  color:orange;
}

HTML:

<div class="form_field">
   <input class="input" type="text" name="name" />
   <label for="name">Name</label>
</div>

Edit: Also view @Hunter McMillen answer because this is a nicer way to do it if you can access the HTML, you won't need the for attribute on the label then.

If you can't alter the HTML for any reason use JavaScript:

So we need to use JavaScript if you can't change the order of HTML.

First we can create a function to toggle a class on the previous sibling using previousElementSibling on the e.target when focused (we will use an event listener).

The blur event will happen when "un focused".

// get the input in a variable for better readability
const input = document.querySelectorAll('.input');


// create a function which takes an event, so we can access the target
// and get its previous sibling (in our case the label).
const toggleSiblingClass = e => {
   // get the previous sibling of the event target (the input)
   const label = e.target.previousElementSibling;
   
   // toggle the class .focus on it, which we've assigned color:orange in css
   label.classList.toggle('focus');
}

input.forEach(el => {
   // on focus call the toggleSiblingClass function
   el.addEventListener('focus', toggleSiblingClass);
   
   // on focus out call the function again to toggle class off
   el.addEventListener('blur', toggleSiblingClass);
})
label.focus {
  color:orange;
}

label {
display:block;
}

input {
margin-bottom:1rem;
}
  <label>This is a label</label>
  <input class="input" placeholder="Placeholder"/>

  <label>This is a label</label>
  <input class="input" placeholder="Placeholder"/>

  <label>This is a label</label>
  <input class="input" placeholder="Placeholder"/>

  <label>This is a label</label>
  <input class="input" placeholder="Placeholder"/>

  <label>This is a label</label>
  <input class="input" placeholder="Placeholder"/>

Upvotes: 0

Hunter McMillen
Hunter McMillen

Reputation: 61515

You can use focus-within to do this, you'll just need to move your input inside of your label:

label:focus-within {
  color: #f00;
}
<label>
  This is a label
  <input class="input" placeholder="Placeholder" />
</label>

Upvotes: 1

Related Questions