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”.