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)