The idea
Make a label transition from above the input to its initial position when you focus the input using :has selector
Basic Form
Let's put a basic form just as an example
<form action="">
<div class="form-field">
<label for="">Name</label>
<div class="field">
<input type="text">
</div>
</div>
</form>
Basic Style
I'm going to add some padding to the input, and put the label above the input
input{
padding: 5px 20px;
}
label{
color:#666;
transform:translate(.8rem, 1.5rem);
transition:all .3s ease;
display: block;
pointer-events: none;
}
We are going to add pointer-events: none;
to the label aswell to allow focus on the input since the label messes with the focus interactions
Now it looks like this
:has
First we need to target any <div>
sibling of <label>
we can use the ~
sibling combinator which targets any sibling, no matter if it is a previous or next one and along with that we can check in <div>
has an input:focus
as child
label:has(~ div input:focus){
transform: translate(0, 0);
}
Final result
input{
padding: 5px 20px;
}
label{
color:#666;
transform:translate(.8rem, 1.5rem);
transition:all .3s ease;
display: block;
pointer-events: none;
}
label:has(~ div input:focus){
transform: translate(0, 0);
}
If you know more about this selector and have recommendations for compatibility let me know in the comments
Some sources:
https://css-tricks.com/child-and-sibling-selectors/
https://ishadeed.com/article/css-has-parent-selector/
Top comments (0)