How to Create CSS3 Ribbons Without Images

Tweet

In my last post, Pure CSS3 Speech Bubbles Without Images, we saw how the :before and :after pseudo-elements could be used to create different effects. In this post we’ll use similar techniques to create a variety of ribbons.

CSS3 ribbonsRibbon effects are in vogue. Most designers use positioned images, but we’ll create them without using border effects and a single h2 tag:


<h2>My Heading</h2>

Let’s give this a little style and make it overlap the containing element:


/* containing element */
#page
{
	width: 500px;
	padding: 50px;
	margin: 0 auto;
	background-color: #fff;
	border: 1px solid #333;
}

h2
{
	position: relative;
	width: 50%;
	font-size: 1.5em;
	font-weight: bold;
	padding: 6px 20px 6px 70px;
	margin: 30px 10px 10px -70px;
	color: #555;
	background-color: #999;
	text-shadow: 0px 1px 2px #bbb;
	-webkit-box-shadow: 0px 2px 4px #888;
	-moz-box-shadow: 0px 2px 4px #888;
	box-shadow: 0px 2px 4px #888;
}

CSS3 ribbonsIn this example, our #page has 50px of padding and a 1px border. The heading has a left margin of -71px so it overlaps the edge by 20px. Note we’re also using position: relative so the other ribbon elements can be positioned as necessary.

CSS3 ribbonsNow we need to create the folded part of the ribbon which goes ‘behind’ the page. As we saw in the last post, we can use border effects to create any type of triangular shape on an :after pseudo-element with zero width and height:


h2:after
{
	content: ' ';
	position: absolute;
	width: 0;
	height: 0;
	left: 0px;
	top: 100%;
	border-width: 5px 10px;
	border-style: solid;
	border-color: #666 #666 transparent transparent;
}

CSS3 ribbonsIt’s looking great and that might be all you need. But client’s love over-designed pages so let’s take it a little further. First, we could apply a flag shape to the right-hand edge by overlaying a white triangle applied to the :before pseudo-element:


h2:before
{
	content: ' ';
	position: absolute;
	width: 0;
	height: 0;
	right: -2px;
	top: 0px;
	border-color: transparent #fff transparent transparent;
}

CSS3 ribbonsThat’s nice, but what about a folded-back ribbon effect on the left-hand edge? No problem:


h2:before
{
	content: ' ';
	position: absolute;
	width: 30px;
	height: 0;
	left: -30px;
	top: 12px;
	border-width: 20px 10px;
	border-style: solid;
	border-color: #999 #999 #999 transparent;
}

CSS3 ribbonsThe border color of the pseudo-elements much match the background color of the h2 since it actually appears above the title. Altering the z-index doesn’t work on pseudo-elements if the parent is positioned.

Please see the demonstration page for an example which shows all three ribbon styles. It works as expected in IE8, IE9, Firefox, Chrome, Safari and Opera. IE6 and IE7 degrade gracefully and show the main overlapping title. All the CSS code is contained in the HTML source.

Who needs Photoshop?!

And if you enjoyed reading this post, you’ll love Learnable; the place to learn fresh skills and techniques from the masters. Members get instant access to all of SitePoint’s ebooks and interactive online courses, like HTML5 & CSS3 For the Real World.

Comments on this article are closed. Have a question about CSS3? Why not ask it on our forums?

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • rickydazla

    Ribbontastic! I just spent 15 minutes potatochopping a ribbon ‘stencil’ so that I could use it with different background-colors for just this purpose. I’ll give this a whirl instead.

  • Christopher

    What you manage to wrangle out of CSS never ceases to impress me! I’ll definitely try and pick this apart and learn something from it, you kids are just way too quick to pick things up these days I’m struggling to keep pace ;-)

  • Armen

    nice example, Craig! i used something similar in one of my recent projects and i experienced one problem worth noting:
    if your border widths differ on adjacent sides, Webkit (Chrome and desktop Safari) will render them really ugly. this is a known bug in Webkit, but still not fixed :(

  • DLT

    Craig,

    You are a true CSS ninja. However, the ribbons don’t work in IE9 on my Windows 7 box.

    • http://www.optimalworks.net/ Craig Buckler

      Strange – they’re working on my IE9 installation.

      Are you using IE7 compatibility mode? Press F12 and check the “browser mode” at the top.

  • John McClelland

    Apart from the text-shadow and box-shadow this is CCS2.1

  • jase

    very nice work! I’m a bit hesitant on using CSS3 styles as they don’t render in older browsers.

    • Pete

      Good stuff!

  • bobv

    Excellent! Can I treat the the programmer to a restaurant of his/her choice?

  • THG

    This rocks. I was just starting to wrangle with adding a ribbon edge and thinking about photoshop and positioning. I saw this – followed your steps and bam! had it done in a lot less time. Gotta love CCS3!

  • Andy

    Bookmarked!
    I have a client site I can use this on right away. Thanks mate! You’re a genius!

  • Kyawthura650

    Wonderful! I have done it. Thanks. :D

  • Andrew

    I agree this is good but the fact remains IE7 is still in the wild a lot even in the US. So I might do things like this but at the end of the day it’s easier to use pictures.

    Other method: Generate this with a good browser, take screenshots and use those as pictures for old browsers. But in that case, what benefit is it to even do the CSS3 in the first place?

    • http://www.optimalworks.net/ Craig Buckler

      You always need to consider your audience. An ‘average’ site will have fewer than 15% of users with IE6/7 – but no one has an average site! You may be happy for them to have a slightly degraded layout. But if your client demands (futile) pixel-perfection, background images are likely to be the best solution.

  • AdamT

    As others have said: this doesn’t use CSS3, except decoratively. There’s no reason not to deploy this now; with some fiddling it ought to work in IE7, etc.

  • Michel

    Very interesting article!

    The technique is not new but you have added a couple of nice additions to it… :)

    Btw, how would you suggest to achieve a better effect (ribbon that is symmetrical on both sides)? I think I am going to insert a SPAN element for this purpose… Also, a slight gradient would make the ribbon look more realistically, I think.

  • Nathan Thomas

    Very awesome article this will help with not having to have so many images put onto my site.
    I was wondering how do you change the angle of the the ribbon to going upwards instead of downwards? Ive messed around with changing the top left and even added a bottom attribute and it messes with the positioning but not its angle.
    If anyone could help it would be greatly appreciated.

  • Michel

    @Nathan:
    Change the following in the CSS:

    h2:before {
    top: -12px; /* change this from 12px to -12px ... */
    ...
    }
    h2:after {
    top: -12px; /* change this from 100% to -12px ... */
    border-color: transparent #666 #666 transparent; /* ...and this */
    ...
    }

    Hope this helps! :)

  • Nathan Thomas

    @Michel
    Thank you, this helped out remarkably!

  • Michel

    @Nathan:

    You’re welcome! :)

  • Erik

    Awesome, but how would you do a ribbon across a page (let’s say for a global navigation across the top) so that it wraps both sides?

    • http://www.optimalworks.net/ Craig Buckler

      Absolutely. You’d need to make the title extend across the top and over each edge. The :before and :after pseudo elements would then create small triangles on either side to show the wrap around.

  • kailash

    This is really a great article, please tell me how can I learn this beautiful css3 specification. I know some of the properties of css3 but I want to implement my knowledge just like you. So please suggest me some of the websites or books from where I can learn these beautiful things. Please reply on my mail id (kailashk06@gmail.com).
    Thank you.

  • http://gmu.edu Sasha Asjodi

    Hi I was wondering as to how i would would create a triangle on the other side rather it just be one sides I would like to get both sides to have the ribbon effect.

    Thanks