In this post
Most modern browsers support the simple pseudo-element:
::placeholder {
color: #9400d3;
}
but what if you need to apply color to a placeholder in older browsers?
WebKit, Blink, and Edge #
WebKit, Blink (Safari, Google Chrome, Opera 15+), and Microsoft Edge are using a pseudo-element ::-webkit-input-placeholder
::-webkit-input-placeholder {
color: #9400d3;
}
Mozilla Firefox 4 to 18 #
Using a pseudo-class: :-moz-placeholder
:-moz-placeholder {
color: #9400d3;
opacity: 1;
}
Firefox’s placeholder appears to be defaulting with reduced opacity, so needs to use opacity: 1 here.
Mozilla Firefox 19+ #
Using a pseudo-element: ::-moz-placeholder, but the old selector will still work for a while.
::-moz-placeholder {
color: #9400d3;
opacity: 1;
}
Internet Explorer 10-11 #
Using a pseudo-class: :-ms-input-placeholder
:-ms-input-placeholder {
color: #9400d3;
}
Do you still need the prefixes? #
Probably not. The unprefixed ::placeholder works in Chrome 57+, Firefox 51+, Safari 10.1+ and Edge 79+, according to MDN’s compatibility data. The prefixed rules above only matter if you still support Internet Explorer or the old Edge (versions 12 to 18).
Keep each prefixed selector in its own rule #
It is tempting to merge the rules into one selector list. Don’t. When a browser meets a selector it does not recognize, it throws away the whole rule, including the selectors it does know:
/* Chrome drops this entire rule because it doesn't know :-ms-input-placeholder */
input::placeholder,
input:-ms-input-placeholder {
color: #9400d3;
}
In current Chrome, the grouped rule left the placeholder at the browser’s default gray, while two separate rules gave it the new color. That is why every snippet above is its own block.
Set the color explicitly #
Browsers ship different default placeholder colors. MDN notes that Firefox shows the input’s text color at 54% opacity, while Chrome uses a gray. If you want the same color everywhere, set color yourself, as the examples here do.
Contrast and labels #
Placeholder text is still text, so it needs enough contrast against the input background. WCAG AA asks for 4.5:1 for normal-size text. The purple used here, #9400d3, comes out at about 6.6:1 on white, so it passes.
A placeholder also disappears as soon as someone starts typing, so it can’t replace a label. Keep a real <label> and use the placeholder for an example value:
<label for="email">Email</label>
<input id="email" type="email" placeholder="jane@example.com" />



