Porting to Gatsby

Last month, Tumblr announced that they'd no longer be allowing "Adult Content" on their platform. I found this distressing, not because I depend on Tumblr for pornography, but because it was clear that a hamfisted approach to automating the deletion of adult content would not go good.

I downloaded my blog content using a script I found, and started looking around for the best thing to port my blog to. I definitely wanted something that would let me write markdown and export static content. Blosxom looked promising, but it seemed pretty old, and I have no interest in learning Perl at this time.

Gatsby stood out as a serious contender. All the cool kids use React and Graphql these days, and it would let me both learn the new shape of web development, and leverage my JavaScript and Node.js skills.

My initial impressions so far:

  • React: basically an ideal component/data model, though the data handling was a bit of a confusing learning curve. (Gatsby and Graphql make this both better and worse in different ways.) JSX is an itchy sweater that I resent wearing. It's not hard to use, in fact, it's pretty easy, but the ceremony feels excessive, and switching between {xyz} in JSX and ${xyz} in template strings is annoying.

  • Gatsby: pretty effin rad. I like it a lot. Blends really nice dev-time hotswap experience with a powerful component model and an optimized static SSR build for production.

    The docs are well written, and it has them, but there are not nearly enough. As a result, they sometimes jump way too fast from "this is how you type codes into an editor" to "and then you use React components to..." The tutorials were frustrating at first because of being so novice, and then frustrating because they took a lot of know-how for granted.

    Gatsby feels like it's still a bit of a power tool for power users. When there's a paved path or a starter, and that path is marked, it's easy, but I found I ended up hacking through jungle a bunch of times. (Maybe that's what I was looking for? I did enjoy the experience!) There are a lot of paved paths, but they don't go everywhere, and they aren't all marked.

    That being said, it's extremely powerful, well thought-out, and fun to use. I believe this platform will mature very nicely as more docs and tutorials are added to fill in the blanks.

  • Graphql: confusing learning curve, still don't quite grok how it's doing stuff, but once the basics clicked, it's way easier to use than SQL, and I already get queries right on the first try more often than not. I can see why everyone's excited about it.

  • Cloudflare: happy with it as expected, but for one bump. You can't use them as a TLS terminator in front of a plaintext HTTP backend, which I guess sorta makes sense, but wasn't clear in their interface or docs.

The importer was fun to write, and pretty straightforward.

The media plugin goober thingie was originally only going to be used for photosets, but I ended up using it for all media types, so it's increasingly misnamed. I plan to publish it as a standalone plugin, though I'm not sure how many people would make use of it. I did actually try to make photosets work with flex-box and display:table, but in practice, nothing is as stable or reliable as actual <table> elements. I always got weird extra whitespace when turning divs into display:table elements.

I made them reactive by just making all the elements display:block. It's much more reliable to turn a td into a div than the other way around, apparently.

The template and CSS I built from scratch using my existing tumblr blog as a visual design. I went down a weird rabbit hole for a while because I didn't realize you were supposed to just import './foo.css' in a component in order to pull in the CSS. I was using Helmet to stuff a <style> tag in the header, and always getting a flash of unstyled content.

Overall, I'm happy with the result, and really glad that things like Gatsby exist :)

Foo Hack 4.0

Partly because I haven’t been writing much CSS these days, and partly because it’s been just over a year since the last redesign, I felt like this site needed a face lift.


I’ve been getting more and more excited about the impending freedom of the @font-face CSS declaration. The prospect using any true-type or open-type font in a web page without resorting to flash or images is incredible. If you’re viewing this site in Safari 4 or the latest beta releases of Firefox, Opera, and MSIE, you’ll have a much improved experience.

The body text is set in Bodoni SvtyTwo OS, chosen for its beautiful italics (not an oblique, but a true italic), dramatic hinting, and straightforward lines. I chose the OS over the regular Bodoni SvtyTwo because of the more stylish “lower case” numerals: 1234567890.

Update: I decided to go with Hoefler Text instead of Bodoni. Bodoni looks nice, but without the stronger hinting, it was hard to read on some monitors, especially for folks who are crazy enough to browse the web on Windows. Hoefler Text has a lot of what I liked about Bodoni, and was a strong contender, but it’s not free-as-in-speech. However, it is free-as-in-MP3, so I’ll use it until Hoefler & Frere-Jones send me a C&D. I also widened the column a bit to accommodate the wider typeface.

The headings are set in Qlassik Medium, by Dimitri Castrigue. It has just enough fun to make it stand out, but not so much as to be ridiculous.

Code snippets are set in the famous Bitstream Vera Sans Mono. I’d initially planned to set all things monotype in my favorite coding font, Century Schoolbook Mono. Once you get used to coding with serifs, nothing else feels right. Unfortunately, it doesn’t include bold and italic versions. While the OS will “fake” bold and italics with fonts that it has installed, it won’t play ball when asked to manipulate dynamic fonts linked from a CSS file. I put CentSchBook Mono first, so if you have it (which you should!), it’ll work. Otherwise, you’ll get Bitstream.

If you don’t have a browser that understands dynamic fonts, you can grab them from http://foohack.com/tpl/fonts/.


I really wanted to stretch my CSS abilities a bit, and also apply some of the principles of typographic design that I’d been learning about lately. The single-column is about 66 characters wide in the target font, and feels about “right” for readability.

Despite my best intentions, a lot of feature creep had somehow taken over, prompting the last revamp. In this version, I put back some features that I’d removed, and removed some things I’d left in.

The vertical measure is set at 30px, with a font-size of 20px. While that’s a bit large, I’ve always favored erring on the side of “too big”, and the Bodoni just felt too cramped at 16/24.

I’ve also taken a lesson from the print world, and set all my bullets and other adornments off into the margins, such that the text is kept strictly flush left. The only element that I couldn’t figure out how to do this with is the <q> element when it starts a paragraph. In that case, it should have a text-indent somewhere around -0.5ex, but I couldn’t manage to do that without borking quotes that start somewhere in the middle of the paragraph.

Since all the major browsers support resizing fonts that are set in pixels, and “zooming” is now preferred over simple font resizing, I went ahead and set everything in pixels so that the math would be easier. There’s really no benefit to so-called “fluid” layouts that are set in ex or em measurements. Plus, browsers that support dynamic fonts seem to have a really hard time with ex/em measurements, since the layout is rendered before the font has downloaded. I do hope that gets fixed at some point, but doing layout in pixels was a welcome return to basics.

Supported Browsers

The luxury of a personal site: I didn’t test even once in MSIE, and I don’t plan to.

Also, since a lot of the style is in the typography, anyone with a browser older than 6 months isn’t going to see my beautiful styles. But they’ll see their own default font settings, I suppose, and that’s probably fine.

What do you think?

Foo Hack Redesign 3.0

So, it started out as just a few font changes. I’d been growing less and less pleased with Trebuchet MS, and had found a few cases where it broke the militant line-height rules I’d set for this site. In general, I felt that it was too crowded, and the gray hash textured background was (in my opinion) a contrived and artless approach.

I’m not a very understanding end-user when it comes to this site. The Foo Hack design team got fed up with my complaints, and decided to give in and make some changes.

Feature creep is a bitch when you have a deadline. For personal projects, there is no deadline, and so a bit of feature creep is fun, within reason. That’s a big part of the reason why I have so many back-burner projects that are almost finished; just as I near the finish line, I decide that it needs a little more, or another project gets more interesting for a while. So, on to what changed.


I was a computer geek first, but when my dad replaced our DOS home computer with a Windows 3.1 box, I fell in love with fonts. I can waste an afternoon surfing the web downloading fonts that I’ll probably rarely (if ever) use. Web design is about 90% typography, and it is an art that blends strict perfectionism and fluid acceptance in a beautiful way.

For the main body text, I wanted something subtle and easy on the eyes. Something that would let the writing speak in the voice that I intend, without getting in the way. For the “small” items of diminished importance (asides and things in <small> tags) I wanted a serif font with a very thin ex measurement, so that the text could “feel” smaller without altering the line-height. For the headings, I wanted a rounder, more open font that could evoke a sense of boldness without being too heavy. Subheadings and meta items (the date, “comment” link, etc.) should use the same font, but with less letter space and a subtler color.

For the body text, I decided to go with Helvetica, the classier old-world cousin of Arial. I was initially pleased with the results.

Cliché though it may be, Times New Roman was the perfect choice for the diminished items. It’s very light, yet still fairly readable, and when italicized, it practically disappears. I was already using it for that reason, but since I don’t love TNR all that much, I was willing to entertain other possibilities.

If Helvetica is so great, why do I see Arial?

A problem came up when I noticed that the line-height was getting messed up whenever a TNR inline element would wrap to the next line. I figured out the problem.

Let’s say you have font A and font B. You create a block-level element using font A. Then, you have an inline element using font B, which wraps to the next line.

If A and B don’t put their letters on exactly the same point in the line-block, then the line-height will adjust up or down, as the next line is set by the position of the letters in B instead of the position of letters in A. Since the B element isn’t a block-level element, it won’t create a whole new block, and will have the effect of adding or removing a few pixels from the overall height of the A element.

To correct this problem, and still have 2 fonts sharing the same block-level element, you need to find two fonts that have exactly the same vertical letter placement on the line block.

I’m not exaggerating when I say that I created a test page and exhaustively tested every combination of serif and sans-serif fonts on my Mac. It took about a week. There was only one combination that worked.

Arial and Times New Roman.

Ah, compromise, my old nemesis. You strike again. Not willing to give up the line-height strictness, I gave in and decided to use Arial instead of Helvetica. On the bright side, Windows users were mostly going to see Arial anyway, and they’re both tried and true web-safe fonts. And, at typical screen resolutions, it’s hard to tell the difference anyway. But still, it’s a bit of a sore point.

Gotham, Large and Small

Gotham, the masterpiece homage to urban signage by Hoefler & Frere-Jones, is quite possibly the best font ever devised. It’s open and confident even when it’s not bold, balanced and practical. I went with this as the headings, and it also was the best candidate for the smaller informational bits. (After all, it seemed fitting to put navigational links in a font designed for signage.

The downside of such a perfect font is that it’s not free. It would be fantastic if Apple or Microsoft were to license Gotham for their respective operating systems, but I don’t see that happening any time soon. Those that don’t want to install Gotham will see Century Gothic (if it’s installed, most likely because they got it bundled with Microsoft Office), or something in the Lucida family.

Accentuate the Important, Diminish the Rest

I brought down the contrast a bit, and did away with the background graphic. Some color was sprinkled around to help create a meaningful mental model of each page. I got the idea for the categories above the titles from Rands in Repose, one of my favorite regular reads.

The default set of post meta info that Wordpress provides is far more than necessary. I got rid of everything that didn’t directly benefit the goals of conversing with the world through this blog.


It seems awkward that my comments should have a blue left border, and reader comments are unadorned. Simply using random colors wouldn’t do. So, I wrote a function that will hash a string into a color value. A simpler hash would have sufficed, but I wanted more control over the range of colors that it selects, and rand() was a good fit. So, your comment will always have the same color (unless you use a different email address, of course) and all the colors will be in a particular mid-range of luminosity that is bold, but not overpowering.

I’ve already run into a few situations on this blog where I felt that threaded comments would have been helpful. However, the threaded forum-style comments would be complex and counterproductive. I grabbed a standard threaded-comment plugin, and tweaked it to replace the interface with a few hyperlinks. Since conversations are more naturally many-to-many, I’d like to implement something along the lines of what Dunstan Orchard used to have on his blog, but doing that the right way means a bit more investment, and this project was dangerously close to being back-burnered forever.

Marching to a Vertical Cadence

Regular readers will notice that this blog got a bit of a face-lift today. The obvious change is the addition of a background texture, but actually the biggest change is that I updated all of the elements to fit into a vertical em grid. Actually, I’m not all that thrilled with the background image, but it was killing me having such a bland vanilla design, so I whipped up something as fast as possible. (For comparison, here’s the old version.)

If you turn on the lines, you can see how each line of text, every heading and block, is now lined up so that it will “resonate” with a consistent vertical spacing. I’m certainly not the first one to do something like this. However, in the process of figuring out how this could be done, I came up with a few shortcuts to make the math easier. You’ll probably need to have a calculator handy, and building a decent grid tile graphic is key.

First step: Build the grid image

To make the process somewhat sane, come up with a font-size that’s pretty reasonable, and build a background baseline graphic to hold you to that size. Since I favor readability over teensy designery text, I chose 16px, and built this image. It’s 32px tall, with a horizontal line every 8px. (The color choices are purely for nostalgic reasons. I can practically smell the #2 pencil in my hand.)

Going forward, every block element must begin just below a line, and end exactly on a line. If it’s hanging over, there’s a problem. (Adding and removing background colors is a good technique to check things.)

Set the font size to 16px in the HTML element, and add the background image:

html {   background:#fafafa url(line.png) top repeat;   font-size:16px; }

Once everything works, you can pull out the line and the fixed px font-size, and let it resize to whatever the user has set in their browser. Since everything will be based on ems, it will all scale up and down to any size. If you sniff the CSS on this page, you’ll see that I apply this rule whenever the “show-lines” class is on the HTML element.

The Rules

  1. Never set font-size without setting line-height (or vice versa.)
  2. For simplicity, vertical padding and margin should be avoided when they’re not needed, or at the very least not set on an element that has an altered font-size, and must be specified in ems.
  3. Top and bottom borders get hairy. Use outline instead, and let it be a little broken for IE.
  4. The horizontal direction is fair game, outside the scope of this article. Use px or ex or whatever units you want.
  5. The big one: font-size * (line-height + vertical padding + vertical margin) must be a whole number. If you’re going to use a double-spacing cadence, then it should ideally also be an even number most of the time.
  6. Go to 5 decimal places when you get numbers that repeat. Browsers only look at the first 4, but most of them will round rather than truncate, so the additional number is worth having.

So, for example, on the body text, I wanted to have simple double-spacing. So, this rule was fine:

p {   font-size: 1em;   line-height:2; }

On some elements, I wanted to drop down the font size a bit, say to 70% of normal body text (or 0.7em.) If the element had a line-height of 1, and its font-size is 0.7em, then that’s a problem, because 0.7 * ( 1 ) = 0.7, which is not a whole number. If we want to make this element take up 1 row on the baseline grid, then we can say that 0.7 * ( x ) = 1, and solve for x, the line-height. In this case, 1/0.7 = 1.428571, so we set the line-height to that value, and end up with small text that takes up 1 line on the grid.

The same technique can be done if you wanted to go even smaller. The table below has values for various font sizes and double- and single-spacing:

Font-size (in ems)Line-height (single)Line-height (double)

As you might expect, some of these work better than others. The funkier looking a decimal is, the greater the chance that it will be improperly rounded.

Effects on Layout

As you can see in the table above, without the ability to put pixel borders on the tops and bottoms of things, it presents interesting challenges in some cases. A gradient image can be a little nicer than borders for table cells, and is certainly a lot nicer than not having any kind of vertical breaks.

Form elements are particularly tricky. I didn’t want to have them borderless, since borderless forms are just visually weird to me. However, a border on the top and bottom messes with the spacing. So, I’ve used outline, and just passed a border rule to IE 6 via the underscore hack. It’s not a great solution, but it works for now, since outline is drawn outside the element, instead of pushing it further down the page. When I come up with a more clever way to do this, I’ll share it.

Input elements seemed to need just a shade less padding than the math would indicate. They seemed to work properly using 0.41em instead of the 0.421758em that my formula would have predicted. Not sure why that is, but I’m OK with the hack.

Margins and Padding

If you ever have to move something up or down, I find it’s useful to figure out how many ems it needs to move, and then convert by the font size. To keep things easy, you can restrict any font-size changes to inner elements, and apply padding and margin on the container (which always has a font-size of 1em.) However, some adjustments are just easier to make on an element that has a font size, so the conversion comes in handy.

For example, let’s say that we have an element with a font size of 0.6em, and we want to move it down 1.5ems. (In the baseline graphic, that would be moving it down 1.5 “red lines”.) So, the ratio looks like this:

1.5 * 1 = x * 0.6 1.5 / 0.6 = x = 2.5

so we have to give the element a padding or margin of 2.5em. The simplified formula is:

distance / font-size = correct em measurement

I find that, as I have this style live and notice little errors that need correcting, I’m using that formula quite a bit.


Some browsers do this better than others, of course. Gecko browsers (Firefox, Camino, etc.) are impeccable with their em-spacing and line-height calculations. Safari seems to always be a bit off of the lines in the background image, as does MSIE. Opera is better than those two, but not quite as good as the Geckos. Even when it’s not perfect, though, getting close does seem to feel more “right” to me.