Notice (2023-08-16): This post is now outdated, as my website no longer uses Jekyll. Nearly all the features described in this post are no longer available on this site. I am leaving this up purely for archival purposes.

During the COVID-19 lockdown in my state, I’ve been revamping this website. I’ve undertaken a rewrite of all the content and overhauled the design from the ground up. I use Jekyll for this site, and I’ve never been 100% satisfied with any of the Jekyll themes I’ve tried; so I’ve been poking around in its innards, taking things apart and building a new theme from scratch.

The new look is heavily inspired by an older version of Niklas Buschmann’s Contrast theme, which I have been using until now with my own modifications. I got tired of searching through the theme files whenever I wanted to make a tiny change, and I had the time and nervous energy to burn, so I rolled my own theme.

There’s no guide on making a Jekyll theme from scratch without using SASS/SCSS. I’m comfortable with vanilla CSS and I don’t particularly have an interest in learning to use CSS preprocessors. So I first hand-coded a basic HTML site with vanilla CSS. I’d just read a piece by Ethan Marcotte about how a website can be a worry stone and remembered how much I’d loved tinkering with layouts on pages I’ve had in the past. I sat down, went through what felt like 60% of the wonderful CSS-Tricks’ back catalog, and banged out a basic page envisioning how I’d like this website to look. It was beautiful, and I wanted to make more.

I worked on incorporating Jekyll into it one step at a time. I created a new Jekyll project with jekyll new. I copied the default theme Minima’s files into my directory from the theme gem. I opened each layout file and include and puzzled out how it all fit together, with a lot of help from Jekyll’s docs. Then I fired up Vim in a new window and worked the Liquid syntax into my plain HTML file.

And here we are now :)

Screenshot of this site's old theme.
My previous blog theme (view image at full size)
Screenshot of this site's new theme.
My new blog theme (view image at full size)

Design considerations, and what I’ve learned

I’ve done my best to make the site accessible and lightweight. Every page was written with love, with the intention of being:

  • accessible:
  • lightweight:
    • Everything is gzipped thanks to the jekyll-gzip plugin.
    • I’ve subsetted the webfont I’ve chosen to use, so the font file your browser needs to render the page weighs only tens of kilobytes instead of hundreds, and even less than that gzipped.
      • Even if, for some reason, your browser can’t fetch the font file, the page will render fine as I’ve used font-display: fallback with a nice system font stack to fall back on.
      • I’ve learned a lot about webfonts in general, and have done my best to make them performant.
    • All assets are hosted at the site itself: no CDNs here, and no Javascript either (except for a couple of pages containing embeds).
  • beautiful:
    • I’ve paid careful attention to typography. I read Butterick’s Prac­ti­cal Ty­pog­ra­phy and implemented a good deal of it. I’ve also implemented some little tricks I’ve picked up from my experience with LaTeX, such as optimal line length.
      • Try printing a page, I’ve included a little Easter egg ;)
    • I considered using a system font stack, but it wasn’t beautiful and the site could look wildly different for every user, so I’ve chosen to use Inter. It’s a variable font, which is fun, because I can choose the font features :)
    • The site respects dark mode preferences! I’m still working on the colour palette, though, so expect it to change in the near future.
    • I’ve beautified the feed too – I’ve written more about my feed customizations in an earlier post.
    • The site is responsive! I’ve learned about CSS grid and units like ch, em, fr, rem, which have been a pleasure to work with.

I’m happy to say that the site scores well on PageSpeed Insights as well as Pingdom’s website speed test.

PageSpeed Insights score of 100/100
PageSpeed Insights score
Pingdom score of 98/100
Pingdom score1

In addition to the above, I’ve also learned a lot about Jekyll, having written the entire theme myself. Liquid filters are awesome and I’ve used them heavily throughout the theme. I went through past posts and cleaned them up a bit. I’ve also rewritten many of the pages.

I’m now offering email updates via Buttondown, as I understand that not everyone shares my preference for RSS/Atom. I really like that it has an API that I can use to send emails programmatically. Sign up to get blog updates delivered to your inbox :)

Feel free to open an issue if you find any bugs or anything I can improve on. I’m considering releasing this theme once it’s a bit more polished. I hope this post has been informative :)

Let’s use the web to create neat new exciting things. Let’s use the web to help people understand each other.
— Tim Berners-Lee


  1. I’d like to get Pingdom to 100/100 as well, but alas, I cannot edit GitLab’s .htaccess file to satisfy its criterion of setting Expires headers.