skip navigation

::before and ::after

Notes from a Kevin Powell video

  1. These elements are inside their main element. So p::before is a child of p.
  2. They require the content property. Without it they don’t do anything. But an empty value with two single quotes, content: ''; is fine.
  3. They do not work on images. Images are different from content boxes like divs and p’s.
  4. They are inline by default.
  5. You can only have one ::before and one ::after on each element. For instance if you’re targetting <p class="blue"> you cannot use both p::before and .blue::before. If you do the most specific selector is used.

Images

You can add an image with content: url(//picsum.photos/200/300);

Quotes

To add quotes:

.element::before {
   content: open-quote;
   }
.element::after {
   content: close-quote;
   }

There is also the value no-close-quote. Since the CSS looks for a close-quote after an open-quote you can use this to close a quote without actually displaying a closing quote.

NB. These values are not inside quotes. See the post on blockquotes.

HTML symbols

You can use HTML symbols and Unicode characters for content by using a variant of the Unicode code. So a unicode character might look like: U+02122 for example. To add to the content you remove the U, the + and the first 0 and replace them with a forward slash.

To use the Unicode character U+02122 it looks like this:

p::before {
   content: '/2122';
}

You can obtain this from the hex code value too. The hex code value for the above is &#x2122;

These can be used multiple times and combined with text:

li:nth-child(17)::after {
  content: 'forward \25b6\25b6';
}

Emoji

You can also add Emoji

h2::marker {
  content: '😁⭐👽';
}

Using data attributes

These need to be in the HTML tags and can then be pulled into the pseudo-elements.

<p data-some-key="The data I want to use">

Then in the CSS:

p::before {
    content: attr(data-some-key);
}

You can use any HTML attribute, for instance the class or title attributes: content: attr(class) but remember these pseudo-elements don’t work with images.

Positioning

When positioning an absolutely positioned element to the top you can use bottom: 100%.

Counters

This is slightly more involved but it allows you to add an number increment to any element, the same way an ordered list adds numbers to its child <li>’s. First the HTML.

Suppose you have a <section> where you want a number added to each <h2> element.

  1. Use counter-reset in the CSS of that section tag.
    section {
    counter-reset: some-name;
    }
    
    You can give it any name you like. This resets the count to start at 1.
  2. Next add a ::before pseudo-element to your h2’s. Add the property counter-increment with the value of the counter name above:
    h2::before {
    counter-increment: some-name;
    }   
    
  3. Finally we need to use add the content to our pseudo-element. For this you tell it you want a counter and the counter you want is the one called some-name:
    h2::before {
    counter-increment: some-name;
    content: counter(some-name);
    }
    
    You can add more content if you want to using the single quotes. Here’s adding a dot and space here: counter(some-name) '. '

More stuff

Another vid on ideas to use ::before and ::after including the property isolation: isolate. isolation: isolate is useful when layering with pseudo elements to prevent them going behind their parent elements.