The :placeholder-shown
pseudo-class represents any <input>
or <textarea>
element that is displaying placeholder text.
With this rule, we can do this type of styling that would otherwise require the aid of JavaScript:
<input name="food" placeholder=" " />
<label for="food">Favorite food</label>
const input = document.querySelector('input');
input.addEventListener('focus', () => {
// Add parent class to move label above input
});
input.addEventListener('blur', () => {
// Check if input has value
// Remove parent class to reset label
});
But instead of all this overhead, we can leverage the :focus
and :placeholder-shown
CSS rules:
input:focus + label,
input:not(:placeholder-shown) + label {
top: 14px;
left: 6px;
font-size: 12px;
color: #fff;
}
Here we check if the input has focus OR if it does not have the placeholder shown (meaning there is a text value). If either of these states apply, we have the label float to the top left.
A hell of a lot easier than JS event handlers! 😉
Here's a video using this in action:
Check out more #JSBits at my blog, jsbits-yo.com. Or follow me on Twitter and TikTok.
Oldest comments (8)
Cool features
It is totally doable with focus-within I think
For the moving label, you'll still need :placeholder-shown to know whether there's text inside the input since you don't want the label to cover it after focusing out.
Yep thanks for writing about it, it is definitely a great feature!
Look at the animation. When there is no placeholder showing but the word Pizza, the label stays at the top of the input.
Something here is incomplete. I tried to duplicate this in my Codepen but I'm not getting the same results. codepen.io/kwsim/pen/NWjPzrr
Here's my original if it helps
stackblitz.com/edit/placeholder-shown
Yes. Thank you. This explains why what you have in your article was not working for me. Maybe you should add this link to your article.