Grow your CSS skills. Land your dream job.

A Whole Bunch of Amazing Stuff Pseudo Elements Can Do

Published by Chris Coyier

It's pretty amazing what you can do with the pseudo elements :before and :after. For every element on the page, you get two more free ones that you can do just about anything another HTML element could do. They unlock a whole lot of interesting design possibilities without negatively affecting the semantics of your markup. Here's a whole bunch of those amazing things. A roundup, if you will1.

Give you multiple background canvases

Because you can absolutely position pseudo elements relative to their parent element, you can think of them as two extra layers to play with for every element. Nicolas Gallagher shows us lots of applications of this, including multiple borders, simulating CSS3 multiple backgrounds, and equal height columns.

Expand the number of shapes you can make with a single element

All of the shapes above any many more can be created with a single element, which makes them actually practical. As opposed to those "make a coffee cup with pure CSS!" things which use 1,700 divs, which are neat but not practical.

Here's an example of a six-pointed star:

#star-six {
	width: 0;
	height: 0;
	border-left: 50px solid transparent;
	border-right: 50px solid transparent;
	border-bottom: 100px solid red;
	position: relative;
#star-six:after {
	width: 0;
	height: 0;
	border-left: 50px solid transparent;
	border-right: 50px solid transparent;
	border-top: 100px solid red;
	position: absolute;
	content: "";
	top: 30px;
	left: -50px;

Show URL's of links in printed web pages

@media print {
  a[href]:after {
    content: " (" attr(href) ") ";

Clear floats

Rather than insert extra non-semantic markup to clear the float on container elements, we can use a pseudo element to do that for us. Commonly known as the "clearfix", and more semantically titled with the class name "group".

.group:after {
.group:after {
.group {
    zoom:1; /* For IE 6/7 (trigger hasLayout) */

Simulate float: center;

The float property doesn't actually have a value of center, despite how much we might want it. Float does have left and right though, and by using placeholder pseudo elements we can carve out an area between two columns and place an image there, we can simulate the effect.

Label blocks of code with the language it is in

In the current design of this very site, the blocks of code are labeled with what language of code they are with a pseudo element.

<pre rel="CSS"></pre>
pre:after {
  content: attr(rel);
  position: absolute;
  top: 22px;
  right: 12px;

Create an entire icon set

Nicolas Gallagher again taking the shapes idea to another level by creating a massive set of icons created with no images, only pseudo elements on (at most) two elements each.

Use available space more efficiently

What CSS giveth, CSS can taketh away. What I mean is that pseudo element content can be applied or removed conditionally via media queries. Perhaps you apply an icon when space is limited, and replace that with a more descriptive word when there is more room.

Apply typographic flourishes

If your pseudo elements are text, they inherit the same typographic styles as their parent element. But while you are setting their content, you can style them as well. Like, say, use a different font and a different color to make your headers stand out with a flourish.

h2 {
     text-align: center;     
h2:before, h2:after {
    font-family: "Some cool font with glyphs", serif;
    content: "\00d7";  /* Some fancy character */
    color: #c83f3f;
h2:before {
    margin-right: 10px;
h2:after {
    margin-left: 10px;

Create full browser width bars

When you need elements whose background stretches full width but whose content does not, you are often stuck with non-semantic internal wrapping elements or repetitive and cluttery spacing declarations. Or you can simulate the effect by limiting the content width with one element and making the header bar reach out to the edges with pseudo elements.

Create a body border

Using a regular border on the left and right, and fixed position pseudo element bars on the top and bottom, we can get a "body border" effect without any dedicated markup at all.

body:before, body:after {
    content: "";
    position: fixed;
    background: #900;
    left: 0;
    right: 0;
    height: 10px;
body:before {
    top: 0;
body:after {
    bottom: 0;
body {
    border-left: 10px solid #900;
    border-right: 10px solid #900;

Make a gleaming button

If you make a pseudo element block that has a transparent to white to transparent gradient on it, position it outside of the button (which hides it with hidden overflow), and transition-move it across the button on hover, you can make a button which seems to catch a bit of light as you mouse over it. Only supported for Firefox, Chrome 26+ and IE10+.

Original by Anton Trollb├Ąck; Pseudoelementized by Nicolas Gallagher; Another version by me.

Fade out a page when a particular link is rolled over

If you don't set relative positioning on an element, absolutely positioned pseudo elements will be positioned relative to the next parent that does. If nothing else does, it will be relative to the root element. You can use that to make a full-browser-window element, stack it underneath the main element, and reveal it on hover making a "page fade out" effect on a link.

Style a header like a three dimensional ribbon

Everybody loves ribbons! Check out this snippet for the HTML and CSS for this one. It makes use of negative z-index a bit, which in some cases requires an additional wrapping element to prevent losing the element underneath a parent with an opaque background.

Style the numbers in ordered lists

Have you ever tried to style the numbers in an ordered list? You end up doing dumb stuff like wrapping the insides in spans, styling the list items, then removing that styling with the span. Or using background images in crazy ways. Or removing the list styling and putting in your own numbers. All those ways suck. Much better to utilize pseudo elements as counters.

Make data tables responsive

Large data tables are awful to browse on small screens. Either they are zoomed in and require both vertical and horizontal scrolling, or they are zoomed out and too small to read. We can combine CSS media queries with pseudo elements to make the data table responsive and reformat it to a more readable view when on small screens.

Create styled tooltips

Using an HTML5 data attribute, then pulling that attribute in and styling it as a pseudo element, we can create completely custom tooltips through CSS.

1 Normally roundups are kinda looked down upon around here, in favor of creating more original content. But I feel like this one is beneficial in showing off and hopefully garnering more enthusiasm for the awesomeness that is pseudo elements.


  1. Johnathan
    Permalink to comment#

    A lot of good stuff here, looking forward to playing with pseudo more.

  2. Awesome tutorials. Thanks!!

  3. Excellent post! I am trying to learn css, and although the substance of this article is a bit over my head, I know enough to see the utility of what you’re doing. Thanks for the tips!

  4. abaloo
    Permalink to comment#

    WOW! Stunning piece. Thank you.

  5. Chrome 12 (Stable channel), the titles are covering up the pictures below them. Other than that though its a great piece of info :)

    • Brendan
      Permalink to comment#

      .one-thing h3 {
      margin: 0 0 -38px 0;

      That seems to be the culprit. I’m on Chrome 12 and seeing the same

    • intended. Apparently it didn’t turn out as cool as i thought it would.

    • tommy
      Permalink to comment#

      i must admit, i noticed this too and checked it in chrome before deciding it was intentional. :)

    • Ethan
      Permalink to comment#

      Just to throw my tuppence in, I thought it was kind of a clever idea. It didn’t occur to me that it might be unintentional.

  6. Permalink to comment#

    Absolutely brilliant. Using non-semantic markup for clearfloats has always bothered me, and the simulated float: center is ingenuous.

  7. thomas
    Permalink to comment#

    wow awesome stuff here

  8. Sam
    Permalink to comment#

    Nice– albeit intimidating– list. I’ve let my limited skills get rusty. Sigh.

    On a for what it’s worth note:

    Who’s is a contraction for Who is.

    The word you want here is whose (“elements who’s background stretches full width but who’s content does not”).


  9. Jonathan
    Permalink to comment#

    Awesome stuff! How’s the browser support? Aside from ones specifically mentioned like the Gleaming button Firefox support, could these be used in a production environment?

  10. This article is very exciting, I’m going to try all of them out when I get home!

  11. The original gleaming button demo seems okay in Chrome 12, though not the latter ones (which isn’t surprising, given the mention of FF4+ only right now).

    That’s a pretty slick effect. :D

  12. Permalink to comment#

    your mom.. is hot. haha

  13. Josh
    Permalink to comment#

    Great post!

    Decided to play around with the pure CSS tooltips that you linked to, but noticed a few issues in older browsers (i.e. IE).

    Decided to troubleshoot and came up with this.

    What do you think? First time really digging into solving CSS browser support issues so it wouldn’t surprise me if I have made some glaring errors!

  14. igor goldny
    Permalink to comment#

    awesome post :)
    too bad firebug have no support editing this kind of stuff.

    and some of them not working on ie.

  15. Mark
    Permalink to comment#

    This stuff is delicious!

    F*** ie!

  16. Really loving the idea of the typographic flourishes never even thought of taking that approach

  17. Great list with some useful tricks I have never heard before. Thanks!

  18. Ray
    Permalink to comment#

    Really, this is a hot post. Love it. Keep on the good work!!

  19. Chrish spelling mistake,
    All of the shapes above any many more can
    in link (and many more) used any for and.
    Any ways nice collection

  20. bleicher
    Permalink to comment#

    Opera 11 does support transition on pseudo-elements as well (nice effect btw) , its not only FF4-5

  21. Hey Chris,

    I caught your talk at MinneBar this year on the pseudo-element topic. Great stuff, keep it coming.

  22. Minor nitpick regarding rel="CSS": CSS is not a valid link relation. It would probably be better to use a custom data-* attribute instead.

    • Yeah… I was kind of thinking of it as “this code is RELated to the language of ____”. Maybe the entire world will bend to my will and allow it.

  23. You can also target selectors to mess around with the “shadow DOM” of elements (which are now inspectable in Chrome). For instance, you can target the slider on input type=”range” with ::-webkit-slider-thumb. I took it a bit too far, implementing the iPhone unlock slider by abusing it :) – see my post (sorry, self-promotion, but it’s relevant!)

  24. Ryan Dunn
    Permalink to comment#

    When oh when will we get unlimited pseudo elements, it makes such perfect sense in the doctrine of separating content and markup. Maybe one day~

  25. All I can say is wow Chris, simply wow. I had no idea that CSS is as powerful as it is, color me impressed. Also love the way you present information like this it makes it that much easier to follow and endure and it’s nice to have some good old fashioned humor thrown in for good measure.

  26. Simply great stuff, really creative idea to use them..

  27. Pseudo tooltip need extra topping; visibility: visible/hidden.

  28. Uli
    Permalink to comment#

    Been there, done that….

  29. Permalink to comment#

    Inspired by your ideas here, I made a proof-of-concept flipbook animation in pseudo elements.

  30. Great post. I like the feature to be able to show urls in printed pages.
    what are the browsers supports these features?

  31. I made a little website for you to create simple, only-CSS (with ::before and ::after) 3D ribbons, soiheardyouliekribbon.

  32. Aww… wish you’d included my progress bars ( in your post… great post anyway though Chris.

  33. Zander

    Really awesome post, so useful. Thanks Chris

  34. Quite a lot of nice ideas, but also examples which should not be used in real life sites. Content MUST be written in the HTML document. CSS is for styling ONLY. Everything else is just… – playground stuff.

    Anayway: nice collection!

  35. Thank you for collecting these and putting them together on a single page!

  36. @Chris: Somethings not working here?!? I am trying to answer you – of course you are right. Everythings fine (if you do not count, that I – as a user, not a developer) do NOT like responsive design.

  37. Very good article actually
    I think adding pseudo spriting section to this article may be a good idea :)

  38. Nickm
    Permalink to comment#

    The counting using the :after stuff is amazing. Loved this write up, thanks!

  39. Permalink to comment#

    Amazing list. I’m thinking of using :after to create line under header text, which will be shorter in width than text.

  40. Edel
    Permalink to comment#

    Never thought about doing tricks like this, pretty cool!

  41. Abishek R
    Permalink to comment#

    Amazing write up! It really helped me a lot. Thanks !!!

  42. Abishek R
    Permalink to comment#

    Chris is there any difference between :after & ::after

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".