I recently learned about the pseudo CSS class :placeholder-shown. Obviously, it is a class that is added only when input placeholder is shown. But what that also means is that the input is empty:
/* Input is empty */
By negating it with :not()
we can detect if the input has value:
/* Input has value */
I created a demo that uses these two CSS snippets to highlight input's current state. There is no JavaScript involved.
Real world use cases
I recently used this to conditionally display a clear button next to an input. But it can also be used to create floating labels.
However, it's important to note that anything you want to style based on the input's state needs to be positioned after the input element.
Floating labels
For a floating label, the HTML structure should look something like this:
Floating label
The floating label needs to be repositioned in two scenarios: when the input is focused and when it has a value.
/* Input has value */
}
Clear button
Similarly, we'll put the clear button after the input:
Clear
and hide it when input is empty:
/* Input is empty */
}
Demo
Focus an input to make its label float, and type something to make the clear button appear.
You can also play with the code on CodePen.
Safari gotcha
Be aware that in Safari the :placeholder-shown
pseudo class will only be added if the input has the placeholder attribute explicitly defined.
Which means that we have to define it, but if we don't need the placeholder, we can easily hide it using CSS:
}