Premium Superbooks 📚


Three months ago we made an announcement on Hacker News that made it to the top of the front page.

It was around 11:00 pm in the night when our show:hn link started ticking on the dashboard and over a period of next 24 hours we recieved plenty of actionable feedback, lots of useful criticism and a total of 376 signups.

We were onto something.



Today, I’m super happy to announce our first premium Superbook on the web: The Return of Exile by David Eyk. 🍻


[ Image credit: David Eyk]


The Return of Exile is David’s first book from an eight-part space opera the Salvage of Empire.

It’s a cliffhanger, and I’m sure you’ll love reading the first episode just as much as I did. The book features twenty fullbleed bifolium illustrations, a clever plot and a very strong protagonist. It is inlaid with responsive typography and an near impeccable* formatting that we have invented along the way. We’ll discuss more about this, shortly.

*impeccable. The formatting isn’t as airtight as we would like in the first edition of David’s book, but we are close. While there have been few improvements on our layouting code since his book was published two weeks ago, there is still some more distance to go for better resilience and scalability. Since the format is still early tech we are looking for solutions along with suggestions and tips! As one of the founders of the project I wish to lay here that even though we are following the definition of common book for Superbooks, this is being done without picking up skeuomorphic elements of the physical form. In the end, since the book is on web, its formatting has to remain webbish and accessible across the board.

The book is iPad first and offline first. It is supported almost everywhere via the web browser. I expect it to work on Apple Watch Safari too, but we couldn’t test it because my watch is an older version. Feedback so far has been great and about 3% readers confirmed that the experience was ideal (magical even) on the iPad, in landscape mode.

Well, we might be rooting for the promise of post-pc era on web here, but YMMV!

Let’s look at how David’s book was made and how you can publish your own book on the web too!

Working on David’s book was exactly the kind of opportunity we had been waiting for and Hacker News was instrumental in helping us connect. His expertise on typesetting and the formatting standards of a physical book was an excellent north star for us to follow. Through his book we were able to develop a formula to scale content on the browser without triggering a reflow (does not work precisely on Safari, but does work good enough).

This was deemed impossible on the web until now.

I personally believe that pagination without reflow is critical for books to succeed on web. Avoiding reflow is possible and we can already see that it has some wonderful side-effects. Since all of the content on book sits above-the-fold and scaled economically, the book becomes immediately referenceable via page numbers. This makes it possible for students to send their friends straight to page number 510 of Pride and Prejudice, for example, to find out what Ms. Elizabeth says to Mr. Darcy when she is unhappy.

It’s literally being on the same page, on web!

With this kind of referential integrity there is room for conversations and annotations on the book without confusion. Using standard HTML with quality markup and ARIA labels ensures accessibility for one and all.

The formula for scalable typography solves a middle path between a fluid and fixed layout, both of which have been a bane of publishing industry for a while. It is now available as a layout template under Blue Oak License 1.0.0 for further exploration. We have also written a tiny CLI tool called m2s to quickly convert markdown files into web-compatible Superbooks.

Here’s how it works:

For the purpose of clarity,

  1. Manuscript is one which is not ‘consumer-ready’ immediately.
  2. Book is one which is ‘consumer-ready’ and ‘distribution-ready’ both.

Going by these definitions, this repo on Github, which carries the sourcecode of The Kama Sutra is a manuscript. I’m using the source code behind the book The Kama Sutra by Vātsyāyana for examples below. This code is in a state of great flux but will give you a solid insight on how Superbooks work and how to manage line-tracking, orphans and widows responsively on the web. Feel free to reach me on marvin at bubblin dot io if you have any questions or comments or tweet/dm me @marvindanig:

First off, we chose typography as per standard for our book:

<link href='https://fonts.googleapis.com/css?family=EB+Garamond:400,400i|Berkshire+Swash' rel='stylesheet' type='text/css'>
<title> The Kamasutra by Vatsyayana | Bubblin Superbooks | Bookiza </title>

The two lines shown above go into the HEAD template of the book so that the required typography gets applied across the entire book!

Leaving the first five pages of the book aside, the body of book will use the following HTML template:

<div class="leaf flex">
  <div class="inner justify ">
    <h1> Hello world! </h1>
    <p> Lorem ipsum dolor sit amet, <a href="https://wikipedia.com">consectetur</a> adipiscing elite... </p>
  </div>
</div>

You might want to checkout the structure of a page on a Superbook to understand how the HTML template and HEAD template shown above works.

The manuscript of The Kama Sutra uses a very small HTML vocabulary like the p, div, h1, h2, h3, a and hr tags with occasional use of blockquote or list. The book on Bubblin will use images at some point in future, so we’ll reset CSS for images too. It is safe to assume that the vocabulary on this book is a subset of markdown.

Since a page on a Superbook is basically a sandboxed iframe, we’re going to style the entire book with the following template:


/* 
* Tip:	Please keep copious amounts of patience at hand. :-)
*
*	This template will not work on apps because it doesn't follow the normal 'app design or development' techniques.
*	We'll assume that the Superbook container will maintain aspect ratio the page on book at all times and that the page will   
*	always remain above the fold.
*/



html, body {
  background: #fff;
  margin: 0 0;  				 /* Kill default margin on Chrome/webkit */
  overflow: hidden;
  color: #000;
  height:100vh;
  width:100vw;
  font-family: 'EB Garamond', serif;
  font-style: normal;
  font-synthesis: none;
  font-stretch: ultra-condensed;
  font-variant: no-common-ligatures proportional-nums slashed-zero;
  font-size: 4vw;
  line-height: calc(4vw * 1.50); /* Set the line-height for text at 150% for accessibility and numeric precision */ 
  font-kerning: normal;
  text-rendering: geometricPrecision;
}


h1, h2, h3, h4 {
  padding: 0;
  color: #444;
  width: 100%;
  text-align: center;
  font-weight: 100;
}

h1,
h2,
h3,
h4,
h5,
h6 {
    font-family: 'Berkshire Swash', cursive;
    margin: calc((4vw * 1.50)/2) 0;  	/* Take up half a line-height above, half below. */
    padding: 0;
}


img {
  border: 0;
  -ms-interpolation-mode: bicubic;
}

a {
  color: #0077ff;
  outline: 0 none;
  text-decoration: none;
}

a:focus,
a:active,
a:hover {
  outline: 0 none;
  color: #070;
}

a:active {
  text-shadow: 0 0 2px #fff;
}

/* Page specific */

.leaf {
  height: 100%;
  height: 100vh;
  width: 100%;
  width: 100vw;
  margin: auto;
}

.inner {
  margin: calc((100vh - (17 * (4vw * 1.5) + 4vw))/2) auto; 
  width: 85vw;
  max-height: calc(17 * (4vw * 1.5) + 4vw);	/* Allow a maximum of 18 lines per page for line-tracking */
  break-after: right; 
  /* background: goldenrod; */		/* Toggle the background to see the maximum staging area.  */
}

/* The .inner div above is centered using flex class below, but it still carries a `margin: calc((100vh - (17 * (4vw * 1.5) + 4vw))/2) auto;`. Why is that, can you tell? */

.flex { 
  display: -webkit-box; 
  display: flex !important;
  align-items: center;
  justify-content: center;
}

.justify {
  text-align: justify;
}

p {
    text-indent: 5vw;	/* Indent at the start of a para */
    margin: 0 0 0 0;
    -webkit-hyphens: none;
    -moz-hyphens: none;
    hyphens: none; 
}

.no-indent {
  text-indent: 0;	/* Kill indent if the para is split over to next page */
}

.stretch-last-line {
  text-align-last: justify;	/* Stretch the last line of the split para on the previous page */
}

/* Manual helpers */

.squeeze-para{
  letter-spacing: -0.5px; /* Kill orphans and widows manually, by squeezing if required */
}

.stretch-para{
  letter-spacing: +0.5px; /* Kill orphans and widows manually, by stretching if required */
}


/* Separators */


hr.section {
  border: 0;
  text-align: center;
  height: calc(4vw * 1.50);          /* Take a break of two lines only. */
  margin: calc((4vw * 1.50)/2) 0; 
}

hr.section::after {
  content: "";
}

hr.section::before {
  content: "❉"; 
  color: black;
}


hr.chapter {
  border: 0;
  text-align: center;
  height: calc(4vw * 1.50);          /* Take a break of two lines only. */
  margin: calc((4vw * 1.50)/2) 0; 
}

hr.chapter::after {
  content: " ";
}

hr.chapter::before {
  content: "❧";
  color: black;
}


hr {
  border: 0;
  text-align: center;
  height: calc(4vw * 1.50);          /* Take a break of two lines only. */
  margin: calc((4vw * 1.50)/2) 0; 
}

hr::after {
  content: "";
}

hr::before {
  content: "✧";
  color: black; 
}


blockquote {
  text-align:center;
  font-size: 90%;
  font-style: italic;
  position:relative;
  quotes: "\201C""\201D""\2018""\2019";
  width: 90%;
  margin: calc( 4 * (150vh *(1115/1443))/100 * 7/5) auto;
}

blockquote p {
  margin: calc( 4 * (150vh *(1115/1443))/100 * 7/5) auto !important;
}


pre, code {
  white-space: pre-wrap;     
  white-space: -moz-pre-wrap;
  white-space: -pre-wrap;  
  white-space: -o-pre-wrap;
  word-wrap: break-word;
  margin: 0 auto calc( 4 * (150vh *(1115/1443))/100 * 7/5); 
  font-size: 90%;  
}

.uppercase {
  text-transform: uppercase;  
}


ol {
  margin: calc((4vw * 1.50)/2) 5vw; 
  padding: 0;
  list-style-type: none;
  counter-reset: step-counter calc(var(--start) - 1);
}

ol li {
  counter-increment: step-counter;
}

ol li::before {
  content: counter(step-counter) ". ";
  margin-right: 1vw;
  color: black; 
  font-weight: bold;
  padding: 0.3vw 0.8vw 0.3vw 0;
}

ol li.split-li {
}

ol li.split-li::before {
  content: '';
  margin-right: -0.8vw;
  background-color: rgba(255, 255, 255, 1);
  color: black;
  font-weight: bold;
  padding: 0.3vw 0.8vw 0.3vw 0;
}


ul {
  margin: 0 0 0 5vw;
  padding: 0;
  list-style: none;
}

ul li {
  margin: 0;
  padding: 0;
}


/* Helper classes */

.pad-vertically{
  padding: calc(4vw * 1) 0;
}


.center {
  text-align: center;
  margin:0 auto;
}

.small {
  font-size: 80%;
}


/* Book specific customization */

h3 {
  font-family: 'Berkshire Swash', cursive;
  line-height: 1.2em;
  color: black;
  font-size: 200%; 
}

.berkshire {
  font-family: 'Berkshire Swash', cursive;
  line-height: 300%;
  color: black;
}


Great, now at the root of your manuscript ( bookiza project):


$ m2s objectify & m2s pagify		/* Wait for m2s to paginate the content as specified on the layout template */
$ m2s bookify.                      /* This command will fill up the pages into /manuscript folder of your bookiza project.

To test:
$ bookiza server 					// Opens the book on localhost:4567

Once your book is ready:

$ bookiza publish

That’s it. Your book is now on web. It is responsive, it has luxurious paragraphs with line-tracking, content scaling, no orphans and widows and best of all it works everywhere.


Written by: Marvin Danig, CEO of Bubblin Superbooks. Follow me on Twitter perhaps?

P.S.: It’s likely that you read this post on your desktop. That’s obsolete. We recommend you revisit us on your iPad!