How to Think Inside the Box: Programming Fixed Layout for E-Books


Published on

What's under the hood of a fixed-layout e-book? In this presentation, created by Dave Cramer (Hachette), originally featured in the February 25th BISG webcast of same name, you'll have a look at the basics of file construction, learn about different approaches to creating fixed-layout books, and learn about common pitfalls from an expert in digital content creation.

To view a recording of the WebEx webinar in which this presentation first appeared, please email your request to Standard rates apply: $49.00 for non-members, FREE for members.

1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

How to Think Inside the Box: Programming Fixed Layout for E-Books

  1. 1. Inside Fixed Layout Dave Cramer / Hachette Book Group
  2. 2. Ten Questions 1. Why not PDF? 2. How do I draw the line? 3. Has anyone seen my viewport? 4. Why are all these positions so confusing? 5. Is this rendition ordinary? 6. Can’t we all just get along? 7. One lump or two? 8. How do I teach my book to speak? 9. Doc, what's wrong? This never happened before… 10. Are you kidding?You couldn’t pay me to do this stuff…
  3. 3. Why Not PDF?
  4. 4. How do I draw the line?
  5. 5. Images
  6. 6. <rect  x="72"  y="79.25"  fill-­‐rule="evenodd"  clip-­‐rule="evenodd"  fill="#F0F0F0"  width="468"  height="279"/> <rect  x="72"  y="652.999"  fill-­‐rule="evenodd"  clip-­‐rule="evenodd"  fill="#F0F0F0"  width="468"  height="46.5"/> <text  transform="matrix(1  0  0  1  72  67.4458)"  font-­‐family="'SourceSansPro-­‐BoldIt'"  font-­‐size="11">HTML</text> <text  transform="matrix(1  0  0  1  76  90.1157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">&lt;?xml</text> <text  transform="matrix(1  0  0  1  108.5107  90.1157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">version=&quot; 1.0&quot;</text> <text  transform="matrix(1  0  0  1  184.3691  90.1157)"  font-­‐family="'DejaVuSansMono'"  font-­‐ size="9">encoding=&quot;UTF-­‐8&quot;?&gt;</text> <text  transform="matrix(1  0  0  1  76  105.6157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">&lt;html</text> <text  transform="matrix(1  0  0  1  108.5107  105.6157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">xmlns=&quot;http://</text> <text  transform="matrix(1  0  0  1  243.9722  105.6157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">1999/</text> <text  transform="matrix(1  0  0  1  271.0645  105.6157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">xhtml&quot;</text> <text  transform="matrix(1  0  0  1  76  121.1157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">xmlns:epub=&quot;http://</text> <text  transform="matrix(1  0  0  1  249.3906  121.1157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">2007/</text> <text  transform="matrix(1  0  0  1  276.4829  121.1157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">ops&quot;&gt;</text> <text  transform="matrix(1  0  0  1  86.8369  136.6157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">&lt;head&gt;</text> <text  transform="matrix(1  0  0  1  97.6738  152.1157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">&lt;meta</text> <text  transform="matrix(1  0  0  1  130.1846  152.1157)"  font-­‐family="'DejaVuSansMono'"  font-­‐ size="9">name=&quot;viewport&quot;</text> <text  transform="matrix(1  0  0  1  216.8799  152.1157)"  font-­‐family="'DejaVuSansMono'"  font-­‐ size="9">content=&quot;width=600,</text> <text  transform="matrix(1  0  0  1  325.249  152.1157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">height=600&quot;/&gt; text> <text  transform="matrix(1  0  0  1  97.6738  167.6157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">&lt;meta</text> <text  transform="matrix(1  0  0  1  130.1846  167.6157)"  font-­‐family="'DejaVuSansMono'"  font-­‐ size="9">charset=&quot;utf-­‐8&quot;/&gt;</text> <text  transform="matrix(1  0  0  1  97.6738  183.1157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">&lt;title&gt;The</tex <text  transform="matrix(1  0  0  1  157.2769  183.1157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">Earth</text> <text  transform="matrix(1  0  0  1  189.7876  183.1157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">Book&lt;/title&gt;</ text> <text  transform="matrix(1  0  0  1  97.6738  198.6157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">&lt;link</text> <text  transform="matrix(1  0  0  1  130.1846  198.6157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">href=&quot;css/</tex <text  transform="matrix(1  0  0  1  184.3691  198.6157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">stylesheet.css&quot; text> <text  transform="matrix(1  0  0  1  271.0645  198.6157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">type=&quot;text/</te <text  transform="matrix(1  0  0  1  330.668  198.6157)"  font-­‐family="'DejaVuSansMono'"  font-­‐size="9">css&quot;</text> <text  transform="matrix(1  0  0  1  357.7598  198.6157)"  font-­‐family="'DejaVuSansMono'"  font-­‐ size="9">rel=&quot;stylesheet&quot;/&gt;</text> SVG
  7. 7. <?xml  version="1.0"  encoding="UTF-­‐8"?> <html   xmlns:epub="">    <head>        <meta  name="viewport"  content="width=600,  height=600"/>        <meta  charset="utf-­‐8"/>        <title>The  Earth  Book</title>        <link  href="css/stylesheet.css"  type="text/css"  rel="stylesheet"/>    </head>    <body>        <div  class="page006">            <img  src="006.png"  alt="Girl  with  card  saying  I  love  you"/>            <p  class="p6l1">                <span  id="s6l1">I  use  both  sides  of  the  paper</span>            </p>        </div>    </body> </html> HTML+CSS
  8. 8. HTML+CSS Viewport in HTML Absolute Positioning in CSS Metadata in OPF
  9. 9. Has anyone seen my viewport?
  10. 10. <meta  name="viewport"   content="width=1200,  height=600"/> 1200 600 1200 600
  11. 11. 600
  12. 12. Why are all these positions so confusing?
  13. 13. #thing1  {   background-­‐color:  pink;   padding:  10px;   }   #thing2  {   background-­‐color:  #CCC;   padding:  10px;   }
  14. 14.   #thing1  {   background-­‐color:  pink;   position:  static;   padding:  10px;   }     #thing2  {   background-­‐color:  #CCC;     position:  relative;     top:  -­‐10px;     left:  20px;     padding:  10px;   }
  15. 15. #thing1  {   top:  55px;   left:  100px;   background-­‐color:  pink;   position:  absolute;   padding:  10px;   }   #thing2  {   top:  110px;   left:  55px;   background-­‐color:  #CCC;     position:  absolute;     padding:  10px;   }
  16. 16. <html> <head>   <meta  name="viewport"  content="width=600,  height=600"  />   <title>The  Earth  Book</title>   <link  href="css/style.css"  type="text/css"  rel="stylesheet"  /> </head> <body> <div  class="page006">   <img  src="components/006.png"  alt="Girl  with  card"  />     <p  class="p6l1">     <span  id="s6l1">I  use  both  sides  of  the  paper</span>   </p> </div> </body> </html> body  {  width:  600px;  height:  600px;  } img  {  position:  absolute;  width:  600px;  height:  600px;  top:  0;  left:  0;   z-­‐index:  -­‐1;  } p  {  position:  absolute;  font-­‐size:  20px;  font-­‐family:  'Parr';  } .page006  >  p  {  top:  50px;  left:  100px;  } CSS HTML
  17. 17. Is this rendition ordinary? <meta  property="dcterms:modified">2013-­‐10-­‐13T19:05:04Z</meta> <meta  property="rendition:layout">pre-­‐paginated</meta> <meta  property="rendition:orientation">portrait</meta> <meta  property="rendition:spread">none</meta> <meta  name="cover"  content="cover-­‐image"/> <meta  property="ibooks:version">1.0.1</meta>
  18. 18. <meta  property="rendition:layout">pre-­‐paginated</meta> <meta  property="rendition:layout">reflowable</meta>
  19. 19. <itemref  id="s22"   properties="rendition:layout-­‐reflowable   rendition:spread-­‐auto"/> Spine Override
  20. 20. Orientation <meta  property="rendition:orientation">landscape</meta> <itemref  id="s009"  properties="rendition:orientation-­‐ portrait"/>
  21. 21. Spread <meta property="rendition:spread">both</ meta> <itemref id="p003" properties="rendition:spread-none"/>
  22. 22. One lump or two? p1.html p2.html p3.html p4.html p5.html p1.html p2–3.html p4–5.html One file, one page One file, one spread
  23. 23. Spread Options none never create synthetic spreads two pages per file / books that don't need spreads landscape only create spreads in landscape portrait only create spreads in portrait both always create spreads one page per file but need spreads auto reading system decides
  24. 24. page-spread-* <itemref  id="page001"   properties="rendition:page-­‐spread-­‐left"/>
  25. 25. Can’t we all just get along?
  26. 26. Amazon <meta  name="original-­‐resolution"  content="1024x600"/>   <meta  name="RegionMagnification"  content="true"/>   <meta  name="book-­‐type"  content="children"/>  
  27. 27. Apple <meta  property="ibooks:ipad-­‐orientation-­‐lock">portrait-­‐only</meta> <meta  property="ibooks:ipad-­‐orientation-­‐lock">landscape-­‐only</meta> <meta  property="ibooks:iphone-­‐orientation-­‐lock">portrait-­‐only</meta> <meta  property="ibooks:iphone-­‐orientation-­‐lock">landscape-­‐only</meta> <meta  property="ibooks:specified-­‐fonts">true</meta> <meta  property="ibooks:binding">false</meta>
  28. 28. Pidgin eBooks • based on HTML+CSS • redundant metadata • one file per spread • use SVG for text on paths • JS popups to enlarge text • design for tablets if possible
  29. 29. How do I teach my book to speak? HTML SMIL AUDIO
  30. 30. <smil>    <body>    <seq>        <par>            <text  src="test.html#word1"/>            <audio  src="audio.mp3"   clipBegin="00:00:00.000"   clipEnd="00:00:01.063"/>        </par>      </seq>        <seq>            <par>              <text  src="test.html#word2"/>              <audio  src="audio.mp3"   clipBegin="00:00:01.063"   clipEnd="00:00:02.871"/>            </par>        </seq>    </body> </smil> <html> <body> <section>   <p>   <span  class="word1">Hello</span>     <span  class="word2">World</span> </p> </section>   </body> </html> HTML SMIL
  31. 31. Doc, what's wrong? • Embed (legally) all your fonts if the design depends on it. • Be wary of text-align: justify • Don't over-constrain boxes • relative positioning • not all CSS is supported • TOC • Viewports
  32. 32. <?xml version="1.0" encoding="UTF-8"?><html xmlns=""><head><meta name="viewport" content="width=864.00, height=1080.00" /><title>Isa Does it</title><link href="styles/ template.css" type="text/css" rel="stylesheet" /><link href="styles/sbs.css" type="text/css" rel="stylesheet" /><link href="styles/sbs-portrait.css" type="text/css" rel="stylesheet" /><link href="styles/slider.css" type="text/css" rel="stylesheet" /><link href="styles/timer.css" type="text/css" rel="stylesheet" /><style type="text/css"> .i0 {position: absolute; left: 79.50px; top: 30px; width: 864.00px; height: 1080.00px; z-index: 00;} .p1 {position: absolute; left: 429.60px; top: 456px; width: 429.60px; height: 23.18px; z-index: 1001; line-height: 17px; text-indent: 27px;} .p3 {position: absolute; left: 429.60px; top: 422px; width: 453.56px; height: 23.18px; z-index: 1003; line-height: 17px;} .p6 {position: absolute; left: 429.60px; top: 371px; width: 437.06px; height: 23.18px; z-index: 1006; line-height: 17px;} .p9 {position: absolute; left: 429.60px; top: 321px; width: 453.51px; height: 23.18px; z-index: 1009; line-height: 17px;} .p12 {position: absolute; left: 429.60px; top: 271px; width: 466.47px; height: 23.18px; z-index: 10012; line-height: 17px;} .p13 {position: absolute; left: 135.00px; top: 544px; width: 158.36px; height: 21.25px; z-index: 10013;} .p15 {position: absolute; left: 150.00px; top: 516px; width: 261.29px; height: 21.25px; z-index: 10015; line-height: 13px; text-indent: -15px;} .p16 {position: absolute; left: 134.62px; top: 494px; width: 123.56px; height: 21.25px; z-index: 10016;} .p19 {position: absolute; left: 150.62px; top: 466px; width: 297.83px; height: 21.25px; z-index: 10019; line-height: 13px; text-indent: -15px;} .p21 {position: absolute; left: 134.62px; top: 445px; width: 216.58px; height: 21.25px; z- index: 10021;} .p23 {position: absolute; left: 135.00px; top: 426px; width: 178.19px; height: 21.25px; z-index: 10023;} .p25 {position: absolute; left: 150.00px; top: 399px; width: 273.50px; height: 21.25px; z-index: 10025; line-height: 13px; text-indent: -15px;} .p26 {position: absolute; left: 134.62px; top: 377px; width: 184.38px; height: 21.25px; z-index: 10026;} .p28 {position: absolute; left: 135.00px; top: 359px; width: 295.56px; height: 21.25px; z-index: 10028;} .p29 {position: absolute; left: 135.00px; top: 341px; width: 243.36px; height: 21.25px; z-index: 10029;} .p31 {position: absolute; left: 150.00px; top: 313px; width: 279.24px; height: 21.25px; z-index: 10031; line-height: 13px; text-indent: -15px;} .p32 {position: absolute; left: 134.62px; top: 291px; width: 242.68px; height: 21.25px; z-index: 10032;} .p34 {position: absolute; left: 135.00px; top: 273px; width: 198.90px; height: 21.26px; z-index: 10034;} .p37 {position: absolute; left: 387.30px; top: 664px; width: 523.01px; height: 22.09px; z-index: 10037; line-height: 20px;} .p43 {position: absolute; left: 387.30px; top: 536px; width: 486.62px; height: 22.09px; z-index: 10043; line-height: 20px;} .p44 {position: absolute; left: 387.66px; top: 202px; width: 464.57px; height: 25.73px; z-index: 10044;} .p47 {position: absolute; left: 299.16px; top: 97px; width: 565.22px; height: 66.15px; z-index: 10047;} .p48 {position: absolute; left: 135.00px; top: 1040px; width: 143.50px; height: 12.88px; z-index: 10048;}</style></head><body class="recipe left peach"><div class="recipeName"><span class="high">Mediterranean</span><br />Overnight Scramble</div><div class="sbs-trigger"></div><div><img src="images/p252.jpg" alt="images" /></ div><div class="new"><p class="p48"><span class="textStyle2855">244 Isa Does It </span></p><p class="p47"><span class="textStyle2857 ls6">mediterranean</span></p><p class="p44"><span class="textStyle2859 ws5">serves 4</span><span class="textStyle2860"> .</span><span class="textStyle2859 ws5"> total time: 20 mins</span><span class="textStyle2860"> .</span><span class="textStyle2859 ws5"> active time: 20 mins</span></p><p class="p43"><span style="line-height: 2px;" class="textStyle141 ws-1">Crumble the tofu into a mixing bowl. </span> <span class="stepSplit"></span> <span style="line-height: 2px;" class="textStyle141 ws-1">Now mash it with your hands until</span><br /><span style="line-height: 2px;" class="textStyle141 ws-1">it’s very crumbly and only pea-size pieces remain. You don’t want it to</span><br /><span style="line-height: 2px;" class="textStyle141 ws-1">be completely mushy. </span> <span class="stepSplit"></span> <span style="line-height: 2px;" class="textStyle141 ws-1">Add the olives, red pepper, lemon juice, nutritional</span><br /><span style="line-height: 2px;" class="textStyle141 ws-1">yeast, thyme, basil, garlic, turmeric, crushed red pepper flakes, salt, and</ span><br /><span style="line-height: 2px;" class="textStyle141 ws-1">black pepper, and mix well with your hands. </span> <span class="stepSplit"></span> <span style="line-height: 2px;" class="textStyle141 ws-1">Cover with plastic wrap and</span><br /><span style="line-height: 2px;" class="textStyle141 ws-1">refrigerate overnight.</span></p><p data-timer-config='{"minutes":"5"}' class="p37"><span style="line-height: 2px;" class="textStyle141 ws-1">In the morning, preheat a large, heavy-bottomed pan over medium-high heat</span><br /><span style="line-height: 2px;" class="textStyle141 ws-1">and add the oil. Cook the tofu for 5 to 7 minutes, stirring occasionally, until</span><br /><span style="line-height: 2px;" class="textStyle141 ws-1">heated through and lightly browned. Serve.</span></p><p class="p34"><span class="textStyle1908">14 ounces extra</span><span class="textStyle1911">–</span><span class="textStyle1908">firm tofu</span></p><p class="p32"><span class="textStyle141a">¼</span><span class="textStyle1908"> cup kalamata olives, chopped</span></p><p class="p31"><span style="line-height: 2px;" class="textStyle1908">1 roasted red pepper (store</span><span style="line-height: 2px;" class="textStyle1911">–</span><span style="line-height: 2px;" class="textStyle1908">bought</span><br /><span style="line-height: 2px;" class="textStyle1908">or homemade; see <a href="p118.xhtml">page 118</a>)</span></p><p class="p29"><span class="textStyle1908">2 tablespoons fresh lemon juice</span></p><p class="p28"><span class="textStyle1908">2 tablespoons nutritional yeast flakes</span></p><p class="p26"><span class="textStyle141a">½</span><span class="textStyle1908"> teaspoon dried thyme</span></p><p class="p25"><span style="line-height: 2px;" class="textStyle1908">2 tablespoons finely chopped fresh</span><br /><span style="line-height: 2px;" class="textStyle1908">basil leaves</span></p><p class="p23"><span class="textStyle1908">2 cloves garlic, minced</span></p><p class="p21"><span class="textStyle141a">¼</span><span class="textStyle1908"> teaspoon ground turmeric</span></p><p class="p19"><span style="line-height: 2px;" class="textStyle141a">¼</span><span style="line-height: 2px;" class="textStyle1908"> teaspoon crushed red pepper flakes</span><br /><span style="line- height: 2px;" class="textStyle1908">(optional)</span></p><p class="p16"><span class="textStyle141a">¼</span><span class="textStyle1908"> teaspoon salt</span></p><p class="p15"><span style="line-height: 2px;" class="textStyle1908">Several pinches of freshly ground</span><br /><span style="line-height: 2px;" class="textStyle1908">black pepper</span></p><p class="p13"><span class="textStyle1908">1 tablespoon olive oil</span></p><p class="p12"><span style="line-height: 2px;" class="textStyle31 ws-1">If you can take 10 minutes to mash a bunch of stuff up in a bowl the</ span><br /><span style="line-height: 2px;" class="textStyle31 ws-1">night before, you can have scrambled tofu in 7 minutes the next</span><br /><span style="line-height: 2px;" class="textStyle31 ws-1">morning.This scramble is perfect for tucking into an on</span><span style="line-height: 2px;" class="textStyle1910">–</span><span style="line-height: 2px;" class="textStyle31 ws-1">the</span><span style="line-height: 2px;" class="textStyle1910">–</span><span style="line-height: 2px;" class="textStyle31 ws-1">go</span></p><p class="p9"><span style="line-height: 2px;" class="textStyle31 ws-1">wrap, with things like avocado, hummus, and lettuce, or try a big</span><br /><span style="line-height: 2px;" class="textStyle31 ws-1">scoop on your bagel. Of course, you can also serve it with roasted</span><br /><span style="line-height: 2px;" class="textStyle31 ws-1">potatoes, like a civilized human being.What’s so great is how</span></p><p class="p6"><span style="line-height: 2px;" class="textStyle31 ws-1">effortless it is. There’s a little chopping, but nothing you can’t</span><br /><span style="line-height: 2px;" class="textStyle31 ws-1">handle before bed, and the rest is just like playing in the sandbox,</span><br /><span style="line-height: 2px;" class="textStyle31 ws-1">mushing the tofu up with your hands and adding a host of flavorful</span></p><p class="p3"><span style="line-height: 2px;" class="textStyle31 ws-1">ingredients that season your tofu as you sleep.A quick sauté the</span><br /><span style="line-height: 2px;" class="textStyle31 ws-1">next morning and you’re done.</span></p><p class="p1"><span style="line-height: 2px;" class="textStyle31 ws-1">Naturally, if you want to make this right away and eat it, that</span><br /><span style="line-height: 2px;" class="textStyle31 ws-1">is totally cool, too. No need to let it sit overnight.</span></p><script src="scripts/libs/jquery.js"></script><script src="scripts/events.js"></script><script src="scripts/Timer.js"></script><script src="scripts/slider.js"></script><script src="scripts/libs/iscroll.js"></script><script src="scripts/autoMailer.js"></script><script src="scripts/SBS.js"></script></div></body></html> Are you kidding?
  33. 33. Questions but, perhaps, not answers
  34. 34. ThankYou! Dave Cramer @dauwhe