The first time I tried to create this design was over a decade ago, back when we had Web 2.0, when we were all struggling with semantic markup and strict XHTML and the web held so much promise. I wasn’t happy with the results then. Three important things had to happen for this design to work:
So now I can finally share a version of Diplograph that I’ve been thinking about since the time when blogs still mattered.
The main serif typeface, used in the site’s masthead, header elements, and body text, is EB Garamond. Garamond has long been one of my favorite fonts, and I was really happy to find this version! It’s elegant, beautiful, and thoughtful.
In The Elements of Typographic Style,You would be forgiven if you looked at this site and thought, “she read Typographic Style ten years ago and never moved on from that.” You would be forgiven because you would be right. Robert Bringhurst writes:
Choose a typeface or a group of faces that will honor and elucidate the character of the text.
This is the beginning, middle and end of the practice of typography: choose and use the type with sensitivity and intelligence.
What is the character of my text? I have no idea. The content of this site is as much Animal Crossing screenshots as it is anxiety. So maybe EB Garamond is aspirational: it’s the stories I want to share, the art I want to make.
The accent typeface, used for navigation links in the header and footer, is Poppins. I wanted something absolutely as a contrast, something like Futura or Avant Garde, to pull the blog away from looking like a 16th century manuscript. Poppins is that geometric sans serif.
Technical prose uses Source Sans Pro. EB Garamond is great for reading, unless the words are made up or have weird capitalization rules like HTMLElement and printf and performant, so I went looking for a straight-forward sans-serif instead. I think it looks okay with
inline code too.
Look, real talk for a second? I chose Source Sans Pro because I got really annoyed at a different face’s curly apostrophe, and so I went searching for something where I didn’t hate how “For our caller’s convenience” looked. That’s it. That’s how I chose the typeface.
cat << EOF Code is set in FiraCode, which is also what I use in my editor most of the time. It has a lot of really neat / weird ligatures and contextual alternatives, such as === for triple equals. I write a lot of TypeScript, and these hints are really nice once you get used to them. EOF
There’s enough really cool stuff going on with the code formatting that it needs its own page. I want to write that one soon.
The full fonts would be too large to send to every visitor. The EB Garamond Regular alone would be nearly 200KB.
For example, for EB Garamond Regular, I’ve kept these codepoints:
And these layout features:
kernfor inter-character kerning
ligafor common ligatures
dligfor discretionary ligatures
loclfor localized variants
smcpfor small caps
swshfor the ridiculous and amazing swash on Q
onumfor old-style figures
I also drop the
s_t ligature glyphs.
After subsetting and compression, the font is a much more reasonable 55KB.
@font-face font-family: "EBGaramond" src: url("/fonts/EBGaramond-Regular.woff2") format("woff2"), url("/fonts/EBGaramond-Regular.woff") format("woff") unicode-range: U+0000-00FF,U+2000-206F,U+FB00-FB04,U+2103,U+2105,U+2109,U+2116,U+2120,U+2122
The usual set of ligatures, such as ff or ffl are enabled. Compare affably baffled vs affably baffled.
I’ve also enabled discretionary ligatures, for example Th, tt, ss, or fj. Compare: Throttled fjord Crossing vs Throttled fjord Crossing.
I’ve removed a few specific glyphs, such as the ct or st ligatures. They’re beautiful but distracting in modern prose, I think. My current process is at best a hack. It works like this:
LigatureSetthat no longer has any ligatures, or the modified
These steps probably only work for the specific glyphs I’m dropping in the fonts I’m dropping them from. But now I get to turn on more ligatures without them being distracting, and that’s cool.
html font-variant-ligatures: discretionary-ligatures
I use old-style proportional figures in prose, as in 5,678. Tables use tabular figures so numbers will line up with each other:
html font-variant-numeric: oldstyle-nums table font-variant-numeric: tabular-nums
InkInk is what I call the software that generates this site. automatically turns any "straight quotation marks" into their “curly equivalents,” using an algorithm based on David Dunham’s Smart Quotes algorithm.
It skips over text it doesn’t think is prose (e.g.,
<code>). It will traverse sibling nodes, so it will correctly curl the marks around “emphasized text”.
“Opening punctuation hangs into the left margin in supported browsers, so the text remains aligned in each paragraph.” (Your browser may or may not support this.)
html hanging-punctuation: first
Emphasized text and citations are italicized. Strong text is set in small caps instead of bold, which looks weirdly out of place to me.
Superscript uses the
sups font feature. I don’t really use subscript that often, so I’ve removed those glyphs from the font for now.
em font-style: italic strong font-variant-caps: all-small-caps letter-spacing: 0.03em sup font-variant-position: super cite font-style: italic
I’ve only styled three levels of headers for now, and by this point you’ve seen all of them.
<h1> is used for the page title. The first two levels of headers are outdented into the left margin, and the third level is indented, all of which is to break up the left edge of the body text and make scanning for sections a little easier.
All of the headers are also anchor links that point to themselves, so you can copy the URL of a header to share a link directly to that section. When someone visits one of these links, the header is highlighted. (You can click a header to see the effect.)
EB Garamond has the wonderfully whimsical capital Q as a swash alternative, but it’s a bit too much in body text, so it’s enabled only on headers. Compare Quickly Quoth vs Quickly Quoth.
@mixin main_column margin: $line_height auto max-width: $body_width padding: 0 $right_body_padding 0 $left_body_padding @mixin main_column_outdent max-width: $body_width + $left_body_padding - 10px padding-left: 10px hanging-punctuation: none h1, h2, h3 @include main_column font-feature-settings: "swsh" a color: inherit h1, h2 @include main_column_outdent h2, h3 &:first-child margin-top: 0 h1 font-size: 42px line-height: $line_height * 2 margin-top: $line_height * 3 h2 font-size: 28px margin-top: $line_height * 3 h3 letter-spacing: 0.3em padding-left: $left_body_padding + $line_height * 3
@counter-styleto implement lists one day, but at the moment it’s not widely supported.
@mixin list_marker display: block position: absolute text-align: right margin-left: -$line_height - 10px width: $line_height #page ol counter-reset: contentol li:before counter-increment: contentol content: counter(contentol) @include list_marker ul li:before @include list_marker content: "•"
Block quotes are marked with a vertical line and use a subdued color. The text is indented to offset it from the main text.
That was probably written by someone very cool.
blockquote color: var(--secondary-color) border-left: 2px solid var(--layout-color) padding-left: $line_height - 2px
Ink supports sidenotes.They look like this. At larger layout sizes, on laptops or desktops, the sidenotes appear in the right margin. On smaller screens, the superscript is tappable and shows the sidenote as an inline parenthetical in a subdued color.
A sidenote’s structure and styling look like this:
<span class="sidenote"> <label for="9d6a952f-c07c-4416-b594-b6d05f936710"></label> <input type="checkbox" id="9d6a952f-c07c-4416-b594-b6d05f936710"> <span class="sidenote_contents">Sidenote contents go here.</span> </span>
span.sidenote counter-increment: sidenote_counter label:before content: counter(sidenote_counter) line-height: 0 font-variant-position: super input[type="checkbox"] display: none @media (min-width: $column_breakpoint) .sidenote_contents @include right_column font-size: $aside_font_size .sidenote_contents:before @include list_marker content: counter(sidenote_counter) font-variant-numeric: tabular-nums text-align: right @media (max-width: $column_breakpoint - 1) label:before color: var(--link-color) .sidenote_contents display: none color: var(--secondary-color) .sidenote_contents:before content: " (" .sidenote_contents:after content: ") " input:checked + .sidenote_contents display: inline
Words and acronyms formed entirely of UPPERCASE LETTERS stick out from their surrounding text like shouting, and so Ink instead sets them in SMALL CAPS. A mix of numbers, letters, and some punctuation is also allowed: JPEG, 3DES, C-3PO, A-Z, A/B, 3 PM.
Capitals that are a part of another word are not included: macOS. Some initialisms are skipped over when part of specific phrases: EB by itself is set in small caps, but not in EB Garamond.
Some technical acronyms are set in small caps, with an initial full capital, when they are part of a mixed case name: MozJPEG, OptiPNG.
To be honest, I haven’t really found an exact set of rules I’m happy with, so Ink has a lot of exceptions to make this work.
A small amount of tracking has been added to any sequence of small caps, including acronyms, strong text, and headers. Compare: JPEG vs JPEG.
strong, h3, .small_caps font-variant-caps: all-small-caps letter-spacing: 0.03em