How CSS selector specificity is calculated

I spent the end of this week working on Readership’s exporting tools, more specifically the CSS inliner.

To make sure that the correct styles are applied when multiple selectors with a common property match the same element, I needed to calculate the specificity of each individual selector, keeping only the declaration of the one with the highest specificity.

Read on, there’s more »

The building blocks of a healthy community

Over the course of my time on the internet I have been a part of many different communities, from the household names to the highly niche.

If one thing can be learnt from them it’s that building a community is hard; building a welcoming, helpful, ludicrously smart community is nigh-on impossible.

Building one such community is something Mozilla has managed to do with Rust however. My first month using the language and interacting with it’s community has set a new gold-standard in my eyes for what a healthy community looks like.

Read on, there’s more »

Sleepless nights

As I write this, it’s been about 37 hours since I last slept.

For almost as long as I can remember I’ve had trouble getting to sleep; staying asleep has never been an issue though.

Every couple of months or so, there will be a night that’s worse than usual. For the love of all that is holy, I will not be able sleep. I can typically trace the restlessness: I’m excited about progress made on a project; I’m looking forward to digging my teeth into a new project the following day; I’ve hit a problem I haven’t found a good solution for; my mind’s revisiting the past; or, as is currently the case, my brain in making the most of the quiet dark room to unearth those little what-ifs? and poke them with a stick.

Read on, there’s more »

Dead Men Tell No Tales

Things have been quiet around here this past week. That’s mainly due to my focus being on completing Readership’s current milestone before my folks come out to visit at the end of the week. I’ve been toying with a new side project as well though—my first real one in a long while. The idea is pretty simple: answer the question “just how fast can a large site be statically generated?”.

Read on, there’s more »

My Hackintosh 6 months in: specs, thoughts and useful links

In the summer of last year, I was in the process of leaving my job to go full-time as an indie. I arranged to keep the mid-2012 MacBook Pro that had served me so faithfully at my old job as a backup machine, but it was starting to show it’s age when running Photoshop or Illustrator. I set about looking for my next workhorse.

Read on, there’s more »

Tracking commits to a GitHub repo with RSS

Watching a repo on GitHub will keep you up to date with it’s issues and pull requests. From time to time there are repos that need a closer eye kept on them though.

I inspected the page of one such repo this afternoon and to my slight surprise found what I was after: an RSS feed. Props to GitHub for going one step further by providing per-branch commit feeds, structured like this:

A working example:

New about page

I finally took some time this weekend to sit down and write an about page for this site. As part of my continued push for this site to tell a complete story—to document both the personal and professional ups and downs, I forced myself to break out of the boilerplate 3 line about page I’ve some to expect on personal websites:

Hello, my name’s NAME. I work at COMPANY in CITY as a JOB TITLE. Formerly at OLDCOMAPNY and OLDCOMPANY2. Feel free to get in touch.

Read on, there’s more »

Dynamic input values, .value and .getAttribute(‘value’)

There are two ways to go about getting the value of an input with Javascript: .value and .getAttribute('value'). It’s important to know that they weren’t born equal however. It’s easy to be caught out by the fact that whilst .value updates dynamically to match the user’s changes, .getAttribute('value') does not.

Read on, there’s more »

Improving webfont performance with FontFaceObserver and sessionStorage

I spent some time trying to optimise webfont loading on this site yesterday. The current best-practice for most websites leverages FontFaceObserver and sessionStorage.

FontFaceObserver is a fairly small Javascript library made by Bram Stein that will load one or multiple @font-faces, then notify you once they have finished loading via a Promise. sessionStorage is like localStorage except that, as it’s name suggests, it expires at the end of the session. We’ll be using it to keep track of whether or not the fonts have been loaded.

Let’s start by adding the necessary @font-face syntax to our CSS. This site uses Domine, which I self-host. FontFaceObserver is compatible with any webfont service though.

Read on, there’s more »

On importing my old writing

I’ve been going back and forth with myself on this for what feels like an age. When I came back to having everything associated with this domain, including my writing, I started afresh.

The question I’ve been going back and forth on is whether or not I should import my old writing. Having started afresh, I feel like the site no longer tells the full story. Whether we like it or not we are a culmination of the events of our past, and whilst there are posts I’ve written in the past that I regret publishing and/or no longer agree with, redacting or deleting them isn’t going to change the fact that once upon a time I put them out into the world with my name next to them. Doing that feels like I’m being deceitful—first and foremostly to myself.

All that to say that I have now imported all the old posts from and all the posts I could find from the first version of as they were originally published.

Screencast #1: How I manage my dotfiles with GitHub

There are plenty of different ways to manage dotfiles. This screencast shows you how I sync mine across machines via GitHub.

I like this solution because it doesn’t rely on any tools other than Git which is more or less platform-ubiquitous. There’s no need to install other scripts or software and if you’re not a fan of GitHub then you can just as easily use Bitbucket or any other host.

Hacker News commenter StreakyCobra is the brains behind this setup and, as I mentioned in the video, it’s a setup that has served me flawlessly so far.

Configuration for a cleaner command history in ZSH

Being able to scroll back through all of the commands entered into the terminal with the up arrow key is very handy. A level of annoyance is added when having to scroll back through all the occurrences of a command that was repeated multiple times in succession however.

Fortunately, there’s an option you can set in your .zshrc to reduce a block of repeated commands down to just one line in the command history.

setopt hist_ignore_dups # Don't save multiple instances of a command when run in succession

You can go further with the setopt hist_ignore_all_dups option. With that set, all previously saved commands that match the command you just entered will be removed from the history. I personally don’t like this though, as when I’m going back through my history I like having the complete context around any previously entered command.

Lastly, in the name of a cleaner command history, you can set setopt hist_reduce_blanks which will just remove any superfluous whitespace from the command before saving it to the history.

Conditionals and regular expressions in Javascript

Regular expressions (regexes) are, at first, baffling to look at. What they lack in initial digestibility however, they make up for in power.

Before going any further with this post, let’s take a quick look at the structure of a regular expression in case you haven’t used one before.

Read on, there’s more »

Section comments with centred text in Vim

Everyone has their own taste when it comes to comment styles. I personally like section comments with centred text as shown below. They’re time consuming to get right though so I tend to opt for a simpler format.

/* -------------------------------------------------------------------------- *
 *                                 COMPONENTS                                 *
 * -------------------------------------------------------------------------- */

Some light procrastination led me to investigating how much of the above layout could be automated in Vim. As it turns out, all of it. Here’s what the final workflow looks like in action.

The mapping isn’t particularly pleasant to read, but it works.

nnoremap <leader>sh VU:center 79<cr>0c2l<space>*<space><esc>A<space><esc>40A<space><esc>d79<bar>ch<space>*<esc>YPS<esc>i/*<space><esc>74A-<esc>A<space>*<esc>jo<esc>S<esc>i<space>*<space><esc>74A-<esc>A<space>*/<esc>o<esc>o<bs>

As a reminder, you can change the mapped commands based on the filetype of the file being edited. That way, <leader>sh can always be “section header” but the comment syntax can be changed for languages that don’t use /* */.

autocmd BufRead,BufNewFile *.{es6,js,scss,css} nnoremap <leader>sh VU:center 79<cr>…

jQuery to pure JS: Target each direct child of an element

If you’re coming from jQuery to pure Javascript and are trying to target each direct child of an element, your first attempt to select the direct children will probably be element.querySelector('> *'). That will throw an error though, because .querySelector() doesn’t support tag-name wildcards.

Your next attempt might involve element.childNodes, and you’d be closer. The issue with that is that .childNodes will return all of the element’s children, not just the direct children.

Read on, there’s more »

Jekyll: Create a list of all posts in the same category

Let’s take a look at how to create a list of all of the posts in the same category as the one currently being viewed, bearing in mind three requirements:

  1. If the post has more than one category, we want to create a list for each category.
  2. We don’t want to show the list if there is only one post in the category (the one being viewed).
  3. We don’t want to include the post who’s page is currently being viewed within the list.

Read on, there’s more »