Save 25% on Wizard’s SQL for WP w/ code: WIZARDSQL
Web Dev + WordPress + Security

Better CSS Placeholder

I haven’t seen anyone mention this little CSS tip. All the proprietary vendor-specific placeholder rules now safely can be replaced with just ::placeholder. Seems very useful especially with the ever-increasing emphasis on site performance. The end result is less code and thus faster loading, better SEO and so forth.

Contents

5 second summary

Instead of this widely used monstrous vendor-specific anti-pattern:

::-webkit-input-placeholder {  /* Chrome and Safari */
	color: #777;
	}

:-moz-placeholder {            /* Mozilla Firefox 4 - 18 */
	color: #777;
	opacity: 1;
	}

::-moz-placeholder {           /* Mozilla Firefox 19+ */
	color: #777;
	opacity: 1;
	}

:-ms-input-placeholder {       /* Internet Explorer 10 - 11 */
	color: #777;
	}

::-ms-input-placeholder {      /* Microsoft Edge */
	color: #777;
	}

We now can just write this:

::placeholder { color: #777; opacity: 1; }

And done. That line supports all major browsers. So we just saved some bandwidth and boosted performance in like 2 seconds. Less code, cleaner code. Thanks CSS devs and browser makers.

Tip: In the above code, the opacity property is included for Mozilla because browsers like Firefox decrease the opacity of placeholder colors by default. For more information, check out how to deal with Firefox later in the article.
Note: “All major browsers” excludes IE, which has been retired. We’ll look at how to support IE later in the article.

Code discussion

The above vendor-prefixed anti-pattern is very common even today:

::-webkit-input-placeholder {  /* Chrome and Safari */
	color: #777;
	}

:-moz-placeholder {            /* Mozilla Firefox 4 - 18 */
	color: #777;
	opacity: 1;
	}

::-moz-placeholder {           /* Mozilla Firefox 19+ */
	color: #777;
	opacity: 1;
	}

:-ms-input-placeholder {       /* Internet Explorer 10 - 11 */
	color: #777;
	}

::-ms-input-placeholder {      /* Microsoft Edge */
	color: #777;
	}

Five declaration blocks to style the placeholder element. Looking at it now feels wrong, but alas it did the job, got us through some dark times. And you can still go that route; although a royal mess, that set of rules continues to work just fine if for some reason you need to support very old browsers.

Hmm.. Ironically the actual ::placeholder pseudo-element is not included in the commonly used anti-pattern (although it should have been). Including it would have made for a smoother transition over time.

You might think, combining all the selectors would help, something like:

/* Don't do this it doesn't work */

::-webkit-input-placeholder,
:-moz-placeholder,
::-moz-placeholder,
:-ms-input-placeholder,
::-ms-input-placeholder {
	color: #777;
	opacity: 1;
	}

Unfortunately that syntax is not supported. When it comes to styling the placeholder, you have to define each selector individually. Combining is not allowed. So if you want to customize placeholders for multiple elements, the number of declarations increases by a multiple of five.

Let’s look at an example using my pro WordPress plugin, SAC Pro. I wanted to style the placeholder for two different elements, so would have needed 10 declarations, like:


.sacpro-box  ::-webkit-input-placeholder { color: #777; }
.sacpro-form ::-webkit-input-placeholder { color: #333; }

.sacpro-box  :-moz-placeholder { color: #777; opacity: 1; }
.sacpro-form :-moz-placeholder { color: #333; opacity: 1; }

.sacpro-box  ::-moz-placeholder { color: #777; opacity: 1; }
.sacpro-form ::-moz-placeholder { color: #333; opacity: 1; }

.sacpro-box  :-ms-input-placeholder { color: #777; }
.sacpro-form :-ms-input-placeholder { color: #333; }

.sacpro-box  ::-ms-input-placeholder { color: #777; }
.sacpro-form ::-ms-input-placeholder { color: #333; }

And it just gets crazier the more elements you want to style. So much code for something so simple.

Notice the above CSS rules are all vendor-prefixed selectors, implemented to support placeholder in various browsers until full support is rolled out. Well good news, that day finally has arrived..

A better way..

Fortunately browser support for the actual CSS placeholder selector has improved greatly. In fact, recent versions of all major browsers fully support ::placeholder. So now we can style placeholders with a single golden rule:

::placeholder { color: #777; opacity: 1; }

Compare that with the ol’ vendor-prefix stack. Much less code & easier to maintain.

Or if you need to target placeholder for a specific element, say .example:

.example ::placeholder { color: #777; opacity: 1; }

And to really drive it home, let’s return to the SAC Pro example. It’s now possible to style two separate placeholders using only two lines instead of 10:

.sacpro-box  ::placeholder { color: #777; opacity: 1; }
.sacpro-form ::placeholder { color: #333; opacity: 1; }

Elegant and awesome.

Dealing with Firefox

Note the inclusion of opacity in the above examples. That helps to normalize the color property across browsers. For example, Firefox lowers placeholder opacity by default. This can be addressed directly by including the vendor-specific selector for Mozilla/Firefox:

/* Firefox lowers placeholder opacity by default */
::-moz-placeholder { color: #777; opacity: 1; }

Fortunately it’s NOT necessary to include that vendor-specific rule.

Instead, to address Firefox’s weird placeholder opacity tweaking, simply include opacity when declaring ::placeholder. The color then will be accurate and consistent across all browsers, exactly as specified.

::placeholder { color: #777; opacity: 1; }

Dealing with IE

Internet Explorer (IE) has been retired. Some people are still using IE though. According to this source, IE still enjoys 28 million users in 2023. Read it again.

So to be extra safe for those folks you could do like this. Basically including the IE vendor rule whenever using ::placeholder. For example:

/* All major browsers */
::placeholder { color: #777; opacity: 1; }

/* Internet Explorer */
:-ms-input-placeholder { color: #777; opacity: 1; }

Personally, I’m no longer adding special/extra support for anything IE. Anyone still using IE imho is gonna be just fine without my custom placeholder styles lol.

Tip: You can inspect the shadow DOM to find any applied placeholder styles.

Jeff Starr
About the Author
Jeff Starr = Creative thinker. Passionate about free and open Web.
Blackhole Pro: Trap bad bots in a virtual black hole.

Leave a reply

Name and email required. Email kept private. Basic markup allowed. Please wrap any small/single-line code snippets with <code> tags. Wrap any long/multi-line snippets with <pre><code> tags. For more info, check out the Comment Policy and Privacy Policy.

Subscribe to comments on this post

Welcome
Perishable Press is operated by Jeff Starr, a professional web developer and book author with two decades of experience. Here you will find posts about web development, WordPress, security, and more »
The Tao of WordPress: Master the art of WordPress.
Thoughts
DIY: Monitor File Changes via Cron working perfectly for over a decade.
Mastodon social is a trip. Glad I found it.
As a strict rule, I never use cache plugins on any of my sites. They cause more problems than they solve, imho. Just not worth it.
Currently on a posting spree :)
6 must come before 7.
My top three favorite-to-write coding languages: CSS, PHP, JavaScript.
If you’re not 100% sure that you can trust something, you can’t.
Newsletter
Get news, updates, deals & tips via email.
Email kept private. Easy unsubscribe anytime.