nine months agoDinky pocketbooks with WebKit transforms
I'm a big fan of stuff written on paper. My computer is covered in useful post-it notes, and I do a lot of planning on paper at the start of every client-side build.
On my desk at work is a piece of paper written in felt tip that I pass around to my co-workers on occasion. It's a reference document for how we check projects out of subversion, upload to live and some basic terminal commands for people who are unfamiliar in that environment.
This was a great opportunity to break out my favourite paper folding technique, where an A4 page becomes an 8 page booklet. I first learnt about this from a Christmas card I received a few years ago from some very inventive friends.
Brian Suda happened to be in the office that day and pointed me to a cool Flash interface for creating these, pocketmod.com. He also suggested that it would be possible to build these using just HTML and CSS with CSS3 transforms, currently supported by Safari and WebKit.
Inspired, I did exactly that.
Here's the demo.html (no transforms, so I can easily preview the pages) - the transforms are applied by the print stylesheet, so hit "print preview" to see them. Alternatively, visit demo.html?print to preview the print stylesheet directly in your browser.
Just in case you aren't running Webkit or Safari, here's what the print output looks like:

Each "page" has a set width and height (241x370 px) and is absolutely positioned, but the real magic happens with the CSS3 transforms in the print stylesheet:
/* rotated left */
#page1, #page8, #page7, #page6 {
-webkit-transform: translate(64.5px, -64.5px) rotate(-90deg);
}
/* rotated right */
#page2, #page3, #page4, #page5 {
-webkit-transform: translate(-64.5px, -64.5px) rotate(90deg);
}
It's not enough just to rotate 90 or -90 degrees. This works fine if you are rotating something that is square because the rotation happens around the centre point. I wanted to rotate the rectangles around the corner to ensure they fitted snugly inside their parent container. The solution was to shift the position using a translate() transform. I could have done this with position: relative, but I opted for a transform since I was already using -webkit-transform for the rotation. 64.5px is worked out as (height - width) / 2.
You can fill each page with whatever you like, but make sure it fits or it will be clipped by the overflow: hidden applied to the page. The only required markup is as follows:
<div id="book">
<div id="page1" class="page"></div>
<div id="page2" class="page"></div>
<div id="page3" class="page"></div>
<div id="page4" class="page"></div>
<div id="page5" class="page"></div>
<div id="page6" class="page"></div>
<div id="page7" class="page"></div>
<div id="page8" class="page"></div>
</div>
I surround textual content with a <div class="inner"> to apply sensible padding without affecting the width of the page.
There are currently two special page types. An empty page with lines (suitable for hand-written notes) is achieved by applying a class of lines:
<div id="page5" class="page lines"></div>
The second special page uses the Google Static Maps API. The API takes a bunch of name value pairs, which I decided to represent using a definition list. On load, pages with the class gmap are scanned for definition lists, which are then hidden and replaced by an image constructed from the definition terms.
<div id="page4" class="page gmap">
<dl>
<dt>center</dt>
<dd>50.8197155,-0.1365716</dd>
<dt>key</dt>
<dd>insert your Google Maps API key here (get one here)</dd>
<dt>zoom</dt>
<dd>13</dd>
</dl>
</div>
I use Simon's www.getlatlon.com to find the correct values.
Aside from these special pages, I've included styles for the HTML usual suspects - lists, tables, headings, pre etc. To make a todo list, simply apply a class of todo to a <ul> or an <ol>. To make a blank todo list, just use blank list items.
Once you've constructed and printed your dinky booklet masterpiece, you'll need to fold it. Here's a nifty video from pocketmod.com showing how:
I've published the code on GitHub, so please feel free try it out yourself or fork it and have a play. Let me know what you think.

This is awesome work. I've definitely going to use it in a project (I'll crowbar it in!).
Alex 21st May 2009 23:39
That's really cool! :)
Although translate(64.5px, -64.5px) rotate(-90deg); makes me instinctively reach for a matrix transform…and what do you know, matrix(a,b,c,d,e,f) does exactly that.
James Aylett 22nd May 2009 02:17
This is pretty awesome, I just need to tinker with the sizes to make it fit my bizarre US-letter paper. :/
dbt 22nd May 2009 07:54
That's pretty cool :)
Richard Terry 22nd May 2009 08:10
Looks OK in Firefox 3.5pre nightly, too:
s/-webkit-transform/-moz-transform/gJan! 22nd May 2009 08:48
Handcraft + geekery? Absolutely wonderful.
CSS at its finest
Mislav 22nd May 2009 09:14
Lovely. It should also work in Firefox 3.5 if you include "-moz-transform"
Jeremy Ruston 22nd May 2009 09:15
Awesome. Thanks a lot for the tip. I will try to enable this programatically for the wiki pages.
Thejesh GN 22nd May 2009 09:49
Hmmm - PocketMod is pretty cool, although it appears to only use "Letter" size, and not full A4. Presumably your version is doing full A4?
mrben 22nd May 2009 10:16
Ooh, was that my Xmas Da Vinci Code thing that inspired you? Anyway, nice work: love the whole PocketMod universe.
Hatmandu 22nd May 2009 10:32
Nice one! Here's my script for making a PDF pocketmod for a daily digest.
http://github.com/jwheare/digest/tree/master
I found the hardest part was getting stuff that's interesting and useful on a daily basis, and I don't have a printer, so I kinda lost interest :)
James Wheare 22nd May 2009 12:25
I'm also big fan on planning on paper. Wow, I just simple love your project! Great work!
Vladimir Carrer 22nd May 2009 12:34
Very cute.
Olly Willans 22nd May 2009 14:05
Since you're using Safari/Webkit, you could save yourself the IDs and selectors and take advantage of nth-child.
#book > div:nth-child(even) { /* rotate the other way */ }
#book > div:nth-child(1) { /* adjust position */ }
...and so on.
Very cool idea, all 'round. :)
Jonathan Snook 22nd May 2009 14:48
Very nice! I might have to look in to this more closely!
Richard, Peacock Carter 22nd May 2009 16:20
Thanks for the feedback everyone!
Jan and Jeremy - awesome that Firefox now does this! I have updated the css to use
-moz-transformas wellAndrew -you and Helen were indeed the inventive friends I was talking about :)
James - your pdf generating thing looks like a really cool project!
Jonathan - oooh yes I could indeed use nth child, that would really clean up the markup. I couldnt use odd and even to rotate though as its 1, 8, 7 and 6 that go one way and 2, 3, 4, and 5 that go the other.
Natalie 23rd May 2009 17:27
That is so cool Nat!
Nicole Sullivan 26th May 2009 19:20
That's realy cool!
cheers for sharing.
web design leeds 27th May 2009 14:51
I came here from tiddlypocketbook.com, which uses TiddlyWiki as a editor, and having both used the PocketMod folding technique to send a Christmas card one year off-and-on relied on a GTD version of TiddlyWiki for keeping track of things, I'm really happy to have discovered your breakthrough.
Thanks! The whole thing is very impressive (especially the mash-up stuff you put up at GitHub). I'll see how to use your technique to apply it directly to my own TiddlyWiki file (using the MonkeyGTD layout at tiddlyspot.com).
Roger Sperberg
Roger Sperberg 1st July 2009 18:56
You can use the
-webkit-transform-originproperty (and its -moz- equivalent; and see its documentation) instead of thetranslate()transform. That property controls the point of origin of the transform.-webkit-transform-origin: 50% 120.5px;should do the trick for all pages (120.5 is width / 2).Jorrit 6th September 2009 00:12