Creating a Stacked Paper Effect in CSS3

Replicating a stack of paper is a common design found on the web; it’s an easy way to make a design a little less harsh and digital by giving it an “analog” look. For a quick example, take a look at the “Chapters” WooThemes WordPress theme.
In the past I would have used a couple of wrapper divs
in HTML, and some background-image
CSS to get a vertically expandable (but probably fixed-width without a lot more work) content box. However, with the improvements in CSS3, along with rapidly improving browser support, I wondered if it would be possible to make a similar – and more flexible – effect without images.After a bit of a brain-storming session I came up with the following theory:
- A wrapper with
position:relative
- A content block (such as article, or a div)
- use of the
:before
and:after
selector to create pseudo-elements which could be placed under our content block usingposition: absolute
andz-index
transform
andbox-shadow
to apply the effects
A quick mock-up in a text-editor later and I had a working proof-of-concept.
Given a sample HTML page like this:
[sourcecode language=”html” wraplines=”false”]
<!doctype html>
<html>
<head>
<title>Test Page</title>
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<div class="hfeed">
<article class="entry post">
<header class="entry-header">
<h1 class="entry-title">This is a Test Page</h1>
</header>
<div class="entry-content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</article>
</div>
</body>
</html>
[/sourcecode]
Now we apply some CSS (only showing the bit which makes the “magic” happen):
[sourcecode language=”css”]
div.hfeed {
position:relative;
}
article.post {
position:relative;
margin: 0 0 2em 0;
background: #fff;
padding: 10px;
border: 1px solid rgba(0, 0, 0, 0.150);
-webkit-box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.18);
-moz-box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.18);
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.18);
}
article.post:before {
z-index: -1;
position: absolute;
top: -2px;
left: 0;
content: ”;
width: 100%;
height: 100%;
background-color: #fff;
border: 1px solid rgba(0, 0, 0, 0.150);
-webkit-box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.19);
-moz-box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.19);
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.19);
-webkit-transform: rotate(1deg);
-moz-transform: rotate(1deg);
-o-transform: rotate(1deg);
-ms-transform: rotate(1deg);
transform: rotate(1deg);
}
article.post:after {
z-index: -2;
position: absolute;
top: 1px;
left: -2px;
content: ”;
width: 100%;
height: 100%;
background-color: #fff;
border: 1px solid rgba(0, 0, 0, 0.150);
-webkit-box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
-webkit-transform: rotate(359deg);
-moz-transform: rotate(359deg);
-o-transform: rotate(359deg);
-ms-transform: rotate(359deg);
transform: rotate(359deg);
}
[/sourcecode]
This will give you something like this screenshot:
The sample code above has the effect being applied to a single content block. If you want each block to have the paper effect (such as each entry on a blog archive page) then you will need to slightly change your CSS and HTML. I will leave this for you to discover – after all, half the fun of learning is experimenting!
As far as compatibility goes: I’ve tested in Chrome, IE9, and Mobile Safari and all work fine. I don’t envision Firefox or the Android web browser would have a problem with this code.
You can find the complete code for the sample page + CSS here, as a Gist on GitHub
5 comments
Works fine in Firefox 8.
Thanks for checking that for me 🙂
This is awesome thanks for the inspiration.
Comments are closed.