Search code examples
csscross-browservendor-prefix

Using multiple vendor-specific CSS selectors at once


I'm styling placeholder text, and need to use several vendor-prefixed selectors so that it works in different browsers. When I put each of them as a separate code block, it works. However, if I use a comma-separated list of selectors instead of repeating the same CSS for each of them, it won't work. Can anyone explain?

This works:

input[type=text]::-webkit-input-placeholder {
    color: green;
}
input[type=text]::-moz-placeholder {
    color: green;
}
input[type=text]:-ms-input-placeholder {
    color: green;
}
input[type=text]:-moz-placeholder {
   color: green;
}
<input type="text" placeholder="Placeholder Text" />

But this doesn't:

input[type=text]::-webkit-input-placeholder,
input[type=text]::-moz-placeholder,
input[type=text]:-ms-input-placeholder, 
input[type=text]:-moz-placeholder {
	    color: green;
}
<input type="text" placeholder="Placeholder Text" />

Why?


Solution

  • Unfortunately, you can't.

    When a selector that the browser does recognise as valid is found, it stops execution of the code block following it.

    Only one of the vendor-prefixed selectors you are using will exist in each browsers (for example WebKit browsers do not have the Mozilla and Microsoft vendor-prefixed selectors); therefore you will never be able to execute that block as there is no browser where all three pseudo-selectors are valid.

    However...

    ... you can simply use three different blocks. For example, this should work:

    input[type=text]:focus::-webkit-input-placeholder {
      color: green;
    }
    
    input[type=text]:focus::-ms-input-placeholder {
      color: green;
    }
    
    input[type=text]:focus::-moz-placeholder {
        color: green;
    }
    <input type="text" placeholder="Hello, world!">

    If you have a lot of code, you could use a preprocessor like LESS or SASS to dynamically put the same code inside each block.