Code

Useful Examples of CSS Pseudo-Classes :before and :after

Put simply, CSS pseudo-classes a way to append styles that relate to existing elements. (Here’s a much more complex description.) They’ve been around awhile and browser support is pretty good. Common examples include :hover and :first-child.

Beyond these simple examples, pseudo-classes can be really powerful. For example, you can use CSS to generate content in the document tree through the :before and :after pseudo-classes. This means you can add design elements to your page, such as icons, quotes, borders, and more, without muddying up your markup. This helps keep content and style separate, making design changes easier and more manageable by not mixing site components.

Below are a few examples I’ve found useful or inspiring.

Creative borders

Say you want a border to lay under your element or have it only be half the width of your element. Without resorting to some delicate CSS trickery, or adding a presentational-only element to your DOM (yuck), this can be difficult to accomplish.

With :before and :after you can create a new element and add your styles to it. This gives you a lot more flexibility with your borders and, of course, doesn’t muddy up your markup.

Inspired by Frank Chimero, this border sits behind the quote and dynamically adjusts to the width of the container.

But I will wear my heart upon my sleeve
For daws to peck at: I am not what I am.
Iago

HTML

<div class="quote">
  <blockquote>But I will wear my heart upon my sleeve<br />
    For daws to peck at: I am not what I am.
    <cite>Iago</cite>
  </blockquote>
</div>

CSS

.quote {
  margin: 0.5rem auto;
  max-width: 30em;
  padding: 2rem 0;
  position: relative;
  z-index: 3;
}

cite {
  color: #666;
  display: block;
  line-height: 1.5;
}

/* Background border */
.quote:before {
  border: 0.8rem solid #333;
  bottom: 0;
  content: "";
  display: block;
  left: 20%;
  position: absolute;
  right: 20%;
  top: 0;
  z-index: -1;
}

.quote blockquote {
  font-weight: 300;
  border: none;
  margin: 0 auto;
  padding: 1rem 0;
  text-align: center;
  font-size: 140%;
  line-height: 1.3;
  font-style: normal;
}

/* Quote mark */
.quote blockquote:before {
  content: '\201c';
  color: #cc3333;
  display: block;
  font-family: Arial, San-serif;
  font-size: 5.5rem;
  font-style: normal;
  font-weight: bold;
  line-height: 0;
  margin: 20px 0 12px;
}

This example of a multicolored border was inspired by elements from the World Wildlife Federation’s excellent website.

IAGO

Iago is a fictional character in Shakespeare’s Othello. The standard bearer of General Othello, Iago hates Othello with a passion (really) and devises a plan to destroy him.

HTML

<figure>
  <h1>IAGO</h1>
  <p>Iago is a fictional character in Shakespeare's Othello. The standard bearer of General Othello, Iago hates Othello with a passion (really) and devises a plan to destroy him.</p>
</figure>

CSS

figure {
  border: 0.2rem solid #666;
  display: block;
  position: relative;
  margin: 0 auto;
  padding: 24px 30px;
  width: 300px;
}

figure::before { top: -0.2rem; }
figure::after { bottom: -0.2rem; }

figure::before,
figure::after {
  border-left: 1rem solid #222;
  border-right: 1rem solid #222;
  background: #cc3333;
  content: "";
  display: block;
  height: 0.2rem;
  left: 50%;
  margin-left: -2rem;
  position: absolute;
  width: 2rem;
}

figure h1 {
  letter-spacing: .25rem;
  margin: 0 0 20px 0;
  text-align: center;
}

figure p {
  line-height: 1.5;
  margin: 0;
}

Adding images

Adding images via pseudo-classes is also quite easy, and similarly an easy way to add design elements without adding more markup.

Using this method, instead of adding the image as a background, makes it easier to style the image as a separate element, which is particularly useful when using image sprites. Plus, you’ll gain additional flexibility in case you want to swap out the images for media queries or high pixel density screens.

HTML

<ul>
  <li class="claudius"><a href="#">Claudius</a></li>
  <li class="aaron"><a href="#">Aaron the Moor</a></li>
  <li class="richard"><a href="#">Richard III</a></li>
</ul>

CSS

ul {
  font-size: 150%;
  letter-spacing: 0.25rem;
  margin: 0 auto;
  padding: 0;
  display: table;
}

ul li {
  font-weight: bold;
  list-style: none;
  margin-bottom: 1.2rem;
}

ul li:last-child {
  margin-bottom: 0;
}

ul li a {
  color: white;
  text-decoration: none;
  text-transform: uppercase;
}

ul li:before {
  background-image: url(http://www.darrenkrape.com/i/articles/pseudoclasses/shakespeare-icons.png);
  background-position: top left;
  background-repeat: no-repeat;
  content: " ";
  display: inline-block;
  height: 30px;
  vertical-align: middle;
  width: 44px;
}

ul li.aaron:before { background-position-y: -30px; }
ul li.richard:before { background-position-y: -60px; }

Menu dividers

In menus and lists, adding a divider can make it easier for users to see where each element begins and ends. However, if you add these directly to your markup, it will be more difficult to adjust how they look in different situations. For example, you want them to show on the desktop but not when viewed on mobile. You could hide them via a media-query, but they’ll still be cluttering your markup.

On this site, I’ve added the dividers in my top menu via pseudo-classes. Since these are newly generate elements, I can also add a transform to get them the exact rotation I’m looking for.

HTML

<ul>
  <li><a href="#">Iago</a></li>
  <li><a href="#">Macbeth</a></li>
  <li><a href="#">Tamora</a></li>
</ul>

CSS

ul {
  font-size: 150%;
  letter-spacing: 0.25rem;
  margin: 0;
  padding: 0;
  text-align: center;
}

ul li {
  display: inline-block;
  font-weight: bold;
  list-style: none;
  margin: 0;
  padding-right: 1rem;
}

ul li a {
  color: white;
  text-decoration: none;
  text-transform: uppercase;
}

ul li:after {
  content: "\00a0";
  border-right: 2px solid #cc3333;
  display: inline-block;
  margin-left: 1rem;
  padding: 1rem 0;
  transform: rotate(30deg);
  -ms-transform: rotate(30deg);
  -webkit-transform: rotate(30deg);
}

ul li:last-child {
  padding-right: 0;  
}

ul li:last-child:after {
  display: none;
}

These are just a few examples of what you can do with :before and :after pseudo-elements. What are your favorites?

Leave a Reply

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