A fancy box with rounded corners and drop shadow with CSS3 only. Really?

I have to admit that when I like the design of a website I check its CSS and HTML to see the code hoping to learn something new. I’m horrible at design and I cannot make a box even if I have it in front of me for 24 hours non stop but I love all kinds of tricks to make the content more appealing: rounded boxes, sexy quote marks, bubbles, everything.

What is really weird is that all these fancy design elements are usually cut as images and put as background-image for some DIV while the vast majority of them can be recreated with CSS. I admit, not all of them are simple but some do and today I’ll show you my latest experiment. I love a certain kind of box and I’m trying to make it using CSS3 only. After a little prayer to the CSS3 God let’s start.

If you’re not a patient person skip all this and go directly to the test page.

Let’s pick an image and apply some CSS3 love

I usually like these kind of boxes with rounded corners, some smooth gradient inside, maybe an inner shadow and definitely a drop shadow. Definitely! So here’s our guinea pig.
box with rounded corners and drop shadow
The problem with it is the drop shadow and I have a feeling that making it will be fun but seeing it in Internet Explorer will not.

The rounded corners and the gradient are piece of cake. With a little help from the Ultimate CSS Gradient Generator the code looks like this:

background: #f5f5f5; 
background: -moz-linear-gradient(top,  #f5f5f5 0%, #efefef 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f5f5f5), color-stop(100%,#efefef)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top,  #f5f5f5 0%,#efefef 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top,  #f5f5f5 0%,#efefef 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top,  #f5f5f5 0%,#efefef 100%); /* IE10+ */
background: linear-gradient(top,  #f5f5f5 0%,#efefef 100%); /* W3C */
-pie-background: linear-gradient(top,  #f5f5f5 0%,#efefef 100%); 
border-radius: 7px;
border:1px solid #d8d8d8;

You noticed I used CSS PIE because I am really trying to make this work on Internet Explorer. There was also a grey border that we added.

The white inner border is an inner shadow actually, let’s create it:

box-shadow: 0px 0px 1px 1px white inset;

The outside shadow is a bit tricky, we could add it to the inner shadow cause box-shadow property allow elements to have multiple shadows:

box-shadow: 0px 0px 1px 1px white inset, 0px 23px 21px -33px #000;

old school CSS3 shadow

The problem is that the shadow is not quite how the designer wanted it to be – and as you can see it for yourself it’s not even looking the same in all browsers (Internet Explorer simply killed it). It’s some sort of blurred copy of the box while our shadow is elliptical.

Almost the same is not acceptable. And you, as programmer, really have to make pixel-perfect websites, right???

Using the :after pseudo element

The idea is simple: we generate the box but when it comes to generating the shadow we just create an ellipse and apply the shadow to it. The ellipse stays behind the box (if we’re lucky) and its shadow drops under OUR fancy box.

I tried applying the :after element to our box directly and because it was really stubborn and did not want to go behind the box I had to create a wrapper and apply the shadow to it. The HTML is simple:

<div class="wrapper"><div class="box"></div></div>

The CSS is:

        border-radius: 50%;
        box-shadow: 0 20px 20px -20px #000;

The result is not bad.
shadow with pseudo elements

The problem is that the mix of :after pseudo element, CSS PIE and the box-shadow is fatal for Internet Explorer 7 and 8 while IE9 generates the box a bit different.

So no crossbrowser solution here.

What if we break the rule and use an image for shadow?

We cut the shadow as image and use the :after pseudo element to position it. No wrapper needed this time and the CSS looks like this:

	background: url("../img/shadow.png") no-repeat bottom left; 

The box will look like the image because we actually hacked the shadow. I know, I’m ashamed but this time Internet Explorer finally behaves because IE8 supports pseudo elements. (IE7 not really)
shadow placed as image

A crossbrowser solution? Not quite!

But if we isolate Internet Explorer 8 and 9 and apply them the shadow-as-image solution, IE7 takes the shadow-as-image but no pseudo-elements and the rest (Mozilla, Chrome, Safari, Opera) the pure-CSS3-no-image solution then we have a deal!

I know it’s ugly but we save one HTTP request and do not load a 3Kb image for modern browsers and that is something! Multiply that with X boxes we usually use in a website and we have more than nothing there.

This is how Mozilla displays the boxes…

mozilla screenshot

… but the fun part is this one: Internet Explorer 9 screenshots:
IE9 screenshot