0

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>

2 Answers2

1

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>
Hunter McMillen
  • 59,865
  • 24
  • 119
  • 170
  • 1
    Great Hunter, this is what I was looking for, it was just a matter of placing the element within the label and apply that selector, thank you! –  Feb 01 '21 at 00:45
0

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"/>
Joe
  • 918
  • 1
  • 8
  • 17
  • Wow this is a good answer, in JavaScript we can do thing more simple and with more features! I was looking to do it without JavaScript because the project doesn't require it, but I'll make sure to apply it on other projects –  Feb 01 '21 at 00:44