498-css3-ribbons

How to Create CSS3 Ribbons Without Images

By | | JavaScript

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?!

 

Craig Buckler

Craig is a Director of OptimalWorks, a UK consultancy dedicated to building award-winning websites implementing standards, accessibility, SEO, and best-practice techniques.

More Posts - Website

{ 26 comments }

Sasha Asjodi November 14, 2011 at 12:17 pm

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

kailash October 31, 2011 at 10:31 pm

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.

Erik April 21, 2011 at 5:06 am

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?

Craig Buckler April 21, 2011 at 12:19 am

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.

Michel April 9, 2011 at 10:36 pm

@Nathan:

You’re welcome! :)

Nathan Thomas April 8, 2011 at 6:56 am

@Michel
Thank you, this helped out remarkably!

Michel March 31, 2011 at 1:01 am

@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 March 30, 2011 at 10:02 pm

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 March 30, 2011 at 9:06 pm

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.

AdamT March 30, 2011 at 4:24 pm

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.

Andrew March 30, 2011 at 1:13 pm

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?

Craig Buckler March 30, 2011 at 4:49 pm

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.

Kyawthura650 March 30, 2011 at 10:29 am

Wonderful! I have done it. Thanks. :D

Andy March 30, 2011 at 5:32 am

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

THG March 30, 2011 at 3:58 am

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!

bobv March 30, 2011 at 3:47 am

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

jase March 30, 2011 at 2:33 am

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

Pete March 30, 2011 at 8:24 am

Good stuff!

John McClelland March 30, 2011 at 2:09 am

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

Brandtley McMinn March 31, 2011 at 3:34 am

text-shadow has been apart of the W3C spec since 1998 with the CSS2 spec recommendation http://www.w3.org/TR/1998/REC-CSS2-19980512/text.html#text-shadow-props

however it has since been revised to specify drawing order of shadows on text http://www.w3.org/TR/2011/WD-css3-text-20110215/#text-shadow

but yeah, it’s a really simple technique with very nice embellishments with CSS3

glow April 12, 2011 at 6:00 pm

agreed, i wouldn’t call this css3 ribbons

DLT March 30, 2011 at 1:45 am

Craig,

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

Craig Buckler March 30, 2011 at 2:01 am

Strange – they’re working on my IE9 installation.

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

Armen March 29, 2011 at 11:05 pm

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 :(

Christopher March 29, 2011 at 10:39 pm

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 ;-)

rickydazla March 29, 2011 at 9:50 pm

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.

Comments on this entry are closed.