I Had to Redesign This Site Again

You know I had to do it to 'em

12 minutes

I recently decided to take on the task of redesigning my site. The flashbang of a “black on white text with a little bit of blue” was getting stale, and I found myself once again not writing as often as I would like to because the effort involved in maintaining the underlying framework for the site was becoming a hassle. Granted, I had mentioned in “I Don’t Want To Ever Do This Again”, that I… did not want to do this again. Thankfully, I wasn’t migrating from one site generator to another this time.

I’ll be going over what’s changed in the site’s design, beyond the visual changes, as I’m very pleased with the outcome. Much like the redesign I did in 2018, I had several goals I desired before I was willing to hit publish. Just as last time, here is a checklist of things I wanted, and what I achieved:

Unlike last time, I hit every goal, and improved upon a great many things.

CDNs, Assets, CSS, and Fonts

Let’s get started with the CDN usage. The previous site design would in some cases download a large amount of data from multiple CDNs (about 4 - 8, depending on what was loaded on a given page). This has been changed. I now use only 3 CDNs: jsDelivr, Google Fonts, and the CDN provided by the creator of the Inter font, available via https://rsms.me, which I believe is hosted via CloudFlare. I might reduce this further down to 2 in the future, if I can get Inter to work as I’d like it to. I also reduced several assets to improve memory usage. The biggest is I’ve removed a very ancient version of FontAwesome in favor of a custom font I generated via icomoon. This allowed me to reduce the number of assets downloaded for users, and also allowed me to have more control over how my icons are rendered. I also chose to make the emoji on my site use just one font, because I can’t rely on folks getting the right point across with platform specific emoji (This does in some cases cause some numbers to be rendered with emoji, but those are browser rendering bugs from what I’ve been able to gather)

Right now the most expensive page on my site takes about 10 - 12MB of RAM to render at its peak and this is only during the paint stage. Once painted, the page takes up whatever the hell your browser wants to because we’re adults and we have no control over our own computers anymore because all that matters are metrics to convince shareholders that a web browser is worth having. And what are you going to do not interact with the Information Super Highway turned Super Turnpike?

Sadly, there was one regression, where the Inter font has doubled in size (and downloads two variants, even if only one is ever used) and sadly, an uncached download will cause a page to download about 1MB. I am still working on a few experiments for this, and am hoping to find a solution to cut this down dramatically.

Like last time, all the CSS for this site is written by hand. There are no predetermined frameworks here, and this continues to cause a drastically small generated CSS file from all the SASS files that I’ve written. I’ve removed a great deal of SASS specific syntax, and am actually mostly using modern CSS features, such as var(). I’m eagerly awaiting some Firefox updates and then waiting a year or two before I can get into the real gritty operations that would let me remove SASS altogether. Until then, there might be some weirdly named CSS variables that are overly verbose, but there is little I can do there.

I’ve also continued to use the CSS3 Grid feature for layouts. Only a handful of items on my site still use display: flex;. For everything else, it’s almost always display: grid; for containers. This actually came in handy when I had to write a custom plugin for highlight.js to display line numbers, as the currently existing plugin does not work with ESM. This turned out to be very simple, as I just had to place a series of <span>s, and do some CSS magic with grid layout to get a nice feature. You can see the code I wrote for this below:

export default class {
  'after:highlightElement'({el: element}) {
    const children = element
      .flatMap((element) => {
        const lineNumber = document.createElement("span");
        lineNumber.setAttribute("class", "hljs-line-marker");

        const line = document.createElement("span")
        line.setAttribute("class", "hljs-line");
        line.innerHTML = `${element}\n`;

        return [lineNumber, line];

If you’d like to see exactly how it’s done, feel free to view the source of this site, and look at the CSS for .hljs-line-marker class. The real true magic is the @counter CSS function. Never thought I’d have a use for it, but here we are.

Lastly, one “feature”, my website lacked previously was a responsive design. Except, it actually did support it because I went overboard with CSS Grid. It just made code samples look like shit because it would overflow horizontally almost all the time. But that’s what every site does, so who gives a shit? Surprisingly Chrome and other Chrome based browsers don’t actually work correctly with my site and have a minmax stopping point. They seem to have implemented the grid mechanics correctly. Firefox works, and that’s what matters to me. If you’d like to see the responsiveness of the site, just make this window smaller. It will automatically work until about 450px in width on desktops, and about 250px on mobile. It seems to depend on your browser. Oh well!


Another decision I had for this site was to take on a neobrutalist design. I enjoy the harsh shapes and clashing colors this design trend originally advocated for a great deal. It feels like I’m back on geocities or angelfire or lycos, but the website is still readable, instead of red text on a repeating blue image background that is 100px across. That said, having looked around at the general web, I have seen the corporate memphis style slowly devouring neobrutalism and making it look boring and without personality, as corporate web design is wont to do (Can’t scare away the normies, the shareholders won’t like that). I’ll stick to the harsher side of this design, though I’m sure it will be viewed as outdated in just a few months. Still better than a boring minimalist site that flashbangs you at 7PM on a Thursday ☺

Color selection was difficult. Most palettes that have been done for Neobrutalism are either too washed out, or look like someone dipped the color in au jus and then dried it on a dishrack next to a landfill, then asked Figma to generate the palette from there. I tried several other palettes, including Mozilla’s Protocol palette. But ultimately, I came back to GitHub’s Primer. If the colors you see on this sight look familiar, it’s because they are. You just haven’t seen many of them at such a scaled up view, or used beyond a context of a single button or the border of some visual element.


Which brings me to my next goal: I hate CommonJS. I think it is dumb (why don’t you try require()ing some bitches), and I’ve never liked it. Javascript Modules (also known as ESM) are just a much better experience to work with and make more sense for me personally.

The addition of an importmap script type also means I have full control over how my code is written inline. Sadly, ESBuild and Hugo do not really have a concept of importmap, so I’ve had to do some magic behind the scenes to get my code to work correctly. Such is life. My hope is that this will change in the future, and I can more easily isolate my JS code.

Syntax Highlighting

Despite Hugo having made huge strides in performance and usability since I first adopted it back in 2018, it still relies on the chroma library for syntax highlighting. Chroma itself isn’t too bad, but it suffers from a common problem with syntax highlighters: it is has absolutely horrible syntax highlighting support for CMake. This shouldn’t be too surprising. CMake is in fact very difficult to highlight outside of functions. I selected HighlightJS all those years ago because it had better support than chroma did for CMake. However, I decided to write my own CMake syntax highlighter, so I could improve on what exists out there. This gave me two options: write a highlighter plugin for HighlightJS to replace the publicly available one, or improve the chroma highlighter, get it merged in and then quietly wait until Hugo updated it’s chroma dependency. For time reasons, I opted for the former. The script is about 20kb when not compressed or minified. It also executes fairly well, to the point that it beats out GitHub’s highlighter, and allows me to have more control over what renders. There is however a dirty secret to highlighting CMake: It’s actually a bajillion lexers in a trench coat. For every command that exists in CMake, including user-defined functions, you need a unique lexer. Sometimes, you can reuse the lexer options, but you need a unique instance for each command.

As a result, my plugin looks a great deal like this:

new Command("FetchContent_Declare", "title.function",
  new Symbols(

Just imagine this but for about 2000 lines. There are so, so, so many regular expressions used. 😢

If you think this is unreasonable, then don’t look at the official vim and emacs files that are stored inside the CMake repository. Ignorance is bliss, after all. 😌

I will, at some point, have to do this again but this time for chroma. I’m not looking forward to this as I’ve managed to obliterate most uses of <div> on this site, and last I checked chroma generates a lot of <div>s. HighlightJS does take up most of the memory during painting, and is also a fairly large dependency for me to have just to make CMake look nice. Which it should because then it’s easier to actually read. But what do I know, it’s not like I’ve written millions of lines of CMake (willingly) at this point in my life.

Internal File Layout

Organizing my files was a difficult task. I had tried to do it on a category or concept level before but it turned into a mess quickly as I tried to stay organized. This time, I decided to instead adopt a better naming convention, even if it meant more file operations and many small files.

To give you an idea, this is what I started with (you cannot guess what is stored where. No, there are no elements in _elements.scss):

├─ main.scss
├─ _custom.scss
├─ _mixin.scss
├─ _vars.scss
├─ _admonition.scss
├─ _compare.scss
├─ _elements.scss
├─ _sections.scss
├─ _headers.scss
├─ _lists.scss
├─ _gist.scss
├─ _base.scss
├─ _themes.scss
└─ _color.scss

And this is the directory layout now.

├─ base
├─ elements
├─ components
├─ overrides
└─ text

It’s much easier for me to find things now, and I can more easily add or modify specific sub-objects.

I was also able to organize a few other directories I had been using by sending them to shadowest realm because they were costly and also got in the way of making it easier to update my site’s dependencies.

Social Media Support

My site should properly embed in applications like Discord, Signal, and more. This isn’t that big of a deal, but it had been broken for me for quite some time due to a massive typo (resulting in the code never generating). Ideally, you’ll start to see descriptions and images for every embedded link in the future. I’m still trying to see what other OpenGraph entries I might need to support, but for now, this is more than enough for me.

Markdown “Plus”

Cohost has been the site I tend to frequent most these days. It’s a nice break from the usual algoslop driven websites that so many of us have come to rely on for information. Like many other web services, cohost has adopted markdown syntax for posting. However they have a unique feature: Some CSS and custom HTML are permitted allowing for detailed CSS actions to occur. In some cases, these are called “CSS Crimes”, when you’ve done something the average person might find mind boggling, like implementing a wario ware game. Another is just having fancier text, something that I think is lost on the modern web. One such cohost poster created a tool called Markdown Plus, and I enjoy some of the visual effects that the text provides. However, Markdown Plus uses custom markdown syntax to generate a bunch of HTML via Javascript. However, Hugo supports shortcodes, and that also lets me do some basic programming operations as well, so I can more or less do the same actions and move most of the logic into CSS, setting only CSS variable properties on the generated <span> elements. And so, I ported several of these effects to my site. Now I can bounce , glitch g l i t c h , or shake all I want to my heart’s desire, without ruining the experience for anyone with a screenreader.

What’s Next?

I’ve got quite a bit of things I would like to do now that the general redesign is done. For example, I’d like to maybe write a bit about the xz-utils situation (even though I’m weeks late at this point to the discourse at this point). Additionally, I’d like to more accurately categorize the posts on this site, and make a difference between a post, an article, and a tutorial (yes, I’ll still be writing CMake tutorials). This is mostly so that if you care about my technical posts you can subscribe to that RSS Feed and not have to give a shit regarding some rambling post about some dumb synthesizer I might have purchased. For anyone worried about links, don’t worry. My deployment mechanism supports a _redirects file format (popularized by Netlify, Cloudflare Pages, etc.), so previous links will work, and submitted links to various aggregators over the years will continue to function.

Until next time

Life Update Web Design