New May 5, 2026

Spring Cleaning

More Front-end Bloggers All from Kitty Giraudel View Spring Cleaning on kittygiraudel.com

The sun is shining, I have plenty of time as I’m still looking for a job so I’ve poured a lot of work into this website to clean up and improve things. I want to share the highlights in this article.

New navigation

Except for some recent design tweaks in February, this website has remained virtually unchanged since as far back as 2020, which is when I ported it to Eleventy. I couldn’t find a Wayback Machine snapshot dated earlier than that, so I’m going to assume this is also when I redesigned it.

I’ve finally bitten the bullet and moved the navigation out of the content column. It took me a little while to come up with something I didn’t hate, and I’m still not enamored with it, but I feel it’s better than it used to be. It’s more anchored, it’s more usable, and breaks the centered column flow a little. Also, the skip link fits very nicely within it.

On the plus side, this enabled me to play with the Popover API for the first time, for the mobile version (thanks to John Dalesandro for his instructive article on the matter). I tried a few approaches where the whole menu was visible at all times before, but there just wasn’t enough room so I decided to switch to a popover menu. It looks nice, I’m happy with it.

I’ve also used @starting-style for the first time to animate the apparition of the menu.

.Navigation[popover] {
	opacity: 0;
	transform: translate(1rem, -1rem) scale(0.95);
	transition: 300ms ease-out;
}

.Navigation[popover]:popover-open { opacity: 1; transform: translate(0) scale(1);

@starting-style { opacity: 0; transform: translate(1rem, -1rem) scale(0.95); } }

New post head

Moving the navigation out of the way had some unintended design side-effects, and led me to rework the header of blog posts. I’ve made the following changes:

Update dates

As mentioned above, I’ve added an update date to articles to help figure out how relevant the content still is.

To do that, I wanted to leverage Eleventy’s built-in support for git Last Modified, which tells Eleventy to extract the date from the last commit touching the file. It has two major downsides though:

  1. It only works for a field named date. If you want both a publication date and an update date, you end up with date being the update date, and have to create a publication_date (or whatever) field. This is backward to me: the publication date is the truly important one, and as such should be held in date. Not the other way around.

  2. It comes with a significant performance hit, due to Eleventy spawning a git log subprocess for every single template being rendered, which starts to matter when you have hundreds of files. To be fair, Eleventy mentions that in the docs.

So I’ve shamelessly copied Jens Oliver Meiert’s approach. The idea is that you compute all dates at once in a single pass and store them in a data file so templates can do cheap reads. I’ve made two important changes to their code:

I’m pretty happy with the outcome, except for the fact that I work so much on this website that most posts end up being marked as recently edited anyway. In principle, this should be helpful for the future. This change also made its way into the sitemap and the RSS feed.

Deprecation notices

I make a point not to delete content from this website, following the Don’t Break the Web directive. However, not all content ages the same way. So I’ve introduced deprecation notices to old articles. It looks like this:

This article is old and references content that may no longer be available, relevant or accurate. It remains online as to not break the web, but its content should be viewed in the context of its publication date in 2012.

Content improvement

To mark old articles as outdated, I’ve gone through all articles and took this opportunity to clean up a lot of things:

And a few things that are a bit more stylistic:

New lists

As shown in the previous section, I’ve updated the appearance of lists (mostly unordered but also ordered a bit) to be more spacious and provide more breathing room. I used to rely on the default browser styles, and decided to go for something custom instead.

I’ve added a small animation to them so they fade into the viewport as you scroll past them. It was really a pretext to use scroll-driven animations, based on an experiment from Adam Argyle.

@media (prefers-reduced-motion: no-preference) {
	.Post li {
		animation-fill-mode: both;
		animation-name: fade-in;
		animation-range: entry 25% cover 50%;
		animation-timeline: --item-timeline;
		view-timeline-name: --item-timeline;
	}
}

@keyframes fade-in { from { opacity: 0; transform: scale(0.95); } }

Animated theme switcher

I’ve found this other cool demo by Adam Argyle leveraging the View Transitions API to animate the change of theme. I’ve tweaked his code a bit to match the design of this website better, and I really love the transition effect. It basically swoops outward from the button in the bottom right corner. Try it!

Baseline widget

As you can see, I’ve introduced a widget for baseline support. It uses the baseline-status web component, which I integrated in Eleventy following Stuart Robson’s article.

It’s nice overall, but I’m particularly unhappy with the fact that it weighs 65Kb, even if I conditionally and asynchronously load it. For reference, my entire home page weighs 75.9kB, and that’s including a stupid 52.9kB apple-touch-icon.png file, so 23kB really. This is 3 times as big.

Also, I couldn’t find a way to tweak the focus styles of the summary element which lives inside the Shadow DOM. No big deal, the component looks very clean anyway.

Tabbed code blocks

I was browsing Roman Komarov’s fantastic website when I stumbled upon his write-up about responsive tab size within code blocks. I’ve been thinking about this problem in the past, wanting to have smaller indentation on mobile where there is less room.

Turns out he has some magic up his sleeve:

pre {
	container-type: inline-size;
}

pre code { tab-size: round(up, 100cqi / 20ch, 2); }

This is lovely and it works like a charm, but none of my code blocks used tab indentation. I thought it would be a nightmare to convert everything, but Cursor absolutely nailed it out of the park. It quickly wrote a solid script, converted all 1,000 or so code blocks to tabs, and that was that.

Perk of that conversion: tabs are better for accessibility anyway, so I’m glad it’s finally done. The only thing I need to figure out is how to make sure I keep using tabs for new code blocks, because my editor defaults to spaces and I’m likely to forget.

Logical properties

More as a learning opportunity than anything else, I’ve updated all CSS to use logical properties and values. That means padding-left becomes padding-inline-start, margin-bottom becomes margin-block-end and so on. In the process, I’ve learned a few things:

Adrian Roselli has a lovely article and diagram to illustrate the differences on CodePen:

See the Pen Logical Properties Mapping by @aardrian on CodePen.

Of course it doesn’t matter too much for this blog since I write almost exclusively in English, and the few pieces of content that are not in English are still not in languages written right-to-left, but still. It’s nice to know it would work flawlessly. Potentially it could be helpful if someone was to use a browser extension to translate content in, say, Persian or Arabic.

You can toggle RTL mode for the whole document with this button, if you just want to try it:

SEO improvements

While doom-scrolling LinkedIn, I stumbled upon this GEO/SEO guide for Claude. I didn’t want to blindly install it because I am being cautious with AI and live in fear of prompt injection, so I’ve manually set up some Claude agents the way that plugin does.

After running them on this website, I came across some opportunities to improve SEO:

Final Jekyll extinction

Since I edited most files anyway with all the aforementioned changes, I’ve decided to address one of the last remnants of the Jekyll era and renamed all folders using an underscore prefix (e.g. _includes now includes). It’s just unnecessary with Eleventy, where we have more granular control over what gets built and how.

I’ve also replaced the now long defunct Simple-Jekyll-Search script with a simple homemade one.

The last real testament of this blog having ever used Jekyll is the URL pattern for posts, which is /YYYY/MM/DD/slug/. Had I built this website today, I’d drop the date from the URL entirely. Too late now.

Wrapping up

Overall, I’m very pleased with how it all turned out. I know it’s not super significant, and most people won’t notice any of that, but it feels good, you know. It’s like when you deep-clean your kitchen, or go through your wardrobe. It’s good for the soul.

Scroll to top