JavaScript-less Jekyll website, but not empty


Note: This was drafted in 2018 but finally written in 2022, yay for procrastination.

Preface aka whyyy

So, the challenge: build a website that’s “good enough”, meaning it doesn’t hurt the eyes of anyone seeing it, with contents I can publicly acknowledge and, generally, email-signature-includable.

But, there’s a twist or two:

  • I want it to look OK on any device - so responsive design it is;
  • I want it to be super light, no user tracking and so on - so built without using ANY JavaScript;
  • I want it to be inherently secure (at least from the perspective of the server that’s hosting it) - so generated, statically-served content;
  • Any additional bells, whistles, sparkles and fireworks I can fit are a bonus!

Choices

My choices:

  • Jekyll as the generator
  • Pure.css as the base CSS framework (layout)
  • Jekyll Clean Dark as the base of the site’s theme
  • and some additional sparkly bits, as described below.

Jekyll - the generator

I’ve chosen Jekyll because… well, I don’t remember why.
Maybe because there weren’t so many options back then.
Maybe because I’ve heard of Jekyll and I’ve seen some sites built with it.
Maybe because I hate myself and I like to suffer through working with a language and an ecosystem that I’m not familiar with (Ruby).
Maybe because I liked writing short (and sometimes longer) notes in markdown, as I find it readable both in the raw and the rendered versions and it has features matching my requirements (e.g. code blocks).
Maybe it doesn’t matter anyway…

Oh, and the CSS is actually writen in Sass, because why should anyone suffer through writing raw CSS.

Layout

After going through some themes I’ve set my eyes on the Jekyll Clean Dark - it was simple, sleek (-ish) and yet didn’t look half-bad.
Oh, and it was dark - did I mention I set the dark mode EVERYWHERE, even if it requires some hacks, addons and so on?

But, the theme was heavily dependent on many scripts and some, in my opinion, questionable CSS resources.

So I’ve basically rewritten it using Pure.css - a set of really small (the whole site is under 400KiB!), non-JS-dependent CSS classes with some clever tricks up their sleeves, mainly - it’s responsive by design.

The layout is simple and required minimal additional layout styling - mainly forcing flex display and some minor shenanigans to make the footer stick to the bottom of the page even with no content in the main part.

Whole page eyecandy

There is some, though it may not be noticable on the first glance.
The main two things are: fontawesome usage and a responsive, no-JS hamburger menu that appears on mobile (you’re on desktop? Try the responsive view from developer menu!).

Fontawesome without JavaScript

I’ve shifted the files around - the fonts went into assets/fonts/font-awesome/, the underscored SCSS into _sass/font-awesome/, the font-face SCSS (regular, solid) into _sass/ and the main fontawesome.scss into assets/css/.
Additionally, some variables had to be tuned, specifically the paths - fa-font-path in _variables.scss and include paths in the main file.

Pure CSS hamburger

The hamburger menu is based on this codepen entry.
It is visible on smaller screens via the CSS @media rule and is basically a big checkbox and three empty spans acting as the bars.

The checkbox floats in front of the bars and controls whether the menu is visible using the :checked selector for the neighbouring bars.

The bars are simple - just a box with set dimensions and a border-radius.
Making the bars switch between parallel and crossed (for the closing ‘X’) is more tricky - using the aforementioned :checked selector combined with :nth-child(x) one I’m rotating the first and last bars and making the middle one fully transparent (opacity: 0;).
Throw in a small transform 0.5s cubic-bezier and it even animates, for free, no JS!

The hamburger and the menu itself stick to the top-left corner of the screen using position: absolute and some margin manipulation.
The menu is forcibly overflown in size using the min-width: 100vw; property (100% of the viewport) and is shown/hidden using the :checked selector switching the translate transition.

The only thing not implemented is closing the menu by clicking outside of its boundary but that’s a task for another day…

Single entry eyecandy

There are two main items on this list as well: syntax highlighting and collapsible, automatically generated table of contents.

Syntax highlighting

The syntax highlighting is basically automatic: the kramdown Markdown converter marks up the code blocks based on the marked language automatically, and the Clean Dark theme came with a syntax.scss converting them span classes into something colorful.

Table of contents

Thanks to Jekyll Pure Liquid Table of Contents, the table of contents is generated automatically and is included in the post page layout like this:

{% include toc.html html=content sanitize=true %}

Making it nice was more involved, but based on this article I’ve managed to make it collapsible and to do it in pure CSS.

The ToC header is basically a full-width label for an invisible checkbox.
As with the hamburger menu, the :checked selector on the input activates additional rules for the adjacent elements (+ selector) - it rotates the arrow (::after pseudo-element) and changes the max-height for the ToC container.
Unfortunately, for the content below the ToC to slide smoothly I had to set the max-height using absolute units, as 100% results in a jump.
But I don’t plan on writing stuff with ToCs long enough to hit that limitation (;

Post-scriptum

As mentioned in the beginning, this post was first drafted in 2018 but written only recently.
However, the draft was… lacking. Sparse. Well, it was just two lines of a placeholder really.

Re-researching how/why/what did I do so long ago was a challenge in itself and I think the experience can serve as a warning of sorts, or a speck of wisdom.

Not the “don’t procrastinate” type though; more like the “any documentation is better than none”.


Share this post: