After having a plain 2D post-it and a 3D rotated post-it, let’s now move to 3D shadow effects.
First we’ll start with a pretty simple post-it card:
<html> <body> <style> .card { width: 250px; height: 100px; padding: 10px; background: #FFFFA5; font-family: "Lucida Handwriting",cursive; font-size: 15px; } </style> <div class="card"> <p>Buy some milk</p> </div> </body> </html>
It looks like this:
Then we’ll add some shadow so that it looks like the card is not stuck to the background:
.card { -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1); }
It now looks like this:
Note that the shadow is not the same all over the card. It makes it more like a real card with real light and shadow.
Now we want to have a effect so that it looks like the card is not completely rigid but the corners are slightly curved i.e. they look further away from the background. Since we cannot just rotate the card and say that the rotation is non-linear (at least I don’t know a way to do it), we’ll have to use some kind of optical illusion using shadows.
Since our card already has a shadow, we’ll use two additional elements which will throw an additional shadow. Later on, we’ll use pseudo-elements to display them but right now, we’ll just use some normal divs for the sake of explaining how it works:
<style> .shadow-element-before, .shadow-element-after { width: 125px; height: 20px; } </style> <div class="shadow-element-before"></div> <div class="shadow-element-after"></div>
Note that these elements need to have half the width of the card (here it’s a fixed width but when building it in with pseudo-element you can use width: 50%). The height depends on how you like it, you should just experiment a little bit. I find 20% of the height of the card to be a good height for the effect.
We’ll also add the shadow we need for the effect:
.shadow-element-before, .shadow-element-after { -webkit-box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7); box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7); }
These elements will look like this:
Now we’ll want to rotate them slightly to create the illusion that the corner of the cards which are going up (even though actually it’s the shadow of these elements which is rotated):
.shadow-element-before { -webkit-transform: rotate(-2deg); transform: rotate(-2deg); } .shadow-element-after { -webkit-transform: rotate(2deg); transform: rotate(2deg); }
The left one is rotated counter-clockwise and the right one clockwise. Here I only use the CSS3 property and the WebKit specific property as newer versions of FireFox do not need a browser specific prefix and I’m not much into Opera or IE. But if required, you could define copies of the box-shadow property with the following additional prefixes: -moz-, -o- and -ms-.
Here’s how the shadow elements look like with the rotation:
Now we can have them displayed as hidden pseudo-element. Hidden meaning they are displayed below the opaque card. So we have to do the following:
- Define the pseudo elements with :before and :after.
- Set an empty content for the pseudo element.
- Change the z-index of the pseudo-elements to have them displayed below the card.
- In order to be able to properly position the shadow elements, they have to have the position property set to absolute and the card should be set to relative.
- Since we’ve defined a bottom shadow for the pseudo element of 15 pixels, we’ll place them 15 pixel from the bottom so that you only see the blur of the shadow. If you want, you can reduce it to see a little more of the shadow.
- Position the shadow elements 10px from the left resp. from the right hand side so that the shadow below the card is not visible in the corners. This then looks like the corners are slightly lifted.
The code then looks like this:
<style> .card, .simple-card { width: 250px; height: 100px; padding: 10px; background: #FFFFA5; font-family: "Lucida Handwriting",cursive; font-size: 15px; } .card-shadow { -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1); } .card { position: relative; } .card:before, .card:after { content: ""; position: absolute; z-index: -5; bottom: 15px; width: 50%; height: 20%; -webkit-box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7); box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7); } .card:before { left: 10px; -webkit-transform: rotate(-2deg); transform: rotate(-2deg); } .card:after { right: 10px; -webkit-transform: rotate(2deg); transform: rotate(2deg); } .simple-card, .card-before, .card-after { margin-bottom: 40px; } .card-before, .card-after { content: ""; width: 125px; height: 20px; -webkit-box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7); box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7); } .card-before { left: 10px; -webkit-transform: rotate(-2deg); transform: rotate(-2deg); } .card-after { right: 10px; left: auto; -webkit-transform: rotate(2deg); transform: rotate(2deg); } </style> <div class="card card-shadow"> <p>Buy some milk</p> </div>
And the card like this:
Just play around with the different properties and change their values to have the card look as you like.