In this tutorial I talk about Pseudo elements. There are lots of use cases for these elements and in this tutorial I demonstrate one use which is to add a special character to menu items that have sub-menus hidden underneath them.

See the Pen Psuedo-Elements by Lisa Catalano (@lisa_c) on CodePen.

Preferred Learning Method?

Code Snippets
If you just want the code and don’t need a description.

Watching a Video
If you like being shown how something works with some explanation watch the video.

Reading a description
If you learn better by reading, I am including the transcript of the video with corresponding code snippets embedded.


If you would like to follow along with the video:

Starting code here

Code Only

See the Pen Psuedo-Elements by Lisa Catalano (@lisa_c) on CodePen.

See the Pen Psuedo-Elements by Lisa Catalano (@lisa_c) on CodePen.


Pseudo-elements are a way to add actual content to your page using CSS only. Of course, in normal circumstances you want your content to be found in the HTML. But there are plenty of use-cases for psuedo-elements where you might want to add something to the page for presentational reasons.

One example is in the Drop Down Navigation that I created in my last tutorial. If we look at the menu, there are two menus with drop down sub-menus that are only displayed when you hover over the menu. There is nothing to indicate to the user that there are more options underneath.

I’m starting with the code from my Drop Down Navigation example. I am going to add a class name to any menu items with a sub-menu. I’ll just call it sub.

Now I can target those items with .sub.

If I add the ::after to the sub selector I will be able to add some content “after” the selector.

I do that by specifying content as the property, and then whatever I want to add as the value, inside quotes. Whatever I type, will get added after the selector that I’m targeting.

This is not really what I want. If I open the Developer Tools, and inspect the item… I do need to refresh the page so I can look without the Live Preview hooks in here. Now we can see this element ::after at the end of the of the li tags with a class of sub. It comes after the sub menu which is why we see it on a new line. We don’t actually see the > that I added, we see the element “::after”. The > comes from the CSS which you can see when you look at the element’s styles.

I really want this to be added at the end of the anchor tag, like this.

You might wonder why not just add it directly to the HTML. Well of course you can do that, but if you have a really complex navigation that changes, it is easier to target all of the menus that need the character with a class name, like ‘sub’ instead of having to update the HTML every time your menu structure changes.

This content could be anything. It could be many characters or an image that you specify with a url.

I’d like this to be a triangle instead of a > symbol. We can use a character for that instead of an image.

There is a nice website that shows you symbols that are available to use using character codes.

If I search for right triangle, I have lots of options. I want to use this small right pointing triangle.

It is telling me the Unicode character, but if I put that in the content it won’t work. It will just display those characters.

We can see the HTML entity, but that doesn’t work here either. We could use that if we were adding the content directly to the HTML, but if we used it here it would just display the characters.

Instead, if I scroll down and find the Source Code section it tells me the way to represent this character in CSS. Basically it is the same number from above “25B8” with a \ 0 in front of it instead of the U+.

So if I make that the content, it works. We see a nice right-triangle right there.

One of the nice things about psuedo-elements is that they can be styled. I’d like to move the triangle over just a bit, so I can add a margin-left of 3px and the character will have a little breathing room.

  .sub a::after {
    content: "025B8";
    margin-left: 3px;

I could change the color also if I wanted.

color: hotpink;

I’d like to change the character to be pointing downward on hover. We could handle that by tranforming the character with a rotate, or we could just find a downward facing triangle to set as the content.

I’ll search for “down triangle” and I can use this character.

I want to target .sub:hover a::after and I can assume the CSS version of this character is \0 plus the characters I copied.

  .sub:hover > a::after {
    content: "25BE";

Now when we hover, the we can see the character change.

I need to fix my selectors so the triangle only gets added to the top anchor tags. I can do that by adding the > to my selector so only anchor tags that are direct descendents of .sub will be targeted.

  .sub > a::after {
    content: "025B8";
    margin-left: 3px;

  .sub:hover > a::after {
    content: "25BE";

Now I’ve been talking about ::after, but there is also a ::before pseudo-element, which as you might guess will add some content right before your element. It works exactly the same.

I mentioned already that you can use an image for the content insert.

I could add an image before my navigation items by specifying a url for the content. I’m using the direct descendent selector again so I don’t get the sub menu items.

  .nav > ul > li > a::before {
    content: url(;
    margin-right: 3px; 

I don’t really want this image, but just wanted to demonstrate how that works. This technique could be used for navigational icons.

So that’s a quick look at pseudo-elements. You probably don’t want to use them to insert real content into your web-sites, but for adding some presentational elements or decoration, they can be very useful. There are many interesting things that have been done using these elements and you can find many examples all over the web.

One of the most common uses is to use an ::after element as a clearfix solution when you are using floats. I have talked about that solution in a previous tutorial, called Clearfix Solution.

If you have any questions, please let me know.

Leave a Reply

Your email address will not be published. Required fields are marked *