{"id":276762,"date":"2018-10-05T06:45:01","date_gmt":"2018-10-05T13:45:01","guid":{"rendered":"http:\/\/css-tricks.com\/?p=276762"},"modified":"2020-12-14T09:01:58","modified_gmt":"2020-12-14T17:01:58","slug":"one-invalid-pseudo-selector-equals-an-entire-ignored-selector","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/one-invalid-pseudo-selector-equals-an-entire-ignored-selector\/","title":{"rendered":"One Invalid Pseudo Selector Equals an Entire Ignored Selector"},"content":{"rendered":"\n

Perhaps you know this one: if any part of a selector is invalid, it invalidates the whole selector. For example:<\/p>\n\n\n\n

div, span::butt {\n  background: red;\n}<\/code><\/pre>\n\n\n\n

Even though div<\/code> is a perfectly valid selector, span:butt<\/code> is not, thus the entire selector is invalidated \u2014 neither divs nor span::butt<\/code> elements on the page will have a red background.<\/p>\n\n\n\n\n\n\n\n

Normally that’s not a terribly huge problem. It may even be even useful, depending on the situation. But there are plenty of situations where it has kind of been a pain in the, uh, :butt<\/code>.<\/p>\n\n\n\n

Here’s a classic:<\/p>\n\n\n\n

::selection {\n  background: lightblue;\n}<\/code><\/pre>\n\n\n\n

For a long time, Firefox didn’t understand that selector, and required a vendor prefix (::-moz-selection<\/code>) to get the same effect. (This is no longer the case in Firefox 62+<\/a>, but you take the point.)<\/p>\n\n\n\n

In other words, this wasn’t possible:<\/p>\n\n\n\n

\/* would break for everyone *\/\n::selection, ::-moz-selection {\n  background: lightblue;\n}<\/code><\/pre>\n\n\n\n

That would break for browsers that understood ::selection<\/code> and break for Firefox that only understood ::-moz-selection<\/code>. It made it ripe territory for a preprocessor @mixin<\/code>, that’s for sure.<\/p>\n\n\n\n

Here’s another zinger. <\/p>\n\n\n\n

\/* For navigation with submenus *\/\nul.submenu {\n  display: none;\n}\n\nul.menu li:hover ul.submenu,\nul.menu li:focus ul.submenu,\nul.menu li:focus-within ul.submenu {\n  display: block;\n}\n\n\/* Oh no! We've broken all menu functionality in IE 11, \n   because it doesn't know what `:focus-within` is so it\n   throws out the entire selector *\/<\/code><\/pre>\n\n\n\n

This behavior is annoying enough that browsers have apparently fixed it going forward. In a conversation with Estelle Weyl<\/a>, I learned that this is being changed. She wrote in the MDN docs<\/a>:<\/p>\n\n\n\n

Generally, if there is an invalid pseudo-element or pseudo-class within in a chain or group of selectors, the whole selector list is invalid. If a pseudo-element (but not pseudo-class) has a -webkit-<\/code> prefix, As of Firefox 63, Blink, Webkit and Gecko browsers assume it is valid, not invalidating the selector list.<\/p><\/blockquote>\n\n\n\n

This isn’t for any selector; it’s specifically for pseudo-elements. That is, double colons<\/a> (::<\/code>).<\/p>\n\n\n\n

Here’s a test:<\/p>\n\n\n\n