Type study: A responsive 3D text effect

Type study is an ongoing series of guest posts about typography on the web. In this article, we hear from Russ Maschmeyer on a nifty trick for creating a responsive 3D text effect.

While perusing the Lettering.js website, I saw this example post by Trent Walton. When I saw that dynamically-generated graphic and the words “My site is responsive,” I assumed those letters would fold and unfold like an accordion to accommodate any browser width. Suddenly all seemed right and good in the world.

Trent Walton’s inspiring blog post.

Alas! As I pushed and pulled on my browser’s window pane, the graphic folded not. But what a great idea! Why hadn’t it been done? My life had new purpose. The result was foldup.js.

Foldup.js works with jQuery and Paravel’s Lettering.js to create an adaptive folding and unfolding effect for headlines, body copy, or any other text deemed worthy. Let’s walk through how to use it.


Before we begin, let’s see it in action; the demo works in Safari, Chrome, Firefox, and Opera, but not Internet Explorer. (Think of it as an experiment.) Be sure to stretch and squish your browser’s window pane to really get the full effect.

The demo, at a wide browser width.

The demo again, but at a narrow width; the letters fold like an accordion.

Getting started

The goal is to get this working with as little HTML as possible, so, we’ll start very simply:

    <link rel="stylesheet" type="text/css" href="css/style.css">
    <div id="page">		
      <p class="stranger foldup">Hello World!</p>

We’ve created an <html> document, added a generic style sheet called style.css, and created a <div> element which will become our page within the browser window. Finally, we’ve included some paragraph content that we’d like to fold up, and added a class of foldup to that paragraph. This will allow us to identify which elements on the page we actually want to fold up.

Adding style

We’ve got our content marked up, so it’s time to add some CSS so that our letters and words look and behave properly.

First, we’ll set the body background to orange (#ffa500) and declare our font stack — featuring Brevia, plus some appropriate fallback fonts. Next up, we want to set up a responsive, centered page to put our text in. We’ll give our #page element a width of 80% and center it with margin: 0 auto.

body {
  background-color: #ffa500;
  font-family: brevia, helvetica, verdana, sans-serif;

#page {
  width: 80%;
  margin: 0 auto;

Next, we’ll style the element to be folded up. In this case, we’re going for large, uppercase, and center-aligned for our folded letters.

.foldup {
  text-transform: uppercase;
  font-size: 3em;
  text-align: center;
  color: #FFF;

Now for the fun part. Lettering.js will dynamically wrap each word in its own span and label them sequentially (e.g. .word1, .word2, .word3, etc.). We can then use the child selector (.foldup > span) to style every span element within .foldup without having to know how many there are going to be. We’ll also set a display property of inline-block to keep long words from breaking into two lines and use margin: 20px 10px to set both the line height (20px) and the word spacing (10px).

.foldup > span {
  display: inline-block;
  margin: 20px 10px;
  border-radius: 12px;

Lettering.js will also wrap each letter of each word in its own sequential span element. We can reference these new child letters using another child selector: .foldup span > span. We’ll again set display to inline-block; next, we’ll set the width for each letter to 1.5em to make sure they have a consistent width which adjusts appropriately to the font size. We’ll also set the top and bottom padding to .2em and set position: relative; the latter allows us to adjust the vertical position of the letters with our JavaScript for the accordion effect. If you also wanted to add a background texture to each letter, this would be the place to do it!

.foldup span > span {
  display: inline-block;
  width: 1.5em;
  padding: .2em 0;
  position: relative;

The last three lines of CSS combine child selectors and pseudo selectors to round the corners of the first and last letters in each word; if there’s only one letter in the word, it rounds both the left and right side of the single letter.

.foldup span > span:first-child { 
  border-radius: 10px 0 0 10px; 

.foldup span > span:last-child { 
  border-radius: 0 10px 10px 0; 

.foldup span > span:only-child { 
  border-radius: 10px; 

Making it happen

Now that we’ve got our content and style prepped, it’s time to make it dynamic. First, let’s add our script files to our HTML document, like so:

<!-- Add Typekit Fonts -->
<script type="text/javascript" src="http://use.typekit.com/xxxxxxx.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>

<!-- Add jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>

<!-- Apply our foldup plugin to our text -->
  var foldEverything = function(){

<!-- Add our foldup plugin to this page -->
<script src="js/foldup.js"></script>

The first two <script> elements enable our Typekit fonts (where the “xxxxxxx” is your kit ID). The third <script> element adds jQuery. The fourth <script> element applies the foldup effect to our .stranger element. The final script element adds our foldup.js.

Now let’s dive into the foldup function. Thanks to the help of Typekit’s David Demaree, the plugin is set up with some default parameters that you can change when initializing the function:

  var foldEverything = function(){
      containerWidth: 0.8,  // Width at which the effect begins working
      startColor: [255, 165, 0],  // Card starting background-color
      lowlightColor: [172, 111, 0],  // Card will dark to become this color
      highlightColor: [255, 194, 83],  // Card will lighten to become this color
      minShadow: 0.3,  // Lightest shadow, 1= darkest, 0 = no shadow
      maxShadow: 0.4  // Darkest shadow, 1= darkest, 0 = no shadow

You can use all of these or just a few to customize how your foldup looks.

So, how does the foldup plugin actually work? Well, we start by figuring out how much the browser window is currently squished by comparing the current window width against our threshold for beginning the effect; then we determine how far past that threshold we are. Based on that, we dynamically adjust the values for the CSS3 translation properties, skewY and scaleX.

To change the color, we determine how far past our threshold we are and set our current color values for the highlight and lowlight based on how much we’ve squished our window. The more you squish, the closer the starting color gets to the highlight and lowlight colors.

For the shadow, we’re grabbing the span which wraps the whole word, setting the background to black, and then varying the shadow from sharp to blurry by adding a black CSS3 box-shadow which increases in size the more we squish.

When you put it all together it creates the rather convincing foldup effect!

Get the source

Well, that was fun, wasn’t it? If you’re not in the mood to recode this from scratch, I’ve put it all up on github (thanks again to David Demaree for his helpful suggestions). I hope this has thoroughly inspired you to try your hand at creating your own dynamic lettering work using Typekit, CSS, jQuery, and Lettering.js.

Russ Maschmeyer — also known as Strange Native — is an Interaction and
Product Designer at Facebook. He’s also 1/2 of dontfeartheinternet.com, a resource dedicated to teaching web design basics to even the most tech averse.

10 Responses

  1. This is HTML and JavaScript jewellery…

  2. Neat effect, but I really think that this misses the point of responsive design. The goal is to have the text be nice and readable on any screen or device, not to animate page elements as the window is resized. Trent’s original design gets it right.

    1. Mandy Brown says:

      This is intended as a fun experiment to showcase what you can do with type on the web, not as an improvement on Trent’s article (which is lovely just as it is).

  3. dpawson says:

    Unsure about the js inclusion?

    var foldEverything = function(){

    Is shown externally to any element?
    I’m getting js errors in Chrome,

    containerWidth: 0.8, // Width at which the effect begins working
    startColor: [255, 165, 0], // Card starting background-color

    Pointing to this line,
    foldup.js, line 7 Uncaught syntax error :


  4. This is great Russ. Typographical magic.

  5. I was thrilled to see that Russ had created this. My idea turned up to eleven! Delightful!

  6. Thanks Trent!

    @DanBoulet, I agree with you. I hesitated to call it “Responsive” as it really isn’t about creating an optimal experience for any screen size or browser capability. Just figured it was a fun experiment that “responds” to the resizing of a conventional browser to keep the font size the same with a fun accordion effect.

    Apologies if that was misleading to folks!

  7. J Curby says:

    Great idea, already looking for ways to use this in some of our work.

  8. Zandy says:

    How fun – what a good example of modifying something fun and useful into something that’s also fun and useful but in a different way.

Comments are closed.