How to Create a Flexible Folded Paper Effect With CSS3
In this tutorial we’ll learn to create a flexible (responsive) folded paper effect using CSS3 features like background gradients and box-shadows, which can give a cool-looking background to the content area of your website.
Step 1: Setting up the <head>
Let’s start out by making a very basic HTML page. We’ll use HTML5 because.. why wouldn’t you?!
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
|
<!DOCTYPE html> < html lang = "en" > < head > < meta charset = "utf-8" /> < title >Flexible Folded Paper Effect</ title > < link rel = "stylesheet" type = "text/css" href = "css/reset.css" /> < link rel = "stylesheet" type = "text/css" href = "css/style.css" /> < meta name = "viewport" content = "width=device-width, initial-scale=1.0" > <!--[if IE]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> < <!--[if gte IE 9]> <style type="text/css"> .gradient { filter: none; } </style> <![endif]--> </ head > |
In the head we make sure we use the HTML5 doctype, we set our title, we call in our stylesheets, we also use the viewport meta tag so that our effect will be responsive on mobile and tablet devices. Finally, there’s a polyfill to get html5 elements recognized in older browsers, and there’s also a fix for CSS3 gradients for IE which we’ll need later in the tutorial.
Step 2: Setting up the <body>
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
|
< body > < div id = "page-wrap" > < div class = "paper" > < section > < h1 >Flexible Folded Paper Effect</ h1 > < hr />< h2 >Achieved with a mixture of CSS3 gradients and box-shadows.</ h2 > </ section > < section > < p >Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam sollicitudin sapien quis augue pellentesque pulvinar. Morbi non ligula eu justo posuere tincidunt sit amet id nulla. Praesent lectus lacus, tristique at dictum ac, porta at magna. Phasellus est nunc, pulvinar non tempor a, condimentum vitae eros. Aliquam auctor posuere lacinia. Praesent eu risus dolor, a mollis leo. Aliquam pharetra, risus vel rutrum volutpat.Aliquam auctor posuere lacinia. Praesent eu risus dolor, a mollis leo. Aliquam pharetra, risus vel rutrum volutpat.< br />< br />Aliquam auctor posuere lacinia. Praesent eu risus dolor, a mollis leo. Aliquam pharetra, risus vel rutrum volutpat.</ p > </ section > < section > </ section > < section > </ section > </ div > </ div > <!-- END page-wrap --> </ body > </ html > |
Now, in the main section of the page we have one div container wrapping the page and another one wrapping the “paper”. Inside this div we’ll add a <section>
tag every time we want a folded section in the paper. There are two types of these sections, so later on in the CSS we’ll be able to differentiate between them using the ‘odd’ and ‘even’ nth-child selectors. This way, our HTML stays as semantic as possible with no superfluous class names.
In these sections I’ve added some content; titles and some placeholder text. This is a pretty normal plain page structure, but we have everything we need to create the folded paper effect by moving on to the CSS.
Step 3: Styling the Overall Page
In the CSS we’re going to create the effect completely from scratch, with no images, just for fun.
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
|
* { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } body { background : #777 ; } #page-wrap { margin : 0 auto ; max-width : 980px ; width : 100% ; } .paper { margin : 30px auto ; background : #f5f4f0 ; max-width : 960px ; width : 90% ; -webkit-box-shadow: 0 0 2px rgba( 0 , 0 , 0 , 0.7 ); -moz-box-shadow: 0 0 2px rgba( 0 , 0 , 0 , 0.7 ); box-shadow: 0 0 2px rgba( 0 , 0 , 0 , 0.7 ); } h 1 { font : bold 50px "Georgia" , serif ; text-align : center ; text-shadow : 0 1px 0 #fff ; margin-bottom : 20px ; } h 2 { font : bold 25px "Georgia" , serif ; text-align : center ; } |

These are the basic styles for the page. We declare a fixed max-width and a percentage for the actual width to make the whole “paper” element flexible. The header styles are only for the example obviously, it’s up to your artistic skills to change them according to your design.
Step 4: Styling Both Fold Sections
001
002
003
004
005
006
|
section { width : 100% ; min-height : 100px ; position : relative ; padding : 30px ; } |

Here we’re making sure that each section stretches 100% across its parent element. We define a min-height, that way if you want to add empty fold sections like we have in the example, they won’t be 0px tall. We then declare the position relative and we add a bit of padding, once again only for this design.
Note: It’s very important to declare position: relative;
in this section; we need it to place the shadow elements which really sell the effect.
Step 4: Adding the Gradient
001
002
003
004
005
006
007
008
009
|
.paper section:nth-child(even) { background : -moz-linear-gradient( -45 deg, #e9eae5 0% , rgba( 244 , 245 , 240 , 0 ) 100% ); background : -webkit-gradient(linear, left top , right bottom , color-stop( 0% , #e9eae5 ), color-stop( 100% , rgba( 244 , 245 , 240 , 0 ))); background : -webkit-linear-gradient( -45 deg, #e9eae5 0% , rgba( 244 , 245 , 240 , 0 ) 100% ); background : -o-linear-gradient( -45 deg, #e9eae5 0% , rgba( 244 , 245 , 240 , 0 ) 100% ); background : -ms-linear-gradient( -45 deg, #e9eae5 0% , rgba( 244 , 245 , 240 , 0 ) 100% ); background : linear-gradient( 135 deg, #e9eae5 0% , rgba( 244 , 245 , 240 , 0 ) 100% ); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr= '#e9eae5' , endColorstr= '#00f4f5f0' ,GradientType= 1 ); } |

This time we’re only styling every even section element, so that means the second, fourth, sixth etc. We’re applying a gradient to give the impression of a shadow being cast on the paper in 3D space. This gradient is one of the most essential parts of this design and it’s important to choose a color that compliments the paper.
In this case the paper was #f5f4f0 and so the gray of the gradient (which fades diagonally from top-left to bottom-right) is #e9eae5 to completely transparent.
You can use a number of tools to generate your gradients for you, for example:
- Colorzilla
- Damian Galarza’s CSS3 Gradient Generator
- Gradientapp for OS X
Step 5: Adding the Shadows
With that done, let’s now add some shadows under the paper.
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
|
.paper section:nth-child(odd):before { z-index : -1 ; position : absolute ; content : "" ; bottom : 0px ; left : 10px ; width : 50% ; top : 20px ; background : rgba( 0 , 0 , 0 , 0.7 ); -webkit-box-shadow: -10px 20px 15px rgba( 0 , 0 , 0 , 0.5 ); -moz-box-shadow: -10px 20px 15px rgba( 0 , 0 , 0 , 0.5 ); box-shadow: -10px 20px 15px rgba( 0 , 0 , 0 , 0.5 ); -webkit-transform: rotate( 5 deg); -moz-transform: rotate( 5 deg); -o-transform: rotate( 5 deg); -ms-transform: rotate( 5 deg); transform: rotate( 5 deg); } .paper section:nth-child(odd):after { z-index : -1 ; position : absolute ; content : "" ; bottom : 0px ; right : 10px ; left : auto ; width : 50% ; top : 20px ; background : rgba( 0 , 0 , 0 , 0.7 ); -webkit-box-shadow: 10px 20px 15px rgba( 0 , 0 , 0 , 0.5 ); -moz-box-shadow: 10px 20px 15px rgba( 0 , 0 , 0 , 0.5 ); box-shadow: 10px 20px 15px rgba( 0 , 0 , 0 , 0.5 ); -webkit-transform: rotate( -5 deg); -moz-transform: rotate( -5 deg); -o-transform: rotate( -5 deg); -ms-transform: rotate( -5 deg); transform: rotate( -5 deg); } |

Now I know this may seem daunting to people who aren’t used to using CSS3 transforms or pseudo-elements, but this is actually quite straight forward.
Here we’re just adding the shadows for each odd numbered section. We start by pushing the extra element behind the paper with the z-index. It’s here that we declare a position of absolute which is why we needed to declare the position to relative in the parent element earlier.
Basically, we’re making two black boxes that take up half of the width of our fold section (width: 50%;) we’re then giving them box shadows and after that rotating them by an amount of 5°. These extra elements are mostly hidden, but are placed in such a way that they give the illusion of depth, as if the paper was coming away from the page. These shadows accentuate the effect created by the gradient earlier.
Step 6: Adding the Final Shadows
We now need to repeat a similar process for our evenly numbered sections.
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
|
.paper section:nth-child(even):before { z-index : -1 ; position : absolute ; content : "" ; bottom : 20px ; left : 10px ; width : 50% ; top : 0 ; background : rgba( 0 , 0 , 0 , 0.7 ); -webkit-box-shadow: -10px -25px 15px rgba( 0 , 0 , 0 , 0.5 ); -moz-box-shadow: -10px -25px 15px rgba( 0 , 0 , 0 , 0.5 ); box-shadow: -10px -25px 15px rgba( 0 , 0 , 0 , 0.5 ); -webkit-transform: rotate( -5 deg); -moz-transform: rotate( -5 deg); -o-transform: rotate( -5 deg); -ms-transform: rotate( -5 deg); transform: rotate( -5 deg); } .paper section:nth-child(even):after { z-index : -1 ; position : absolute ; content : "" ; bottom : 20px ; right : 10px ; left : auto ; width : 50% ; top : 0 ; background : rgba( 0 , 0 , 0 , 0.7 ); -webkit-box-shadow: 10px -25px 15px rgba( 0 , 0 , 0 , 0.5 ); -moz-box-shadow: 10px -25px 15px rgba( 0 , 0 , 0 , 0.5 ); box-shadow: 10px -25px 15px rgba( 0 , 0 , 0 , 0.5 ); -webkit-transform: rotate( 5 deg); -moz-transform: rotate( 5 deg); -o-transform: rotate( 5 deg); -ms-transform: rotate( 5 deg); transform: rotate( 5 deg); } |

Exactly the same as before but for a few details. Obviously we’re targeting the even numbered elements and not the odd ones, and the positioning is different so the shadow is located at the top of the box and rotated the other way, thus creating a sort of triangular shadow near the point of every “fold”. Here:

Step 7: Adding a few Media-queries
You’ll have noticed that we’ve been using percentages for widths and have been setting up an environment for a responsive design. If you take the example as it is now and resize it down it works quite well. But there are imperfections. These can be fixed with a few corrections that kick in at certain points.
001
002
003
004
005
006
007
008
009
010
011
012
013
014
|
@media only screen and ( max-width : 600px ) { h 1 { font-size : 25px ; } h 2 { font-size : smaller ; } .paper section:nth-child(even):after { right : 20px ; } .paper section:nth-child(odd):after { right : 20px ; } .paper section:nth-child(even):before { left : 20px ; } .paper section:nth-child(odd):before { left : 20px ; } } |
So here we’ve just made our headings smaller (once again just for the demo) we’ve also had to replace the pseudo-elements ever so slightly because they were showing at small viewports. I chose 600px as the break point purely because that’s when the shadows became too big in my eyes, once again this is completely open for you to change according to your design.
Browser Compatibility
As we’re using CSS3 gradients, browser compatibility is limited to modern browsers and Internet Explorer 10. Our gradients do have a backup filter property to give us access to IE9, so that just discounts IE8 and earlier. IE8 actually trips up in a number of ways (our CSS3 selectors, transform rules and box-shadows, so let’s just forget about IE8 completely!) Thankfully, it’s a graceful degradation and the content of the page is perfectly accessible:

IE8
Don’t forget that your media queries will also need to contain the only keyword, to prevent IE8 from parsing all their contents by default.
Conclusion
So there you have it! A flexible folded paper effect created with CSS3 gradients, box-shadows and pseudo elements. I hope you’ve enjoyed this tutorial and hopefully learned something useful from it. Let me know in the comments I’d love to hear your opinions