:placeholder-shown

Avatar of Geoff Graham
Geoff Graham on (Updated on )

The :placeholder-shown pseudo-class selects the input element itself when placeholder text exists in a form input. Think of it as a nice way to distinguish between inputs that are currently showing placeholder text versus those that are not.

input:placeholder-shown {
  border: 5px solid red;
}

The idea behind placeholders

Text-based <input>s and the <textarea> input can have placeholder text. It’s text that is shown when the input is empty, to suggest a possible value. For example, a form asking for a school might have a label for what it’s asking for, but then suggest “Forest Hills Example High School” in the placeholder as an example value:

<label for="school">School Name:</label>
<input placeholder="Forest Hills Example High School" type="text" name="school" id="school">

The difference between :placeholder-shown and ::placeholder

:placeholder-shown is for selecting the input itself when it’s placeholder text is being shown. As opposed to ::placeholder which styles the placeholder text.

Here’s a diagram:

I found this highly confusing as:

  1. the specs only have :placeholder-shown and not ::placeholder
  2. :placeholder-shown can still affect the styling of the placeholder text, since it’s a parent element (e.g. font-size).

Note that :placeholder-shown is a pseudo-class (it’s an element in a particular state) and ::placeholder is a pseudo-element (a visible thing that isn’t really in the DOM). Distinguishable by single-versus-double colons.

Tab Atkins cleared it up for me via email:

:placeholder-shown, being a pseudo-class, has to select an existing element. It selects the input whenever you’re in the placeholder-showing state. The ::placeholder pseudo-element wraps the actual placeholder text.

If you need to style the placeholder text

Use ::placeholder (actually, use all the crazy vendor prefixes for it) which we have detailed in the Almanac here.

More Information

Browser Support

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

ChromeFirefoxIEEdgeSafari
475111*799

Mobile / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
1231241239.0-9.2