There’s this annoying tension between personal and public that comes with personal websites. Are they a home or a gallery? a personal record or a public document?
On the one hand, it feels like it would be fun to have a massive index of everything you’ve done, thought, or written about, all in one place. On the other, this makes it harder for people to find the bits that might be worth reading.
Equally tempting is the idea of perfectly designed templates for each section of your site. I have accepted that I will never do it as well as Aaron, and it’s allowed me to be at peace with tasteful minimalism instead.
Despite the rumors, I do indeed have a few.
This site is fast. Ridiculously fast, even for a static site.
It uses one web font, and only on non-Apple devices. There is just one 800-line stylesheet. There is no JS-based rendering. This page weighs less than 15kb. Images are compressed to within an inch of legibility, and Netlify’s CDN ensures a low time-to-first-byte. I also have an instant.page script running to make cross-page navigation even faster.
Everything is a static asset, everything is cached locally. Yes, even the HTML, it just has a refresh period of one hour. The result is a website that crushes all the important speed metrics, and is a comfortable member of the 250KB club.
* Except sidenotes, because there isn’t a native tag for that yet.
If you aren’t already, you should seriously consider using a static site, built on a foundation of Markdown and Git. It frees you from being reliant on a private company to keep your site alive, and you can switch hosting with ease. It lets your site degrade gracefully.
You’re also free to pick how you want to build your site, instead of being limited to one default method (JS Handlebars for Ghost sites, PHP for Wordpress, etc). I use Hugo because it lets me write my templates in plain HTML, and has lots of useful pre-defined functions.
The fewer special styles and element names I have to remember, the better. The stylesheet for the site is three times smaller than the last version of this site, and I use a grand total of two special elements, sidenotes and masonry-style blocks. No shortcodes, no MDX, no Tailwind.
The important consequence of this minimalism is that writing a new post is simple as opening up a new markdown file, adding a title to the front-matter, and starting to type.
It’s 2023, and web hosting has never been cheaper. Other than the $10/year that I pay for the domain, it costs me nothing to put this website online. I don’t need to rent a server to host pure static files, and Github provides free storage.
|Github||Hosting and version control|
|Netlify||Deployment and CDN provider|
|Google Domains||Domain provider with the most transparent pricing, and excellent UX.|
The site itself is generated with Hugo, which I like because it’s really fast and provides a bunch of of sensible defaults that frees me from having to fiddle with plugins.
Why purple? Because Frank Chimero said it was hard to make purple work in a design and I couldn’t resist the challenge. Also because I got bored of black and white, so
#2F2182 is what we’re going with.
In style and spirit, this site takes after arcana.computer. One theme color, an index on the homepage, simple styling for common elements, and fairly wide variety of writing.
I love weird personal sites and near-unreadable layouts. I’ve even designed some myself. But for better or worse, this version of my site seems to have unconsciously adopted the brutalism code of practice.
Brutalist Web Design
If you’re a web designer or front-end developer, I will help save you from yourself. To help you put fancy to one side. I am going to offer you a brutalism code of practice:
- Don’t be influenced by tools
- Use a system font and only one
- Write clean code
- Write your own CSS
- Don’t hack the scrollbar
- Don’t create custom cursors
- Don’t use an effect just because you can (especially fade effects)
- Have as little design as possible
- Make navigation obvious or not at all
- Be practical rather than pretty
- Don’t use gradients or shadows
- Use high contrast colours
I might change my mind eventually, but for now this simple set-up suits me well. It means I’m actually writing words on here instead of endless fiddling with stylesheet files. The layout also translates well between mobile and desktop, which is the part I usually find most frustrating.
Why isn't there a dark mode?Because you probably shouldn't be reading in the dark, you should be asleep instead.
My typography notes contain the rules that I use for arranging the text you’re reading right now. I chose box-shadows over borders, and have only one stylesheet across all pages.
On iOS/MacOS, this site uses Avenir, a delightfully crisp font that ships with all Apple devices. On other devices, it downloads a copy of Montserrat. That font, in turn, has been converted to WOFF2 and subsetted down to mere 35KB. Font-smoothing is set to
antialiased on Mac devices.
I’ve attempted to arrange content with the minimum amount of scaffolding. And my rule of sticking to semantic HTML means that I try to as much mileage as possible out of simple elements like headings and blockquotes, instead of complicated
<div> tags and classes. Even elements like the expandable sections are just regular
<details> elements with a little extra styling.
There are still multiple ways to implement sidenotes on the web, Gwern has a whole list, and this JS-free solution is particularly neat, but is limited to inline elements. Great for text, not so nice for images and multiple paragraphs.
I respect the desire to have them exist on all screen sizes; but sidenotes are, by definition, not an essential part of the main content. And so, I’m fine with them being invisible on mobile as long as they can contain anything I want them to.
Table of Contents
Hugo does come with it’s own function for creating a ToC, but it was based on directly turning the contents of header tags into the text in the table. This meant that headers that had link tags within them would render two
<a> tags within them; one to the in-page header, and another to an external page.
So, instead, I use a modified version of this snippet. Like sidenotes, the table is only visible on desktop screens.
The double column sections use
column-count: 2 and provide just the right amount of density to my lists.
There are many fun ways to use
<footer> elements on the web. You could add a changing quote, or a ticking clock. I chose to write short sentences instead of singe-word links.
The first one is responsible for showing you a fullscreen view for images when you click on them. Second is the code from instant.page, which begins loading a page in the background whenever you hover over a link to it.
More about instant.page
It uses connection.effectiveType to check what internet speed the user's device is running at, and avoids fetching anything if it's on data saving mode, or on a 2G network. It also has a configuration for mobile that loads links as they scroll into view, instead of fetching them on hover/click (this is similar to what quicklinks does).
It's one of the many things you can do to get SPA-like performance on a regular site. I use an inlined version of the code to avoid the need for an additional fetch reqeust.
The third bit is a JS-powered search function present on two pages (Stream, and the Search page *duh*)
None of these snippets are essential to the core experience of browsing this site. Even the Search page contains a complete index of all the site’s pages and tags.
I rarely check them, but it’s nice to have some idea of how people use this site. It helps me figure out what pages should make it into the “popular” section, and if an incomplete page is getting enough visits for me to bump it up my to-do list.
Basic stats collected by Umami, an open-source, self-hosted analytics platform. Hosting fits comfortably into the free tiers on Netlify and Supabase.