Pure CSS 3D ribbon

In a recent project I set myself the challenge of creating a pure CSS ribbon effect using as little markup as possible. Why? I’m big on progressive enhancement and love how css3 empowers us to create attractive UIs without using hefty imagery. You can see the result in this jsFiddle;

The ribbon is achieved using a single block level element with the class ribbon wrapped around a child element with the class ribbon-content. In this example I’ve used a paragraph containing a strong tag to demonstrate how semantic the code can be.

<p class="ribbon">
    <strong class="ribbon-content">Everybody loves ribbons</strong>
</p>

Creating the ribbony bits involves a nifty use of the :before and :after pseudo elements and some creative border properties:

.ribbon {
  font-size: 16px !important;
  /* This ribbon is based on a 16px font side and a 24px vertical rhythm. I've used em's to position each element for scalability. If you want to use a different font size you may have to play with the position of the ribbon elements */

  position: relative;
  background: #ba89b6;
  color: #fff;
  text-align: center;
  padding: 1em 2em; /* Adjust to suit */
  margin: 0 0 3em; /* Based on 24px vertical rhythm. 48px bottom margin - normally 24 but the ribbon 'graphics' take up 24px themselves so we double it. */
}
.ribbon:before, .ribbon:after {
  content: "";
  position: absolute;
  display: block;
  bottom: -1em;
  border: 1.5em solid #986794;
  z-index: -1;
}
.ribbon:before {
  left: -2em;
  border-right-width: 1.5em;
  border-left-color: transparent;
}
.ribbon:after {
  right: -2em;
  border-left-width: 1.5em;
  border-right-color: transparent;
}
.ribbon .ribbon-content:before, .ribbon .ribbon-content:after {
  content: "";
  position: absolute;
  display: block;
  border-style: solid;
  border-color: #804f7c transparent transparent transparent;
  bottom: -1em;
}
.ribbon .ribbon-content:before {
  left: 0;
  border-width: 1em 0 0 1em;
}
.ribbon .ribbon-content:after {
  right: 0;
  border-width: 1em 1em 0 0;
}

It’s well worth getting your head around how this actually works – there are all kinds of opportunities to create semantic visual elements using this technique.

As the comment within the CSS describes, it’s important to understand that this ribbon is based on a 16px font size and a 24px vertical rhythm. All of the ribbony “graphics” are based on that particular font size to ensure a robust vertical rhythm. If you wan’t to change the font size you may need to adjust the positioning of the ribbon graphics to get it looking just right. Not a big task, but something to remember if you decide to implement this ribbon with your own chosen font size.

With some creative negative margins it’s possible to create some really cool effects with this 3d ribbon. The main body of the ribbon is a standard block level html element so it’s also possible to apply additional border styles, background images, gradients, textures etc too.

Have fun!

Caveat: This technique requires the use of a negative z-index on some of the pseudo elements. This means that if the ribbon is placed inside an element with a background colour it’s appearance will be broken.

To remedy this simply wrap the ribbon inside another element and apply the following styles to that element;

position: relative; 
z-index: 1;

Edit: This post was featured on CSS-Tricks.