How I Added a Blog and a Projects Page to This Site

I wrote a post a little while back about how this whole site got built. Not long after that went up, I kept going, adding a projects page, this actual blog you are reading right now, and a handful of small interactions that took way longer to get right than they had any business taking. This post picks up where that one left off.

Same as last time, I built this with Claude rather than typing every line myself, and I am writing this for the same kind of reader as before. Someone who wants to take the idea and build their own version, not necessarily someone who already knows what a grid layout or a scroll listener is. I will explain the bits that need explaining as I go, but I am not going to water down what actually happened, because the details are the useful part.

Why more pages felt worth it

The original site was a single page. Intro, about me, work history, a photography section, done. That was fine while it was just a résumé with some personality, but I wanted somewhere to actually show finished pieces of work, and somewhere to write, without cramming either into a section that was already doing its own job. Rather than bolt on a separate looking mini site, the goal was to make new pages that felt like they belonged, same colours, same fonts, same navigation bar, just more of it.

Building a projects page first

The projects page came first, and the shape of it borrows pretty directly from an Instagram profile grid. Square tiles, three across, with a bit of breathing room between them so it does not feel like a wall. Each tile represents one project, and I wanted the whole thing to cover three kinds of work, product and data work, photography, and video, without needing three separate pages for it.

To make that work, every tile got tagged behind the scenes with which category it belongs to, and a small row of filter buttons sits above the grid, All, Product, Photo, Video. Clicking one of them does not reload the page or take you anywhere, it just hides the tiles that do not match and keeps the ones that do, using a tiny bit of JavaScript that checks each tile's tag against whichever button you clicked. Hovering a tile reveals its title, so the grid stays clean and photo like until you actually engage with it.

A moving photo strip

The site already had a small photography section with a handful of fixed placeholder photos sitting in a grid. I wanted something that felt more alive, a strip of photos that scrolls past on its own, like a filmstrip rolling by, showing off more shots than a static grid ever could in the same amount of space.

Getting it to loop properly took a bit of thinking. The trick is duplicating the row of photos once, so there are two identical copies sitting side by side, then animating the whole strip so it slides across by exactly the width of one copy before snapping back to the start. Because the second copy is identical to the first, that snap back is invisible, and the scroll just looks endless. I originally had it moving one direction, then decided the other direction read better, which turned out to be as simple as swapping which end of the animation it starts and finishes at.

The other detail worth mentioning is what happens at the edges. The strip deliberately spills out past the normal margins of the page, wider than everything else on the site, but I did not want it to look like it was getting chopped off where it meets the edge of the screen. The fix is something called a mask, which is really just a stencil sitting over the top of the strip, telling the browser to show it fully in the middle and fade it out to nothing right at the edges. The photos dissolve away rather than getting cut, and it reads as intentional rather than broken.

Setting up a blog index

The blog page itself reuses the same navigation bar, footer, colours and fonts as the rest of the site, so it never feels like a separate experiment bolted on. The layout went through a couple of changes though. My first version was a grid of cards, a photo on top and a title and excerpt underneath, several per row. Once there was real content sitting in it, that felt like the wrong shape for a list of things you are meant to read, so I changed it to one article per row instead, with the photo sitting beside the title and excerpt rather than above it, which reads much more like an actual list of posts and less like a shop display.

Each post lives inside its own reusable card, image, category, date, title, a short excerpt, and a read more link, so publishing something new later is mostly just copying one of those blocks and swapping the text, no rebuilding required.

Making the first real post

The post about building the site in the first place needed somewhere proper to live rather than just being placeholder text. Rather than crowd everything onto the blog listing page itself, each article gets its own dedicated page inside its own folder, so every post has its own address that can be linked to and shared on its own, and the listing page just stays a set of short previews pointing at them. This post lives right next to that one in the same folder.

For longer articles like this one, I wanted a list of headings running down the side that you can click to jump straight to a section, similar to what you might see on a long documentation page. On a normal sized screen it should sit next to the article, staying visible the whole time you are reading rather than scrolling away with the text.

Getting it to actually stay still took two attempts. The first version used something called sticky positioning, which behaves normally as you scroll until it reaches a certain point, then locks in place. The problem was the page title sat above it, so there was a small gap before it locked, and that gap meant the sidebar would visibly slide a few pixels the moment you started scrolling, which looked like a glitch rather than a feature. The actual fix was moving the title into the same column as the article text, so it scrolls with the words rather than sitting above the whole layout, and properly fixing the sidebar's position so it never moves at all, worked out with a bit of maths tied to the same page width settings as the rest of the site, so it always lines up no matter how wide your screen is.

Getting the highlight right

Alongside the clickable list of headings, I wanted whichever section you are currently reading to light up automatically as you scroll, so you always know roughly where you are in the article. The first attempt used a built in browser feature that watches elements as they enter and leave the screen. It mostly worked, except the very last heading on the page never lit up, even once you had scrolled all the way to the bottom, because there simply was not enough content sitting underneath it to push it far enough up the screen to trigger.

The fix was to stop relying on that feature and instead directly track how far down the page you have scrolled, checking which heading you have most recently passed, and specifically checking whether you have hit the very bottom of the page, in which case the last heading gets lit up regardless of where it physically sits. A small, slightly annoying edge case, but exactly the kind of thing that is invisible until someone actually reads all the way to the end.

A progress bar for phones

That sidebar simply does not fit on a narrower screen, so it disappears once the page gets too narrow to comfortably fit it next to the article. That meant readers on a phone lost any sense of how far through a long article they were. Rather than try to squeeze the sidebar in somewhere awkward, I added a thin bar sitting under the navigation bar that fills up left to right as you scroll, only appearing on the narrower screens where the sidebar has already disappeared, so the two never overlap or duplicate each other.

Small things that slipped through

A couple of smaller issues came up while doing all of this, worth mentioning because they are the kind of thing that does not throw an error, it just quietly stops looking right. At one point I renamed one of the site's colour variables and forgot to update every single place that referenced the old name. Nothing broke or crashed, a handful of dots and buttons across the site simply stopped showing any colour at all, which is a good reminder that this kind of styling fails silently rather than loudly.

The other recurring one was keeping the navigation bar consistent. Because the site does not share one single template across its pages, adding a new page to the menu means updating it in every single file separately, and it is easy to update three out of four and not notice the last one is now out of step.

What is next

The blog folder is set up now so adding another article is mostly just writing it, and the photos across the site are still the main thing left to swap out for the real thing. I am planning to keep writing here as I keep building, so expect the next one of these to be shorter and a bit more specific.