GitHub Ribbon Using CSS Transforms

Do you know when Tom Preston-Werner released the ‘Fork me on GitHub’ ribbons that you often see on websites for open-source projects? It was December 2008! Man I feel old…

I like the idea behind the ribbon. It’s an easy way of telling your users that this software is open-source, and that there’s a repo available for them to browse and fork. Using an image for the ribbon though? I don’t like that at all, for multiple reasons:

  • Changing things like the font or the colors of the ribbon is really inconvenient, as it forces you to fire up an image editor.
  • Including this image on your page means an additional request, and about 8KB of payload.
  • You have to be careful with the positioning of the image, as it’s a pretty big square, and you don’t want it to block part of your site’s navigation.
  • You have to think about generating and serving a high-definition version if you don’t want your ribbon to look all pixelated on HiDPI devices.

The site for Thoughtbot’s Neat project showcases the last two problems perfectly:

Problems with the ribbon image in Neat's website

Yeah, it looks really bad on a HiDPI screen. But most important, with certain viewport widths, the ribbon overlaps one of the main navigation buttons in the page, making it quite difficult to press. This could be ammeliorated with image maps, so that only the actual ribbon is clickable, but I think we can do better…

What if I told you we can replicate the ribbon in pure HTML and CSS? Easy styling! No extra requests! Reasonably sized clickable areas! No @2x images! I would sound like a late-night infomercial, wouldn’t I? But it’s all true, check out the demo.

Step by step

First of all, let’s deal with the HTML. We just need an extra div tag surrounding the link to our GitHub page:

<div class="ribbon">
  <a href="#">Fork me on GitHub</a>
</div>

Now let’s try to replicate the look of the ribbon with some basic CSS:

.ribbon {
  background-color: #a00;
  overflow: hidden;
  white-space: nowrap;
}
.ribbon a {
  border: 1px solid #faa;
  color: #fff;
  display: block;
  font: bold 81.25% 'Helvetica Neue', Helvetica, Arial, sans-serif;
  margin: 1px 0;
  padding: 10px 50px;
  text-align: center;
  text-decoration: none;
}

The only rules that may catch your eye are those overflow: hidden and white-space: nowrap. They are there just to avoid the text spanning two lines.

Also, the typeface used for the original GitHub ribbon is Collegiate. I went with Helvetica instead, but feel free to experiment with @font-face if you want to stay faithful to the original design.

Here is what we’ve got:

Ribbon with basic styles

To achieve the rotation effect, we’ll use the transform property. It’s still being standardized, so we’ll have to fall back to browser-specific declarations (-webkit-transform for Safari 3.1+, -moz-transform for Firefox 3.5+, etc.):

.ribbon {
  ...
  position: absolute;
  left: -50px;
  top: 40px;
  -webkit-transform: rotate(-45deg);
     -moz-transform: rotate(-45deg);
      -ms-transform: rotate(-45deg);
       -o-transform: rotate(-45deg);
          transform: rotate(-45deg);
  ...
}

We are applying a counterclockwise rotation of 45 degrees, and using the top and left properties to place the ribbon in the upper left corner of the page.

We should be looking at something similar to this:

Ribbon with rotation

Let’s give the ribbon its final touches by using the text-shadow and box-shadow properties. The latter is also being standardized, so again we have to fall back to browser-specific declarations (-webkit-box-shadow for Safari 3.0+, -moz-box-shadow for Firefox 3.5+, etc.):

.ribbon {
  ...
  -webkit-box-shadow: 0 0 10px #888;
     -moz-box-shadow: 0 0 10px #888;
          box-shadow: 0 0 10px #888;
  ...
}
.ribbon a {
  ...
  text-shadow: 0 0 5px #444;
}

If you take a look at the documentation for those two properties, you’ll see we’re using shadows with no offset and a slight blur.

The result:

Ribbon with final touches

It’s not identical to the original, but I think it’s a good enough approximation.

Summing up

This is all the CSS we used to build the ribbon:

.ribbon {
  background-color: #a00;
  overflow: hidden;
  white-space: nowrap;
  /* top left corner */
  position: absolute;
  left: -50px;
  top: 40px;
  /* 45 deg ccw rotation */
  -webkit-transform: rotate(-45deg);
     -moz-transform: rotate(-45deg);
      -ms-transform: rotate(-45deg);
       -o-transform: rotate(-45deg);
          transform: rotate(-45deg);
  /* shadow */
  -webkit-box-shadow: 0 0 10px #888;
     -moz-box-shadow: 0 0 10px #888;
          box-shadow: 0 0 10px #888;
}
.ribbon a {
  border: 1px solid #faa;
  color: #fff;
  display: block;
  font: bold 81.25% 'Helvetica Neue', Helvetica, Arial, sans-serif;
  margin: 1px 0;
  padding: 10px 50px;
  text-align: center;
  text-decoration: none;
  /* shadow */
  text-shadow: 0 0 5px #444;
}

It’s practically begging to be turned into a Less or Sass mixin, so that you can pass the color of the ribbon as a parameter, and maybe its position too… But I’ll leave that as an exercise to you, dear reader.

Browser support

You saw this one coming, didn’t you? Some of those awesome properties we were using are only available on modern browsers:

  Chrome Firefox IE Opera Safari
-webkit-transform 4.0+ No No 15.0+ 3.1+
-moz-transform No 3.5+ No No No
-ms-transform No No 9.0+ No No
-o-transform No No No 10.5+ No
transform No 16.0+ 10.0+ No No
-webkit-box-shadow 4.0+ No No No 3.1+
-moz-box-shadow No 3.5+ No No No
-ms-box-shadow No No No No No
-o-box-shadow No No No No No
box-shadow 10.0+ 4.0+ 9.0+ 10.5+ 5.1+
text-shadow 4.0+ 3.5+ 10.0+ 9.5+ 3.1+
  4.0+ 3.5+ 10.0+ 10.5+ 3.1+

If you don’t give a flying fairy about old versions of Internet Explorer, then go for it! Forget about images, and bask in the delights of pure HTML and CSS!