Reputation:
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
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
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