Reputation:
I want to make an input with the floating label. Exactly like the material-ui for react.
Material UI Code :
<TextField
id="outlined-basic"
label="E-Mail"
variant="outlined"
placeholder="Enter E-Mail"
/>
Link for seeing output for the above code : Code
What I want is, the label must be inside the input field. When the user is clicking the input field, the label should float and the placeholder should be shown. If the user doesn't enter anything and if the focus changes, again the placeholder must be hidden and the label must comeback to initial position
What I have tried so far is :
.container {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.material-textfield {
position: relative;
}
label {
position: absolute;
font-size: 1rem;
left: 0;
top: 50%;
transform: translateY(-50%);
background-color: white;
color: gray;
padding: 0 0.3rem;
margin: 0 0.5rem;
transition: 0.1s ease-out;
transform-origin: left top;
pointer-events: none;
}
input {
font-size: 1rem;
outline: none;
border: 1px solid gray;
border-radius: 5px;
padding: 1rem 0.7rem;
color: gray;
transition: 0.1s ease-out;
}
input:focus {
border-color: #6200ee;
}
input:focus + label {
color: #6200ee;
top: 0;
transform: translateY(-10%) scale(0.9) !important;
}
input:not(:placeholder-shown) + label {
top: 0;
transform: translateY(-50%) scale(0.9) !important;
}
input:empty + label {
transform: translateY(75%);
font-weight: bold;
}
input:empty:not(:placeholder-shown) + label {
top: 0;
transform: translateY(-50%) scale(0.9) !important;
}
input:empty::-webkit-input-placeholder {
opacity: 0;
}
<div class="container">
<div class="material-textfield">
<input placeholder="placeholder" type="text" />
<label> label</label>
</div>
</div>
Upvotes: 0
Views: 5472
Reputation: 11027
You were mostly there with your code. The most important thing to note, :empty
means nothing for inputs. It will always be applied because inputs can't have children.
Though the :placeholder-shown
is pretty much the main workaround to styling an empty input.
I removed most of the :empty
styles and replaced some with :placeholder-shown
.
The other thing I did was I set up the focus and not-empty transitions to be the same.
input:not(:focus)::placeholder {
opacity: 0;
}
This makes it so the placeholder is hidden only when it's not focused.
Here's the full results:
.container {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.material-textfield {
position: relative;
}
label {
position: absolute;
font-size: 1rem;
left: 0;
top: 50%;
transform: translateY(-50%);
background-color: white;
color: gray;
padding: 0 0.3rem;
margin: 0 0.5rem;
transition: 0.1s ease-out;
transform-origin: left top;
pointer-events: none;
}
input {
font-size: 1rem;
outline: none;
border: 1px solid gray;
border-radius: 5px;
padding: 1rem 0.7rem;
color: gray;
transition: 0.1s ease-out;
}
input:focus {
border-color: #6200ee;
}
input:focus+label {
color: #6200ee;
top: 0;
transform: translateY(-50%) scale(0.9) !important;
}
input:not(:placeholder-shown)+label {
top: 0;
transform: translateY(-50%) scale(0.9) !important;
}
input:not(:focus)::placeholder {
opacity: 0;
}
}
<div class="container">
<div class="material-textfield">
<input placeholder="placeholder" type="text" />
<label> label</label>
</div>
</div>
That all being said, there are some accessibility issues with the Material Design shrink labels. So, just make sure you are aware of potential issues.
https://www.matsuko.ca/blog/stop-using-material-design-text-fields/
Upvotes: 6