Here you can find the live version
Now let's see how you can build one.
We'll start like always with
HTML
<div class="form-control"> <input required type="text" name="input" /> <label>Email address or phone number </label> <div class="border-around"></div> </div>
For our text input we first need to create a container:
<div class="form-control"> ... </div>
In this container we are going to have as first child a text input, a label and then a div which will be used to add that nice bluish border around our input.
<input required type="text" name="input" /> <label>Email address or phone number </label> <div class="border-around"></div>
We just finished the HTML part and now we need to add some CSS.
CSS
Styling our container:
Here we're just going to add a width
, height
and also a position: relative;
because we will further use position: absolute;
to align the border
and label
as desired.
.form-control { position: relative; width: 280px; height: 50px; }
Styling text input:
The text input needs to have the same size as the container so we'll use
a width
and height
of 100%
. We need to set border
to 0
because we're going to use the div with class border-around
as the border for our input.
.form-control input { width: 100%; border: 0; outline: none; height: 100%; padding: 0 15px; transition: 0.4s; }
Styling the label:
Now we have to use position: absolute;
with top
set to 0 and flex to center align the label inside our input.
.form-control label { position: absolute; top: 0; display: flex; align-items: center; padding-left: 15px; width: 100%; height: 100%; transition: 0.2s; font-size: 1rem; color: gray; pointer-events: none; }
Styling the border
We will have a border of 1px solid rgba(0, 0, 0, 0.2)
and border-radius
of 3px
.
.form-control div.border-around { position: absolute; border: 1px solid rgba(0, 0, 0, 0.2); height: 100%; width: 100%; padding-right: 25px; top: 0; pointer-events: none; border-radius: 3px; transition: 0.2s; }
Lets now take advantage of the pseudo classes and change some css properties when we interact with our input:
Use pseudo classes to style elements on :focus
, :valid
and :not(:focus)
.
input:valid
Because we've set required
on text input, input:valid
will match only when our text input is valid.
input:focus
When we focus on our input we need to move up the label and also add a color to the border, this two selectors will to the trick:
.form-control input:focus ~ div.border-around
.form-control input:focus + label
input:not(:focus)
After we've added some text to our input and clicked somewhere else
we need to change the text color,input:not(:focus)
will do the trick.
.form-control input:valid + label { top: -0.45rem; left: 10px; font-size: 0.9rem; z-index: 100; width: auto; height: 0.9rem; padding: 0 10px; color: rgba(0, 0, 0, 0.3); } input:not(:focus) { color: rgba(0, 0, 0, 0.5); } .form-control input:focus + label { top: -0.45rem; left: 10px; font-size: 0.9rem; z-index: 100; width: auto; height: 0.9rem; padding: 0 10px; color: #3484f0; } .form-control input:focus ~ div.border-around { border: 2px solid #3484f0; }
That's all you need!
Hope you enjoyed and see you next time!
Top comments (2)
That's so cool, did you use Text Fields for reference?
I already did something similar in my spare time, the guidelines from Material IO are awesome. They are so clear & clean and it looks like they already planned all use case scenarios for using their components. Plus it's free and available on the internets!
I just built it from scratch without any reference, but yeah material design system brings a lot more to the table.
Thanks!