Given your current HTML structure, what you want to do CSS-wise is not possible, because you can only select forward.
That is, CSS has no previousSibling or parent/ancestor selector.
As a sidenote, your label is missing the for
-attribute which works as the connector between the two.
What you can do is wrap both in a div
(if it isn't already wrapped in another element, in that case just use that element) and use :focus-within
pseudo class on the parent. Browser support for :focus-within
is very broad, with IE being the usual exception. To make sure only browsers that support :focus-within
hide the label, wrap the CSS declarations in a
@supports selector(:focus-within)
block:
.input-label-group label {
color: red;
}
@supports selector(:focus-within) {
.input-label-group label {
visibility: hidden;
}
.input-label-group:focus-within label {
visibility: visible;
}
}
<div class="input-label-group">
<label id="emaillabel" for="email">Email</label>
<input id="email" type="text" required placeholder="Email">
</div>
To make things a little more intuitive, you could - instead of switching visibility - also apply fadein/out using opacity
and transition
:
.input-label-group label {
color: red;
}
@supports selector(:focus-within) {
.input-label-group label {
opacity: 0;
transition: opacity 0.2s ease-in-out;
}
.input-label-group:focus-within label {
opacity: 1;
}
}
<div class="input-label-group">
<label id="emaillabel" for="email">Email</label>
<input id="email" type="text" required placeholder="Email">
</div>