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:
- Reduce number of CDN’s used for external assets.
- Reduce number of assets transferred over the network.
- Still no CSS Frameworks.
- Even More CSS Grid usage
- Responsive Design for Mobile Readers
- Usage of the so-called Neobrutalist design trend
- Vibrant Pastel-like Colors used in conjunction with Neobrutalism
- Use ESM over CJS for Javascript modules.
- Better syntax highlighting for CMake (yes, really)
- Better internal organization of SASS (
.scss
) files - Better Social Media Support
- Markdown Plus style text effects (with the option for more in the future)
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
.innerHTML
.trimRight()
.split("\n")
.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];
});
element.replaceChildren(...children);
}
}
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!
Neobrutalism
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.
Yavascript
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 Literals("EXCLUDE_FROM_ALL", "SYSTEM", "OVERRIDE_FIND_PACKAGE"),
new Symbols(
"FIND_PACKAGE_ARGS",
/URL(?:_(?:HASH|MD5))?/,
/DOWNLOAD_(?:EXTRACT_TIMESTAMP|NO_(?:EXTRACT|PROGRESS))/,
/(?:INACTIVITY_)?TIMEOUT/,
/HTTP_(?:USERNAME|PASSWORD|HEADER)/,
/TLS_(?:VERIFY|CAINFO)/,
/NETRC(?:_FILE)/,
/GIT_(?:REPOSITORY|TAG|REMOTE_(?:NAME|UPDATE_STRATEGY)|SUBMODULES(?:_RECURSE)?|SHALLOW|PROGRESS|CONFIG)/
),
new Literals("IGNORED", "OPTIONAL", "REQUIRED", "CHECKOUT", /REBASE(?:_CHECKOUT)?/),
)
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
):
css
├─ 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.
css
├─ 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