Skip to main content

GitHub Ribbon Using CSS Transforms

You know those ‘Fork me on GitHub’ ribbons that you often see on websites for open source projects? Tom Preston-Werner released them in December 2008! Gosh, 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? Not great, for multiple reasons:

  • Changing things like the font or the colors of the ribbon is 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:

Screenshot showing problems with the ribbon image in Neat’s website

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

What if I told you we could 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’re there 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 left and top 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 look up the docs 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 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:

 ChromeFirefoxIEOperaSafari
-webkit-transform4.0+NoNo15.0+3.1+
-moz-transformNo3.5+NoNoNo
-ms-transformNoNo9.0+NoNo
-o-transformNoNoNo10.5+No
transformNo16.0+10.0+NoNo
-webkit-box-shadow4.0+NoNoNo3.1+
-moz-box-shadowNo3.5+NoNoNo
-ms-box-shadowNoNoNoNoNo
-o-box-shadowNoNoNoNoNo
box-shadow10.0+4.0+9.0+10.5+5.1+
text-shadow4.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!

Resources

See also