Better: A Process

Through The Looking-Glass

Dave Liepmann, Clay Harmon, and Ibrahim Saberi

May 1, 2019

Disclaimer: This post is like 95% straight up taken from others on Tufte CSS.

An Intro To Tufte CSS

The Tufte Jekyll theme is an attempt to create a website design with the look and feel of Edward Tufte’s books and handouts. Tufte’s style is known for its extensive use of sidenotes, tight integration of graphics with text, and well-set typography. The idea for this project is essentially cribbed wholesale from Tufte and R Markdown’s Tufte Handout format.See this and this. This page is an adaptation of the Tufte Handout PDF. I give my thanks to all the people who have contributed to these projects!

If you see anything that Tufte CSS could improve, your contribution is welcomed in the form of an issue or pull request on the Github project: tufte-css. Please note the contribution guidelines.

This adaptation of Tufte CSS does diverge slightly from the original guidelines. The core of the guidelines are still the same, but things like link styling have changed. I’ll make note of which changes I (or Clay Harmon) have made below.

A final note from Dave Liepmann when he originally wrote on Tufte CSS:

[A] reminder about the goal of this project. The web is not print. Webpages are not books. Therefore, the goal of Tufte CSS is not to say “websites should look like this interpretation of Tufte’s books” but rather “here are some techniques Tufte developed that we’ve found useful in print; maybe you can find a way to make them useful on the web”. Tufte CSS is merely a sketch of one way to implement this particular set of ideas. It should be a starting point, not a design goal, because any project should present their information as best suits their particular circumstances.

Fundamentals

Sections and Headings

Organize your document with an article element inside your body tag. Inside that, use sectionThe section tag isn’t something that’s natively parsed by Markdown. I’ve created a Liquid block section, but it ends up breaking a lot of kramdown parsing (so I don’t use it, or sections for that matter). You can also just write in HTML. tags around each logical grouping of text and headings.

Tufte CSS uses h1 for the document title, p with class subtitle for the document subtitle, h2 for section headings, and h3 for low-level headings. More specific headings are not supported. If you feel the urge to reach for a heading of level 4 or greater, consider redesigning your document:

[It is] notable that the Feynman lectures (3 volumes) write about all of physics in 1800 pages, using only 2 levels of hierarchical headings: chapters and A-level heads in the text. It also uses the methodology of sentences which then cumulate sequentially into paragraphs, rather than the grunts of bullet points. Undergraduate Caltech physics is very complicated material, but it didn’t require an elaborate hierarchy to organize.Markdown doesn’t have native cite support. I created a cite tag in Liquid that floats the attribution to the right and adds a link if that’s present as a 2nd attribute. It’s not implemented exactly as it is in Tufte CSS but it gets the job done. 🤷🏾‍

Edward Tufte, forum post, ‘Book design: advice and examples’ thread

As a bonus, this excerpt regarding the use of headings provides an example of block quotes. In Tufte CSS they are just lightly styled, semantically corrent HTML using blockquote and footer elements (refer to sidenote 3 on how this is actually accomplished). See page 20 of The Visual Display of Quantitative Information for an example in print.

In his later books ,Beautiful Evidence Tufte starts each section with a bit of vertical space, a non-indented paragraph, and the first few words of the sentence set in small caps. For this we use a span with the class newthought, as demonstrated at the beginning of this paragraph.Clay Harmon created a newthought Liquid tag that accomplishes this. I’m currently working on making it so that the additional space doesn’t get inserted automatically (as seen at the beginning of this paragraph). Vertical spacing is accomplished separately through <section> tags. Be consistent: though we do so in this paragraph for the purpose of demonstration, do not alternate use of header elements and the newthought technique.Oops. Pick one approach and stick to it.

Text

Although paper handouts obviously have a pure white background, the web is better served by the use of slightly off-white and off-black colors. Tufte CSS traditionally uses #fffff8 and #111111 because they are nearly indistinguishable from their ‘pure’ cousins, but dial down the harsh contrast. We stick to the greyscale for text, reserving color for specific, careful use in figures and images.Clay Harmon’s original style uses color for sidenotes and other links. I originally agreed with this approach since it unified the style with colored sidenotes (which is done because otherwise it’s near impossible to tell that they’re clickable), but marking up this article made me realize how distracting the red colored links are. I’ve since reverted to the original style.

In print, Tufte has used the Monotype BemboSee Tufte’s comment in the Tufte book fonts thread. font. A similar effect is achieved in digital formats with the now open-source ETBook, which the original Tufte CSS supplies with a @font-face reference to a .ttf file. In case ETBook somehow doesn’t work, Tufte CSS shifts gracefully to other serif fonts like Palatino and Georgia.

Also notice how Tufte CSS includes separate font files for bold (strong) and italic (emphasis), instead of relying on the browser to mechanically transform the text. This is typographic best practice.

If you prefer sans-serifs, use the sans class. It traditionally relies on Gill Sans, Tufte's sans-serif font of choice.I've created a Liquid tag for this (that also haphazardly rendered this sidenote in Gill Sans), because I clearly have written enough HTML for a lifetime.

Links in traditional Tufte CSS match the body text in color and do not change on mouseover or when clicked. Here is a dummy example that goes nowhere. These links are underlined, since this is the most widely recognized indicator of clickable text. However, because most browsers’ default underlining does not clear descenders and is so thick and distracting, the underline effect is instead achieved using CSS trickery involving background gradients instead of standard text-decoration. Credit goes to Adam Schwartz for that technique.

As always, these design choices are merely one approach that Tufte CSS provides by default. Other approaches, such as changing color on click or mouseover, or using highlighting or color instead of underlining to denote links, could also be made to work. The goal is to make sentences readable without interference from links, as well as to make links immediately identifiable even by casual web users.I use Crimson Text and Rubik as my fonts of choice.

Sidenotes: Footnotes and Marginal Notes

One of the most distinctive features of Tufte’s style is his extensive use of sidenotes.This is a sidenote. Sidenotes are like footnotes, except they don’t force the reader to jump their eye to the bottom of the page, but instead display off to the side in the margin.

Perhaps you have noticed their use in this document already. You are very astute.

Dave Liepmann

I really couldn’t allow this part of the original Tufte CSS document to ever be attributable to me (not that the vast majority of this document should ever be attributable to me). So here’s the quote, to be preserved here for posterity. Now. Um. Back to sidenotes.

Sidenotes are a great example of the web not being like print. On sufficiently large viewports, Tufte CSS uses the margin for sidenotes, margin notes, and small figures. On smaller viewports, elements that would go in the margin are hidden until the user toggles them into view. The goal is to present related but not necessary information such as asides or citations as close as possible to the text that references them. At the same time, this secondary information should stay out of the way of the eye, not interfering with the progression of ideas in the main text.

Sidenotes consist of two elements: a superscript reference number that goes inline with the text, and a sidenote with content. To add the former, just put a label and dummy checkbox into the text where you want the reference to go, like so:


<label for="sn-demo"
       class="margin-toggle sidenote-number">
</label>
<input type="checkbox"
       id="sn-demo"
       class="margin-toggle"/>

You must manually assign a reference id to each side or margin note, replacing “sn-demo” in the for and the id attribute values with an appropriate descriptor. It is useful to use prefixes like sn- for sidenotes and mn- for margin notes.Verdict is still out on whether this is actually useful or not.

Immediately adjacent to that sidenote reference in the main text goes the sidenote content itself, in a span with class sidenote. This tag is also inserted directly in the middle of the body text, but is either pushed into the margin or hidden by default (if you’re on mobile for example). Make sure to position your sidenotes correctly by keeping the sidenote-number label close to the sidenote itself. This can easily be accomplished by just copying the Tufte CSS styles.

If you want a sidenote without footnote-style numberings, then you want a margin note.This is a margin note. Notice there isn’t a number preceding the note. On large screens, a margin note is just a sidenote that omits the reference number. This lessens the distracting effect taking away from the flow of the main text, but can increase the cognitive load of matching a margin note to its referent text. However, on small screens, a margin note is like a sidenote except its viewability-toggle is a symbol rather than a reference number. This document currently uses the symbol ⊕ (&#8853;), but it’s up to you.

Margin notes are created just like sidenotes, but with the marginnote class for the content and the margin-toggle class for the label and dummy checkbox. For instance, here is the code for the margin note used in the previous paragraph:


<label for="mn-id-mn" class="margin-toggle">&#8853;</label>
<input type="checkbox" id="mn-id-mn" class="margin-toggle"/>
<span class="marginnote">
  This is a margin note. Notice there isn't a number preceding the note.
</span>

Figures in the margin are created as margin notes, as demonstrated in the next section.

Figures

Tufte emphasizes tight integration of graphics with text. Data, graphs, and figures are kept with the text that discusses them. In print, this means they are not relegated to a separate page. On the web, that means readability of graphics and their accompanying text without extra clicks, tab-switching, or scrolling.

Figures should try to use the figure element, which by default are constrained to the main column.This is accomplished with a Liquid tag courtesy of Clay Harmon. Don’t wrap figures in a paragraph tag. Any label or margin note goes in a regular margin note inside the figure. For example, most of the time one should introduce a figure directly into the main flow of discussion, like so:

From Edward Tufte, Visual Display of Quantitative Information, page 92
exports and imports

rhino time
F.J. Cole, “The History of Albrecht Dürer’s Rhinoceros in Zoological Literature,” Science, Medicine, and History: Essays on the Evolution of Scientific Thought and Medical Practice (London, 1953), ed. E. Ashworth Underwood, 337-356. From page 71 of Edward Tufte’s Visual Explanations.
But tight integration of graphics with text is central to Tufte’s work even when those graphics are ancillary to the main body of a text. In many of those cases, a margin figure may be most appropriate. To place figures in the margin, just wrap an image (or whatever) in a margin note inside a p tag, as seen to the right of this paragraph.

For whatever odd reason, full-width figures won’t properly clear any margin notes or margin figures if the space they inhabit clashes. I’m not sure if this is a bug with the Liquid tag used for full-width figures (I don’t think it is), but it doesn’t seem like it’s related to the CSS being different; I’ve looked at both the theme and Tufte CSS and haven’t found any differences that would cause this problem. Anyway, this additional text and explanation is primarily meant to help the full-width figure below clear the margin figure above.

If you need a full-width figure, give it the fullwidth class. Make sure that’s inside an article, and it will take up (almost) the full width of the screen. This approach is demonstrated below using Edward Tufte’s English translation of the Napoleon’s March data visualization. From Beautiful Evidence, page 122-124.

Napoleons March
Napoleon's March (Edward Tufte’s English translation)

One obstacle to creating elegant figures on the web is the difficulty of handling different screen sizes, especially on the fly. Embedded iframe elements are particularly troublesome. For these instances we provide a helper class, iframe-wrapper, the most common use for which is probably YouTube videos, e.g.


<figure class="iframe-wrapper">
  <iframe src="https://www.youtube.com/embed/YslQ2625TR4" frameborder="0" allowfullscreen></iframe>
</figure>

I implemented this as a Liquid tag that only accepts the src attribute for the iframe as an argument. The Tufte CSS original implementation is kind of ugly so I also reduced the padding-bottom that determines the height for the iframe so that it isn’t so squarish. The implementation certainly isn’t perfect by any means and I’ll be toying around with this in the future to see if there’s a better way to inject the current document width/ height into the iframe for this Liquid tag.

The original implementation also allowed for the iframe-wrapper helper class to be thrown onto divs. I don’t know what the hell a div is, so I didn’t allow for that.

Also, if you bothered to watch this video, you’ll find that Tufte has some extremely hot takes on how he’d reorganize some of the UI elements in different iOS apps. It was honestly cringe enough that I’m gonna dedicate a blog post to breaking down those suggested changes and why they’re largely, well, not very good. More on that later.

Code

I’m not gonna lie, code syntax is at times a humongous pain in the ass in markdown. In raw HTML, you use the code tag inline or you surround a bunch of code tags with a pre tag if you want to show off a block of code. Fonts on this webpage for code segments will always try to use Github’s Consolas but will fail back to the well known Courier.

For placing code inline, you surround said code with backticks: `put code here` becomes put code here.

Triple backticks can be used for code blocks (you can also input a language for proper syntax highlighting):

` ` `javascript

let foo = bar;

```

becomes


let foo = bar;

This method breaks if you put HTML in a code block. You can use triple tildes (~~~) instead in that case.

ImageQuilts

I’m not gonna lie, I think these just might be the funniest things on the planet. I have no idea what function they serve other than to look like cool abstract art. Here’s one below:

imagequilt
ImageQuilt Example

The original Tufte CSS has included “support” for these. I have no idea what the hell that means. The above image is just a .png file. I haven’t really looked into what an ImageQuilt is and I probably don’t plan on “supporting” them on this site.

Jekyll customizations

To reiterate, the original Jekyll blog theme is based on the github repository by Edward Tufte here, which was orginally created by Dave Leipmann, but is now labeled under Edward Tufte’s moniker. Clay Harmon, the original creator of this blog theme, transformed many of the typographic and page-structural features into a set of custom Liquid tags that make creating content using this style much easier than writing straight HTML. I’ve gone ahead and added to those liquid tags to allow for better interpolation between HTML and markdown and to better format some of the Tufte CSS styles once they’re parsed. Essentially, if you know markdown, and mix in a few custom Liquid tags, you can be creating a website with this document style in short order.

The remainder of this post will be a survey of the additional features of the Tufte-Jekyll theme.

Lists

Tufte points out that while lists have valid uses, they tend to promote ineffective writing habits due to their “lack of syntactic and intellectual discipline”. He is particularly critical of hierarchical and bullet-pointed lists. So before reaching for an HTML list element, ask yourself:

  • Does this list actually have to be represented using an HTML ul or ol element?
  • Would my idea be better expressed as sentences in paragraphs?
  • Is my message causally complex enough to warrant a flow diagram instead?

This is but a small subset of a proper overview of the topic of lists in communication. Tufte CSS encourages caution before reaching for a list element, and by default removes the bullet points from unordered lists.

The original Jekyll theme created by Clay Harmon also removed bullet points from ordered lists. I have readded those. Because I like lists.

Equations

The Markdown parser being used by this Jekyll theme is Kramdown, which contains some built-in Mathjax support. Both inline and block-level mathematical figures can be added to the content.

For instance, the following inline sequence:

When , there are two solutions to

is written by enclosing a Mathjax expression with a Liquid inline tag pair (‘m’ and ‘em’) like so:

When {% m %} a \ne 0{% em %}, there are two solutions to {% m %}ax^2 + bx + c = 0{% em %}

Similarly, this block-level Mathjax expression:

is written by enclosing the expression with a Liquid block tag pair (‘math’ and ‘endmath’) like so:

{% math %}x = {-b \pm \sqrt{b^2-4ac} \over 2a}.{% endmath %}

You can get pretty fancy, for instance, the wave equation’s nabla is no big thing:

All of the standard Latex equation markup is available to use inside these block tags.

Please note that the block-level Mathjax expressions must be on their own line, separated from content above and below the block by a blank line for the Kramdown parser and the Mathjax javascript to play nicely with one another.

The Mathjax integration is tricky,It was also initially broken. When I first looked into Mathjax when integrating this theme, it looked like the project was gone or had lost support. I’m using an old cdnjs source at the moment but I’m not sure what all will work or not. and some things such as the inline matrix notation simply do not work well. Bottom line: If you are using this to document mathematics, be super careful to isolate your LaTeX blocks by blank lines!

Tables

Tables are, frankly, a pain in the ass to create. That said, they often are one of the best methods for presenting data. Tabular data are normally presented with right-aligned numbers, left-aligned text, and minimal grid lines.

Note that when writing Jekyll Markdown content, there will often be a need to get some dirt under your fingernails and stoop to writing a little honest-to-god html. Yes, all that hideous <table>..<thead>..<th> nonsense. And you must wrap the unholy mess in a <div class="table-wrapper"> tag to ensure that the table stays centered in the main content column.

Tables are designed with an overflow:scroll property to create slider bars when the viewport is narrow. This is so that you do not collapse all your beautiful data into a jumble of letters and numbers when you view it on your smartphone.

Table 1: A table with default style formatting

Content and tone of front-page articles in 94 U.S. newspapers, October and November, 1974 Number of articles Percent of articles with negative criticism of specific person or policy
Watergate: defendants and prosecutors, Ford’s pardon of Nixon
537
49%
Inflation, high cost of living
415
28%
Government competence: costs, quality, salaries of public employees
322
30%
Confidence in government: power of special interests, trust in political leaders, dishonesty in politics
266
52%
Government power: regulation of business, secrecy, control of CIA and FBI
154
42%
Crime
123
30%
Race
103
25%
Unemployment
100
13%
Shortages: energy, food
68
16%

This is not the One True Table. Such a style does not exist. One must craft each data table with custom care to the narrative one is telling with that specific data. So take this not as “the table style to use”, but rather as “a table style to start from”. From here, use principles to guide you: avoid chartjunk, optimize the data-ink ratio (“within reason”, as Tufte says), and “mobilize every graphical element, perhaps several times over, to show the data.Page 139, The Visual Display of Quantitative Information, Edward Tufte 2001. Furthermore, one must know when to reach for more complex data presentation tools, like a custom graphic or a JavaScript charting library.

As an example of alternative table styles, academic publications written in LaTeX often rely on the booktabs package to produce clean, clear tables. Similar results can be achieved in Tufte CSS with the booktabs class, as demonstrated in this table:

Table 2: A table with booktabs style formatting

Items
AnimalDescriptionPrice ($)
Gnat per gram13.65
each 0.01
Gnu stuffed 92.50
Emu stuffed 33.33
Armadillofrozen 8.99

Clay Harmon liked this style of table, so they have made it the default for unstyled tables. This allows use of the Markdown Extra features built into the Kramdown parser. Here is a table created using the Markdown Extra table syntax to make a nice table which has the side benefit of being human readable in the raw markdown file:

Table 3: originally a table created with Markdown Extra styling (that was 100% broken), I have gone ahead and just created a tablewrapper Liquid tag that better handles this

  mpg cyl disp hp drat wt
Mazda RX4 21 6 160 110 3.90 2.62
Mazda RX4 Wag 21 6 160 110 3.90 2.88
Datsun 710 22.8 4 108 93 3.85 2.32
Hornet 4 Drive 21.4 6 258 110 3.08 3.21
Hornet Sportabout 18.7 8 360 175 3.15 3.44
Valiant 18.1 6 160 105 2.76 3.46

Using the following markup(down):


|                 |mpg  | cyl  |  disp  |   hp   |  drat  | wt  |
|:----------------|----:|-----:|-------:|-------:|-------:|----:|
|Mazda RX4        |21   |6     |160     |110     |3.90    |2.62 |
etc..

The following is a more simple table, showing the Markdown-style table markup. Remember to label the table with a marginnote Liquid tag, and you must separate the label from the table with a single blank line. This markup:


<label for='Table-ID4' class='margin-toggle'> &#8853;</label><input type='checkbox' id='Table-ID4' class='margin-toggle'/><span class='marginnote'>Table 4: a simple table showing left, center, and right alignment of table headings and data </span>

|**Left** |**Center**|**Right**|
|:--------|:--------:|--------:|
 Aardvarks|         1|$3.50
       Cat|   5      |$4.23
  Dogs    |3         |$5.29

Yields this table:

Table 4: a simple table showing left, center, and right alignment of table headings and data

Left Center Right
Aardvarks 1 $3.50
Cat 5 $4.23
Dogs 3 $5.29
© 2019 - The Galleria By Ibrahim Saberi