Save 10% on our Pro WordPress plugins with discount code: 10PERCENT
Web Dev + WordPress + Security

CSS: Odd Bug with Colons and Combined Pseudo Elements

According to specification (and these helpful posts by Chris Coyier), CSS pseudo elements like ::before and ::after should be written with two preceding colons. It can be confusing because while pseudo elements are prefixed by two colons, like ::element, pseudo selectors (aka pseudo classes) are prefixed by only one, like :selector. So that’s the context for an odd little CSS bug..

Odd CSS bug

Update: Thanks to Chris Coyier for pointing out that :last-child actually is a pseudo-selector, not a pseudo-element. Post updated accordingly.

Many browsers continue to support the double-colon prefix for pseudo-elements pseudo-selectors, for example:

li::last-child { margin-right: 0; }

That works fine in most browsers, but does not work when combined with pseudo elements like ::before and ::after. So if you do this:

li::last-child:after { content: ''; }

..it won’t work. And likewise using the double-colon syntax :: for both selectors, for example like this:

li::last-child::after { content: ''; }

Also doesn’t work. For some reason, at least with webkit browsers (e.g., Chrome, Opera, Safari, and many others), in order to combine pseudo elements, you need to use the single-colon syntax for the first element:

li:last-child:after { content: ''; }

..works as expected. Interestingly enough, this works as well:

li:last-child::after { content: ''; }

The take home message: if you’re combining pseudo elements, the first pseudo element must be single-colon prefixed. It doesn’t matter (apparently) on the second pseudo element.

To help visualize slash summarize all of this, I put together a simple demo for combined pseudo elements »

Btw, here is the W3 specification for combining pseudo elements.

Not sure if that is reason enough to stick with single-colon syntax on pseudo elements or not. Maybe it’s a bug? After reading Chris’ article, I wanted to be consistent and use double colons everywhere. But I also need to use combined pseudo elements once in awhile. So do I use both single and double colons? Or stick with single-colon syntax because it always works? Or stick with specification and use only double colons, thereby forfeiting use of any combined pseudo selectors?

Any thoughts or insights welcome :)

Jeff Starr
About the Author
Jeff Starr = Fullstack Developer. Book Author. Teacher. Human Being.
BBQ Pro: The fastest firewall to protect your WordPress.

3 responses to “CSS: Odd Bug with Colons and Combined Pseudo Elements”

  1. While I’m all about best practices, I like to keep things simple, if I can… so I think sticking with :single:single is fine, as long as it continues to function. If it breaks in the future, clients will come running. =)

  2. I thiiiiink the issue here is that like li::last-child is not a pseudo-element, it’s a pseudo selector. So it shouldn’t ever use the double-colon syntax like ::after does. The fact that it ever works with two colons is probably the “bug”, but I can’t super blame browsers for supporting it because I bet there are a ton of sites that mistakenly use it and it would break them to stop.

    • Jeff Starr 2021/07/18 10:37 am Reply

      Yes, looks like I was confused about :last-child being a pseudo-element. You’re right it’s a pseudo-selector/pseudo-class. So the “bug” now makes more sense, thanks for your wisdom Chris.

Leave a Reply to Tony Scialdone Cancel

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
W3C.org has a very thorough list of accessibility tools.
The more you wake up, the more you realize you are still asleep.
7G Firewall v1.4 now available!
I would pay twice as much for a shorter/smaller/lighter phone.
Taking a much needed break in August :)
The Web was better before social media.
WP 5.8 Gutenberg/Block Widgets is breaking many sites. Fortunately Disable Gutenberg makes it easy to restore Classic Widgets with a click.
Newsletter
Get news, updates, deals & tips via email.
Email kept private. Easy unsubscribe anytime.