Making the new Salter Cane website
With the release of a new Salter Cane album I figured it was high time to update the design of the band’s website.
Here’s the old version for reference. As you can see, there’s a connection there in some of the design language. Even so, I decided to start completely from scratch.
I opened up a text editor and started writing HTML by hand. Same for the CSS. No templates. No build tools. No pipeline. Nothing. It was a blast!
And lest you think that sounds like a wasteful way of working, I pretty much had the website done in half a day.
Partly that’s because you can do so much with so little in CSS these days. Custom properties for colours, spacing, and fluid typography (thanks to Utopia). Logical properties. View transitions. None of this takes much time at all.
Because I was using custom properties, it was a breeze to add a dark mode with prefers-color-scheme
. I think I might like the dark version more than the default.
The final stylesheet is pretty short. I didn’t bother with any resets. Browsers are pretty consistent with their default styles nowadays. As long as you’ve got some sensible settings on your body
element, the cascade will take care of a lot.
There’s one little CSS trick I think is pretty clever…
The background image is this image. As you can see, it’s a rectangle that’s wider than it is tall. But the web pages are rectangles that are taller than they are wide.
So how I should I position the background image? Centred? Anchored to the top? Anchored to the bottom?
If you open up the website in Chrome (or Safari Technical Preview), you’ll see that the background image is anchored to the top. But if you scroll down you’ll see that the background image is now anchored to the bottom. The background position has changed somehow.
This isn’t just on the home page. On any page, no matter how tall it is, the background image is anchored to the top when the top of the document is in the viewport, and it’s anchored to the bottom when you reach the bottom of the document.
In the past, this kind of thing might’ve been possible with some clever JavaScript that measured the height of the document and updated the background position every time a scroll event is triggered.
But I didn’t need any JavaScript. This is a scroll-driven animation made with just a few lines of CSS.
@keyframes parallax {
from {
background-position: top center;
}
to {
background-position: bottom center;
}
}
@media (prefers-reduced-motion: no-preference) {
html {
animation: parallax auto ease;
animation-timeline: scroll();
}
}
}
This works as a nice bit of progressive enhancement: by default the background image stays anchored to the top of the viewport, which is fine.
Once the site was ready, I spent a bit more time sweating some details, like the responsive images on the home page.
But the biggest performance challenge wasn’t something I had direct control over. There’s a Spotify embed on the home page. Ain’t no party like a third party.
I could put loading="lazy"
on the iframe
but in this case, it’s pretty close to the top of document so it’s still going to start loading at the same time as some of my first-party assets.
I decided to try a little JavaScript library called “lazysizes”. Normally this would ring alarm bells for me: solving a problem with third-party code by adding …more third-party code. But in this case, it really did the trick. The library is loading asynchronously (so it doesn’t interfere with the more important assets) and only then does it start populating the iframe
.
This made a huge difference. The core web vitals went from being abysmal to being perfect.
I’m pretty pleased with how the new website turned out.