I recently redesigned my website. It’s not exactly a technical marvel, but I feel that is its strength, and I wish more projects I observed prioritised delivering useful content rather than expensive to implement designs. Most people just want to read some text and look at some pictures and it’s extremely easy to do this if you don’t tie yourself up in flavour-of-the-month technologies.
On the way I got a chance to brush up on some of the more modern CSS techniques which was a lot of fun. People who complain about modern-day web development don’t know how lucky they’ve got it.
There’s so many fantastic techniques and tools built into web browsers compared to 10 years ago that don’t require a lick of JavaScript.
The approach
Under-the-hood not much has changed.
- The server has a
posts
folder which contains markdown files for each post. - The web server is written in Go. When it starts up it opens up every markdown file, converts it into HTML and puts it in an in-memory map.
- When it gets requests, the server simply looks at the path and matches it to a key in the map of posts, returning the pre-rendered post.
- The frontend is plain HTML and CSS because it’s the best, simplest, most performant way of delivering textual content to users.
- It is deployed to Heroku and sits behind CloudFlare CDN.
I’ll use the simplest tools I can to deliver a good experience. This will sometimes rely on using CSS techniques that won’t work on older browsers. This is fine so long as my content is still accessible and looks ok. This is called "graceful degradation".
New things I learned
CSS Variables
On the face of it they seem like a nice way to DRY up some code and give some semantics to things like colours.
:root {
--nav-colour: hsla(354, 100%, 71%, 1);
--link-colour: hsl(354, 100%, 71%);
--bg-colour: hsla(30, 100%, 99%, 1);
--code-colour: hsla(327, 24%, 35%, 1);
--text-colour: hsla(280, 12%, 20%, 1);
--header-colour: hsla(280, 12%, 20%, 1);
--font-size: 2.2rem;
--line-height-multiplier: 1.5;
}
time {
color: var(--code-colour);
}
I think they’re an interesting way of identifying the complexity of your design. If you give yourself the constraint that the only place you’re allowed to declare a colour value is within your variables then you’ll have a well-organised list of colours on your website. If that list gets long, or it becomes hard to name your variables ask yourself
Do I really need all these colours for my website?
You can take the same line of thinking in respect to the variables you use with your typography and your general spacing. By using variables it forces you to think and will help give your design a more consistent and less cluttered feel.
Media query for dark mode
Dark-mode feels pretty faddy to me but I am pleased there is a nice progressive way to change the style of your website without relying on any wonky JavaScript.
If supported, my website will automatically change into dark-mode with no prompting from the user. In OS X you can set dark mode to automatic which will go from light mode to dark through the day and my website will respect the user’s wish.
This feels much better than expecting users to have to update some kind of setting on every website they visit.
This works especially well with CSS variables. To enable dark-mode all I had to do was change the value of my variables.
@media (prefers-color-scheme: dark) {
:root {
--nav-colour: #15B097;
--link-colour: #3282b8;
--bg-colour: #051923;
--code-colour: #15B097;
--text-colour: #EDF6F9;
--header-colour: #1C77C3;
}
img {
filter: brightness(.8) contrast(1.2);
}
body {
font-weight: 350;
}
}
Easy!
Fallback for older browsers
Without any effort, my website is still useable for users of Internet Explorer (and probably Netscape Navigator).
Web browsers are very forgiving and will do their best effort to render even if they see syntax they don’t understand. As I am relying on robust, battle-tested technology (HTML & CSS) it "works" - the content is still accessible.
If I had done some react-whizz-bang framework single page app I would have to jump through a lot more hoops to reliably deliver some text.
Fallback techniques
Including this in the head of the document means this CSS file will only be loaded by users of IE9 and older.
<!--[if lte 9]>
<link rel="stylesheet" type="text/css" href="/static/fallback.css">
<![endif]-->
The following media query lets me style for IE10 and IE11
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
body {
/* IE 10 & 11 specific style declarations */
}
}
I don’t anticipate many users of IE11 or under being especially interested in a programmer’s blog, but it can’t hurt to help them out.
It's not pixel-perfect, but it doesn't have to be. I have seen teams spend days fixing minor pedantic styling issues with Internet Explorer and I can't imagine that's the best way to spend expensive developer time. Are you building websites to satisfy your users or designers?
Performance
All the content delivered and styled in 40ms with under 5kb of payload
(excluding post-specific images, which I try to minimise)
All these fancy computers we use have an impact on the environment. By taking a minimalist approach my website's carbon footprint is cleaner than 99% of the websites tested on websitecarbon.com
Big deal Chris, it’s only HTML and CSS, it’s not a real website
Yeah, it’s only HTML and CSS, brilliant isn’t it. Easy to make, accessible and performant. I made my first website around 21 years ago, and I find it quite comforting the same technology I worked with then works now.
I wish more websites were written like this rather than clogging my network and computer with megabytes of useless JavaScript written by developers running transpilers over transpilers on frameworks built on top of other frameworks and for what?
- Fancy transitions?
- The client not doing a full page refresh going between pages?
Do your users actually care about this? Click between links on my archive page and tell me it’s too slow and has a bad user experience.
There are projects where SPAs are a good fit, but many developers are poor at making this decision and add a huge amount of complexity for no real reason.
Wrapping up
Making a static website does not require a fancy blog generator built on top of a gig of node_modules
. You do not need special tools to make a great website.
Even if you’re not a confident “backend” developer you don't have to write a web server like I did; you can still… create websites with plain old HTML files, written by hand!
This is a totally legitimate way of making many kinds of websites and will most likely result in the best user experience for the least effort.
Top comments (6)
Hello. Your site looks really nice, but the header flickers during scrolling on my Android phone. I'll try to fix it, and I'll let you know what's causing it. Also, one way you could make you site faster is with a service worker. In case you don't know, that's a piece of JS run by the browser that sits between the website and the server, acting like a proxy. You can use it to do things like make your site available offline, and you can use WebAssembly to do it. Because TinyGo (a go compiler) supports compiling to WASM, you could make at least part of your server optionally run in the service worker, fetching only the markdown and metadata, and doing the page generation in the browser.
This is definitely the way ahead Chris. You should have a series of service workers prefetching your site as markdown and then rendering the HTML as you scroll down the page. Anything else isn't using enough JavaScript to be professional.
In fact, you should serve the entire site up as a wasm file including all the markdown and CSS inline. Use Webpack to chunk this appropriately. That way you can have your whole website loading whenever anyone visits your blog so that the page transistions will be lightning fast.
To optimize for SEO remember to serve the same content statically from your server whenever it gets crawled though. You're already doing this so that should be easy.
This is simply never true. There is no minimum amount of JS required. You usually can get by with just CSS.
Nice write up Chris.
Adding to what easrng said, it looks like you need to add a
z-index
to the nav as the images are scrolling over it.That's not the issue I had, I realized the my browser seems to be a little qirky when it comes to elements fixed to the top. I think it's because I use bromite and the "show the omnibar all the time" patch is messing something up.
Also, awesome Page Speed Insights score: