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.
Top comments (8)
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.
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.
Cool features