I moved this blog from WordPress to Hugo in December 2017 to learn about static site generators and to practise maintaining a site using modern processes like Git. I chose the Future Imperfect theme as a foundation and put my own styles in
add-on.css, which takes precedence over the theme’s stylesheet
Override stylesheets are useful. You can restyle elements of a theme yet leave the core styles such as layout and typography intact. When a new version of the core stylesheet is available, you can upgrade a theme without affecting your override stylesheet.
Over time though, override stylesheets can bloat. Four months after switching to Hugo, I reached a tipping point. Battling precedence conflicts and unwanted cascades between
main.css took too much time. I wanted a tidy, maintainable theme and to commit more time to blogging.
Refactoring a theme can be a scary, significant undertaking.
main.css has 2,500 lines while my
add-on.css has reached 1,000 lines.
As well as merging these stylesheets into one file, I wanted to edit other parts of the theme, which is written in the Go language. I’m no programmer. I scrape through by reading manuals or trial and error.
Two things gave me the confidence to jump in:
- A day of front-end web development training (and the prep work) by Mat Mannion. He encouraged me to think more like a developer and “to get more into a mindset of building a house than painting a wall”
- Adam Silver’s book MaintainableCSS, which has principles and practical examples of how to write modular and maintainable CSS
Before writing a line of CSS, I decided on three principles:
- Design for small screens first and progressively add style for wider breakpoints. This meant inverting
main.css’s large-screen-first-then-down structure of media queries.
- Write in LESS instead of CSS to take advantage of variables and to be more efficient.
- Define a new typography scheme with a larger base font size, and vertical rhythm and spacing based on ems.
I prefer names related to scales rather than devices such as
-mobile. At the top of
main.less, I defined breakpoint variable names inspired by T-shirt sizes:
@screen-xxl-min: 1680px; @screen-xl-max: 1679px; @screen-xl-min: 1280px; @screen-l-max: 1279px; @screen-l-min: 980px; @screen-m-max: 979px; @screen-m-min: 736px; @screen-s-max: 735px; @screen-s-min: 480px;
At the top of
main.less, I defined colour variables with names prefixed with
gw-. This helps me search for instances of the colour classes I use throughout the stylesheet. It also makes changing the whole site palette a swift task.
@gw-green-mid: #2ab7ca; @gw-green-dark: #1b7581; @gw-green-light: #def2f4; @gw-grey-dark: #3b4045; @gw-grey-mid: #d2d2d5; @gw-grey-light: #edeeef; @gw-white: #fcfcfc;
Stating the colour in the class name conflicts with the HTML5 spec, which Adam Silver quotes in his chapter on semantics:
“… authors are encouraged to use values that describe the nature of the content, rather than values that describe the desired presentation of the content.”
I could use
@gw-colour-mid, for example. In this instance though, as it’s only me maintaining the stylesheet, I chose a variable name that’s semantic to me.
I reset the base font size to 16px for small devices and 20px for larger screens. The type scale is 1.200 Minor Third:
I optimised the post content’s line length to maintain readability, and left- and right-hand white space, across all screen widths. The stylesheet has a lot of media queries to ensure a line length between 45 and 90 characters. The weighty, repetitive code is worth it though. For a succinct explanation, see Matthew Butterick’s Practical Typography.
To help write the new stylesheet and tick off sections of
add-on.css as I merged them, I used a mini map with
TODO: comments at the top of
main.less. The map outlines the stylesheet structure:
/* - Palette variables - Breakpoint variables - Reset - Type - Wrapper - Header - Menu - Search - Main layout - Category list - Portfolio list - Post - Sidebar - Social share buttons - Footer */
The structure of the stylesheet matches how I look at a site design, interpret the main elements and decide what order to do the work:
- colour palette
- responsive breakpoints
- main layout
It’s easy to go down a rabbit hole when styling the content so I try to focus on styling elements from left to right, top to bottom:
When I get stuck or take a break, I leave
TODO: comments in
main.less. Wayou Liu’s TODO Highlight extension for Visual Studio Code helps me see these:
Searching the theme for
TODO helps me find any parts I may have forgotten about.
Compiling LESS to CSS
I’m using Koala to watch for changes to
main.less and compile it to the theme’s
main.css. Using an app outside of the Hugo build and deploy process is not best practice though. I should work out how to include preprocessing and compiling as part of the Hugo site build. That’s some chunky learning for another day.
For now, I have one maintainable stylesheet for the theme, a responsive mobile-first implementation and a clean visual aesthetic based on solid typography. The original 3,500 lines of CSS are a more manageable 2,000 lines of LESS.
Time for a brew.