Ink CSS for knitR. Click here to see a demo on RPubs. You can also see the same report on the default template by clicking here.

InkCSS for knitR

A better way to explore and tell your data story.

Over my days as a data scientist research assistant, I have continuously needed to crunch data, generate various plots, and draw conclusions to report to myself and to other people. This work also involved seeing others analysis reports. And there lied my problem.

Being exposed to concepts from Edward Tufte, Clevand, Alberto Cairo and Don Normann about design and visualization, some reports were just too hard to deal with. If you don’t believe me, here is an example:

This data analysis “report” was loaded on a big screen for the group appreciation and discussion. The code is embedded with annotations (rather than the other way around!) explaining how the analysis was done. The code was cut and paste from a console to the group’s Google page journal.

Here are some problems with this kind of report:

  • It is hard to tell apart text from code.
  • It is hard to navigate around (there are no headings or menu).
  • A consequence of lack of headings is the inability of a reader to see the main chunks (or method) used to simplify his / her mental model of the report.
  • Can only be reused after some (considerable) work (given output and commands are mixed someone will have to manually distinguish them).

I will go ahead and remember this is not the worst case scenario, most of the times no code, notes or even memory of what was done can be found. Then again, maybe you are better off without any if your advisor tells you to “use as a reference” these reports.

knitR to the rescue

If one of these post tags lured you here, then you are most likely familiar with knitR and RStudio (if not, I urge you to Google those terms and learn more about them! ☺).

knitR offers a solution to these problems which, in my opinion, has an extremely low learning cost to someone who can code in R. Here is what I mean:

Default knitR template. The table of contents is generated automatically by the usage of Markdown on the raw source file. A reader can quickly click on a given section of the TOC to “jump” to the section.
Graphs and and code on knitrR default template provides a clear separation of analysis results and code snippets. The .Rmd source file also enable a programmer to quickly re-run the analysis on any computer.

You can also see this particular class project report on Rpubs by clicking here. Although knitR using it’s default template address all the previous problems, a couple more came to surface as more iterations happened on my research project using it:

  • “Stuck on the top” table of contents: Over time, as the raw report grew in size (as opposed to the one you would submit to a conference or refer outsiders after a talk), navigating it became cumbersome. A continuous need to scroll up and down made finding and comparing information extremely frustrating. This was even more true when the group discussions had no story to be told (yet) and the flow of the analysis was ,at best, a guess.
  • “Big picture is still big!”: For large reports, even with a TOC to understand what lies in there, by the time the group was done discussing one topic, the big picture was long gone.
Sometimes to meet weekly deadlines and in order to quickly navigate over all the information that may be required during a meeting without shuffling over many tabs, a report can grow considerable large!
  • “Which data set is this analysis associated to again?”: Another continuous problem was the headers for some of my group mates. Having only the size to distinguish from H1 to H5 header and some bold and italics here and there, it was easy to get confused which analysis was under what data set (or other hierarchy for the report) as shown below:
H1 and H2 header on the default template. The difference is sometimes too subtle after reading these all day long.

InkCSS for KnitR

While looking for a new template for my personal website more portfolio-wise (still on the making, current is the old one), I stumbled across a very crisp and clean Manual of one of them: Brushed, by Alessio Atzeni. As you may expect, the manual was found by surprise within the zip folder. Here’s how it looks like:

The manual of a free website template found by luck after attempting to use the template on my local machine.

If you noted the first image of this post, you may have guessed right: This looks like a perfect template for knitR reports!

Although motivated to use it right away, that introduced a new problem: I am a data analyst, not a front-end developer, and this falls off my knowledge domain. Furthermore, most documentation and questions found surrounding the usage of custom.css for knitR (at least in a way it would be easy to reuse with RStudio) were little to non-existent.

Changing the default template requires only the top section of the report to add the line ‘css: ~/ink.css’. Other available solutions required additional pieces of R code.

Just have a quick look on RPubs:

RPubs main page. Since all reports uploaded to RPubs are public, it’s main page provide a continuous feed of the most recent uploaded reports.

And you will see nothing but the same, old and default template.

After by accident realizing the location of where the index.html file that uses the CSS in RStudio is located while generating a report and a lot of accidental tweaks with the manual page InkCSS was born:

InkCSS on it’s full glory. Notice this is the same project used to illustrate the problems on the start of “knitR to the rescue” section!
InkCSS menu will remain still to the left side regardless of the section you are, providing quickly navigation and a reminder of the big picture. This menu is an extension of floating-css.

You can open the same project now using InkCSS clicling here. In summary, InkCSS addresses the previous issues with the following features:

  • Implements floating-css to provide a permanent side-bar addressing the big picture and navigation problems. It also provides a lot of room on the left menu TOC for deep nested long-reports in preparation for self usage or group discussion.
  • Code snippets using zenburn code highlight blend with the menu colors, providing an even stronger distinction between results and code, while being aesthetically pleasing.
  • Since the left menu is large, there may be large empty spaced click areas between the analysis and a small heading (e.g. CODING below). In this case, hovering the cursor on the empty space will provide appropriate highlight to identify which header will be skipped upon clicking the empty region.
  • Header colors: Colors with varying opacity provides an additional visual clue among the top headers.
  • And last but not least, a centralized title for the report☺.


I hope this post inspire you to come up with other templates for yourself, and to draw inspiration from and rethink the way reports are done, even within the knitR community. I also invite you to rethink how people react to your reports, and try to improve your everyday template in curious new ways.

I am still thinking how to improve InkCSS, please leave a comment if you have ideas! I am planning on making the code open-source under CC once I can clean the .css file properly.

p.s.: Did I mention how much it’s design call attention on RPubs?