Site Redesign Postmortem

I just launched a redesign of this site, and wanted to record some thoughts on the motivation, process and outcomes.
Why Redesign?
The previous version of this site, statically generated by Bridgetown, served as a great stepping stone away from WordPress. But the visual design was a holdover from an outdated WordPress theme which didn't represent me well. I was also looking for something with more features out-of-the-box, and having previously investigated Ghost, I decided to dig in. I was also itching to experiment with more front-end techniques that I've been learning about.
Revisiting TailwindCSS
Having had a good experience with TailwindCSS, I started this project with Tailwind. It was a good way to get some ideas prototyped, but eventually I migrated to vanilla (mostly) CSS. There are a few reasons for making this switch.
First, the unwieldy list of classes in the HTML. I think even the most ardent supporters of Tailwind would admit that having huge lists of classes is a compromise at best. I haven't been able to devise a good way to organize these. This is compounded when we start adding responsive variants and dark mode.
Here's an example of some actual HTML I wrote:
<div class="flex flex-col xl:flex-row gap-8 md:gap-16 divide-y xl:divide-y-0 xl:divide-x divide-neutral-med dark:divide-neutral-muted">
Is this any better?
<div class="
flex flex-col xl:flex-row
gap-8 md:gap-16
divide-y xl:divide-y-0 xl:divide-x
divide-neutral-med
dark:divide-neutral-muted
">
Marginally, perhaps, but still not good. I found myself spending a lot of time trying to organize these classes into something comprehensible. I also really dislike the way the indentation looks when tag contents are included:
<div class="
flex flex-col xl:flex-row
gap-8 md:gap-16
divide-y xl:divide-y-0 xl:divide-x
divide-neutral-med
dark:divide-neutral-muted
">
Content
</div>
It's awkward, and it's difficult to parse large amounts of code that follow this shape.
I do think Tailwind allows me to get ideas on the page very rapidly, and simplifies some sophisticated techniques. But when I start adding more details and subtlety, I get less willing to make the compromises it demands.
Vanilla Is Actually My Favourite Flavour
At the same time I started losing patience with Tailwind, I was reading resources like Every Layout, and CSS Nouveau. I saw Fabio Neves talk about HTML custom elements at a Ruby meetup. These ideas gave the fuel I needed to start over with plain HTML and CSS.
The immediate benefit of this change was a return to clean HTML, no longer full of endless parades of utility classes. This isn't just an win for aesthetic or convenience: being able to focus on the markup itself eases the process of distilling it to its most essential components, to make better decisions about how we're writing semantic HTML, when to add custom elements, and how to provide accessibility enhancements.
Here's some actual HTML from this site, with very little cruft removed. It may seem simple, but it takes effort to pare the structure down and to avoid elements that are only there to hang styles. I wouldn't have been able to get to this minimalism with the litany of classes that Tailwind requires.
<body>
<header>
<masthead aria-labelledby="site-title">
...
</masthead>
<nav aria-label="Primary">
...
</nav>
</header>
<main>
<article-list>
<h1>Articles</h1>
<article card aria-labelledby="post-header-...">
<post-meta>
<time datetime="2025-03-25"> 25 Mar 2025 </time>
•
4 min read
</post-meta>
<h2 id="post-header-...">
...
</h2>
<excerpt>...</excerpt>
</article>
...
</article-list>
</main>
<footer>...</footer>
</body>
Locality
One of the unexpected benefits of moving from Tailwind back to plain CSS came around the idea of locality of code. Locality seems like one of the most convincing features of Tailwind, right? All the styles for an element are right there on the element itself. But we end up distributing related aspects of our presentation. Classes related to, for example, the high-level layout of your site are spread across many HTML tags and perhaps even in separate templates. As we add, remove, and refine utility classes, it becomes hard to get a birds-eye view of all of the CSS that is contributing to our layout. With vanilla CSS, we can put all layout rules in a single file, and see them at a glance. It's a locality of aspects, rather than locality of material.
This approach made it much easier to refine and simplify, to discover bugs, and resulted in a more elegant design. Here's the CSS for the top-level layou of this site:
body {
@mixin sidebar-parent 2rem;
padding: 2vw;
}
body > header {
@mixin sidebar 20rem;
}
body > main {
@mixin sidebar-content 50%;
}
body > footer {
min-inline-size: 100%;
padding-block: var(--s2);
}
article-list {
@mixin stack var(--s2);
article:not(:last-child) {
padding-bottom: var(--s2);
}
}
layout.css
(I'm using PostCSS Mixins, my one concession to a build step in this project. They are shortcuts for applying techniques from Every Layout)
That's it. The Tailwind version of this would have been spread over four or five templates, and interspersed with other utility classes on the same elements. I can also start to introduce my own abstractions, like the `sidebar` mixins used in this example.
I'm not trying to dunk on Tailwind; I still recognize its value and think that there are good use cases, especially rapid prototyping. But I'm more aware of the trade-offs than ever.
Discovery
Another benefit of doing raw CSS is the discovery of new features. I wasn't previously aware of CSS Logical properties like flow relative values, or some of the sophisticated things you can do with CSS custom properties (variables). I learned how easy it is to add dark mode, and how great CSS selectors are these days.
Yes, CSS frameworks reveal some of these, but they just as often hide them away or abstract the details. I need to use them myself to understand and appreciate them.
Wrap Up
I could go on about some of the cool things I was able to build into this design, like harmonic type scales, intrinsic design, and animations, but others have said it better. It feels good to get back to basics and to double down on structure, semantics and accessibility, and I'm looking forward to learning more.