I’ve started buying .net magazine again recently. I don’t normally but I was hoping it might help in my search for a super-awesome new agency. I was flicking through this month’s edition when I happened upon a Create a wraparound ribbon tutorial. I thought I’d give it a read as I really love little design conundrums and how other people solve them. I was a little surprised to see it had been done in five elements. I challenged myself to do it in one…

Okay, so I can’t re-publish or copy sections of the article but you can either buy .net and read it, or look at the tiny images on the latest issue page. It simply creates what is in the screenshot—a ribbon-like effect that sits outside and then ‘behind’ its content.
I’m not bashing the author’s work at all. It works and is—as far as I can see—pretty robust. However, it certainly doesn’t need five elements and definitely no empty ones. His code was roughly:
<body>
<wrapper>
<wrapper>
<wrapper>
<h2></h2>
</wrapper>
<empty></empty>
</wrapper>
</wrapper>
</body>
Mine is:
<body>
<h2></h2>
</body>
And it does exactly the same thing. The CSS that powers the original makes use of manipulating the CSS borders-arrow behaviour. I opted for a good old fashioned image. There’s nothing wrong with the border-arrow method but I’m orthodox, and manipulating borders to create what is essentially an image just feels really wrong to me. Use whichever you prefer, but remember that images still count!
The full code for my CSS powered ribbon is simply:
<!-- MARKUP -->
<body>
<h2></h2>
</body>
/* CSS */
/*------------------------------------*\
MAIN
\*------------------------------------*/
html{
font-family:Cambria, Georgia, "Times New Roman", Times, serif;
background:#e4e3d5;
color:#666;
height:101%;
}
body{
width:940px;
padding:75px 10px;
margin:0 auto;
background:#fff;
}
/*------------------------------------*\
TYPE
\*------------------------------------*/
h2{
position:relative;
color:#fff;
background:#f43059;
font-size:1.5em;
float:left;
clear:both;
padding:10px 10px 10px 20px;
margin-left:-20px;
margin-bottom:20px;
text-shadow:0 -1px #d0284b, 0 1px #f96080;
-moz-box-shadow:2px 2px 0 rgba(0,0,0,0.1);
-webkit-box-shadow:2px 2px 0 rgba(0,0,0,0.1);
-o-box-shadow:2px 2px 0 rgba(0,0,0,0.1);
box-shadow:2px 2px 0 rgba(0,0,0,0.1);
}
h2:before{
content:" ";
background:url(../img/css/ribbon.png);
display:block;
width:10px;
height:10px;
position:absolute;
bottom:0;
left:0;
margin-bottom:-10px;
z-index:-1;
}
There we have it in four less elements. His five (discounting the <body>) to my one <h2>. 80% less code.
What this does is creates a white <h2> with a pink background, pulls the <h2> out of the content area with a negative margin and then places the image absolutely left-bottom of the <h2> in a :before pseudo-element. Job done.
Demo
I made a demo, also, which shows how this can be extended using some alternating nth-of-type styles. Feel free to pick it apart and see what does what. If any of the examples above seems out of context then view the demo’s stylesheet and source for the comprehensive code.
Final word
This works in IE 7 (without the :before and :after pseudo-elements), IE8, Firefox and Chrome, all with varying degrees of progressively enhanced niceties. Your code should never suffer for the sake of such tiny design elements. Keep it lean and use an aggressive approach to progressive enhancement in order to keep your markup at its best.
Final final word
This isn’t a dig at the author of the article or .net mag. This is simply an illustration of how progressive enhancement and some sensibility can solve the same problem in a far nicer, cleaner and more sensible fashion.
Furthermore, do feel free to use either the border ‘hack’ or the image method. There’s more than one way to skin a cat…
By Harry Roberts on Wednesday, February 9th, 2011 in Web Development. Tags: CSS, CSS3, HTML, Markup | 30 Comments »
+
rollsappletree said on 9 February, 2011 at 1:37 pm
SPETTACOLO :) this with http://nicolasgallagher.com/css-drop-shadows-without-images/demo/ are the most exiting things I ever read about css!
Florian-R said on 9 February, 2011 at 2:22 pm
Good article.
But why don’t push it a little using CSS shapes?
I made a quick and dirty demo : http://jsbin.com/ipeho5/5
didn’t try it in every brower, but it might be OK.
In any case, thanks for sharing the tips.
Paul Eustice said on 9 February, 2011 at 2:51 pm
Hi Harry,
If you wanted to avoid the use of the image for whatever reason, you could still mess about with borders and maintain the one element.
You’d need to remove the background image, then add these lines:
Should work fine, unless the parent of your heading is partially transparent in any way.
Paul Eustice said on 9 February, 2011 at 3:09 pm
Sorry, forgot to say that you’ll need to set the width and height of your ::before to 0.
Also, I’ve just realised you could use clip, so the final CSS is:
Cheers,
Paul
Stuart Robson said on 9 February, 2011 at 4:17 pm
A very nice article Harry. I did something similar before .net hit my doormat when I saw a PVM Garage article with the same amount of tags being used and @matthamm’s CSS3 page curl effect using :before and :after.
So from the demo page I created on New Years Day :- http://bit.ly/dVah34
After seeing the .net article I wrote this blog about it :- http://bit.ly/fHCcSA
As you know I’m using pure CSS with no images so your example would be a great fallback it IE7-8 :)
CHJJ said on 9 February, 2011 at 4:57 pm
It should be. People need to let go of wrapper-ridden markup.
Joe Masterson said on 9 February, 2011 at 9:58 pm
Great article as usual. While we’re trying to condense the code as much as possible, I thought i’d give it a try…
haven’t tried it in IE yet so who knows, but it uses no images and is 2 less lines of code. :-)
Nicolas Gallagher said on 9 February, 2011 at 10:31 pm
Worth noting a small issue. Because you’re using z-index:-1 on the pseudo-elements, they will fall behind any parent elements with a background colour. To get around this you either need to remove the z-index value on the pseudo-elements; or add a z-index for their associated element (and lose a bit of that shadow); or add {position:relative; z-index:1;} to the element with the background colour that they fall behind
Joe Masterson said on 10 February, 2011 at 12:47 am
playing with it a little more…
http://joemasterson.com/ribbon-no-images.html
this blog post consumed way more of my time than it should have haha.
Daniel Winnard said on 10 February, 2011 at 9:45 am
Hi,
Great article. I get .net mag and when I went through this tutorial, i thought that there would be a lot less simpler way to do it by using an image. I get that the author was trying to show you how to do it using CSS3 and no images, but at the end of the day, should we not be focusing on getting a job done as lean as possible without worrying about if we are using the “cooler” CSS3?
davi said on 10 February, 2011 at 8:57 pm
Good article… I read something similar on another blog…
http://www.pvmgarage.com/2010/01/how-to-create-depth-and-nice-3d-ribbons-only-using-css3/
Nicolas Gallagher said on 10 February, 2011 at 9:47 pm
@davi: That article uses exactly the kind of markup craft that Harry was pointing out you can avoid. A better example, using semantic markup, was posted here: http://www.prothemer.com/blog/experiments/no-presentational-markup-css3-infobox/
Ben Matewe said on 10 February, 2011 at 9:54 pm
While i appreciate the technique used to create the ribbon without using images what puts me off is the extra markup needed to achieve the visual aspect.
neil said on 10 February, 2011 at 9:58 pm
It doesn’t work in Opera 10.6 or Camino, thanks anyway
Nicolas Chambrier said on 11 February, 2011 at 7:08 am
Yeah cool. Far cleaner, nicer, etc… And far from being usable as it don’t work in IE, 6th months+ browsers, mobiles… So where’s the demonstration? To achieve this for real you’ll need to add hacks and markup, and finally get back to the more universal previous method.
Well, for teaching purpose it remains interesting.
Luis said on 11 February, 2011 at 11:08 am
I loved it, but saying it works in IE7 isn’t correct. It doesn’t mess your layout in IE7, ok. But also the ribbon’s little corner doesn’t show up, so it’s not really a ribbon, you know.
Ian P said on 11 February, 2011 at 1:55 pm
This is the great debate. What’s better, to avoid an HTTP request but complicate the markup or to load one more image and keep the code clean.
I think I agree with you and I’d go for the extra image. If you use CSS sprites then the difference will be negligible, but even if you don’t…. c’mon!
Rob said on 11 February, 2011 at 5:49 pm
Hi Harry,
Firstly nice write up and good alternative use of code to create the effect.
I admit openly, there is always going to be alternative/cleaner/better ways to achieve something on the web. For example, you can take the code you have here one step further and only use 1 call in the CSS to add a background image to the H2 if your sole aim was to reduce the amount of lines of code used.
But the aim of the tutorial was to show that you can achieve a relatively simple effect ‘without’ the use of any image or background image via CSS. I would be interested to know how much page weight was added by including a .png and how much was reduced by the reduction of code. I am sure either is minimal :-)
Regardless though, good job on the post, we all learn something new everyday and even in the responses to this post have already taught me a few things :-)
All the best,
Rob.
Natalia Ventre said on 15 February, 2011 at 10:35 am
I don’t like the extra markup either, but I think that an image-less solution comes handy for a template where the user can pick the color, like Tumblr for example.
Daniel Hahler said on 15 February, 2011 at 12:55 pm
The solution from http://joemasterson.com/ribbon-no-images.html is nice: no extra image or markup mess.
btw: you do not need an extra HTTP request for an image, if you would use the “data” protocol to use the image data inline.
Josiah said on 16 February, 2011 at 7:29 pm
Actually, I prefer his method, and this is why;
Say you create a website with ribbon headings for a client. Two years down the line, they want the ribbons to be a different color, and a different size. If you used the CSS-only method, it’s simply a matter of changing a color code and a pixel value or two. If you used the image-based method, you have to create new ribbon images, and you may not have the original source files to work with.
I always opt for the leanest markup, but I also always opt for the fewest images. It’s a close call in cases where you have to make a choice between the two, but thinking about the future, the CSS option would be more maintainable in the long-run.
Stuart Robson said on 17 February, 2011 at 4:14 pm
@Josiah note that Harry’s method does use on image (albeit tiny). My versions – http://bit.ly/dVah34 are pure CSS :D
Konstantinos said on 13 May, 2011 at 10:52 am
Hi, I am using inuit css and I try to make a ribbon but it seems that the overflow:hidden does not allow that. :( Could you help?
Sam said on 13 July, 2011 at 4:01 pm
Fantastic method, great markup. Cheers!
Alex said on 15 August, 2011 at 10:01 pm
That is one simple and neat of doing it. I would use some css gradients to make it look cooler and 3Dish..
stoatoffear said on 28 October, 2011 at 9:00 am
I haven’t seen a CSS solution that works in IE7 and IE8 yet.
That could be 75% of visitors to your site who can’t see the ribbon effect you spent ages on.
Karim said on 29 January, 2012 at 4:45 pm
very nice :-) i was actually looking of how to do that away from images to use on a website, it will load a bit faster than slicing up images and all that!
thanks…
Erin said on 5 February, 2012 at 11:38 am
I’m currently learning css, do you mind if I use some of this code in my own project?
Andy Walpole said on 15 February, 2012 at 4:27 pm
I have to agree with you here.
Surely adding extra markup for creating pure CSS images is a step backwards!
SteveO said on 3 May, 2012 at 7:14 pm
Wow! Thanks so much for this tut. And for freeing people to use images… I mean, heck!
Peace!