I don’t want to but I’m giving functional CSS a try

I need to stop telling new CSS tech to get off my lawn...

I’ve been writing CSS for a long time. I like it and it makes sense to me. I’m often bewildered by folks who have such a hard time with it. I was raised on Eric Meyer’s and Jeffery Zeldman’s Web standards and semantic html purity laws. Those ideas are buried deep in my psyche. However, you may not have noticed, but web development has changed a lot in the last 20 years! I’ve learned many new things over that time, but it’s been a long time since I’ve evaluated where I stand with CSS. For this post, I’m not going to do a detailed how-to or deep dive. I’m going to walk you through some thoughts and observations I’ve had as I take my first stab at functional css. Let’s begin!


One of the primary tenets of the ol’ semantic HTML dogmas is the separation of content and presentation. What this means is your HTML should consist of simple, semantic descriptions of you content. If it’s properly done, it should be free from any information related to the visual display of that content. Your CSS should contain all visual information, organized with semantic class names. I love this pattern for developing websites and you should too. It’s powerful in its simplicity and elegance.

The question, as always with any technical pattern, is how far do you take it and what is “correct”. The heaven that this semantic markup approach preached was the ability to redesign your site without changing any markup. Swap out a css file to achieve zen!

After 15 years of writing css, had I ever achieved zen? Well…no. The reality is the second you add that extra div to aid in the styling of a certain set of elements, you’ve embedded visual dependencies into your markup. The more you do that, the likelihood of your markup surviving a redesign dwindles. It’s only recently that tooling such as flexbox and css grid, have made this practically attainable.

Component focused development has helped to reduce duplication and provide clear guidance on how to organize your styles. But it can still be haphazard and messy work. It’s also impossible to deny the explicit and unambiguous productivity boost utility classes such as .text-center provide. These classes break the semantic contract, but do so with obvious benefits.

Writing this all out has been helpful. I still think semantic html is important, but if I’m honest with myself, I’m open to the idea of unsemantic css. I’m ready to take the next step.

Enter tailwind

What I’m looking for is something simple and unobtrusive that lets me think in CSS without having to worry about organization or naming. This is where functional css enters the picture. Functional css says to-hell with semantic styles (mostly). Tools like tailwind generate thousands of css attribute specific utility classes. You then compose them in your html. You no longer create a container class. You apply mx-auto max-w-lg. Sounds promising!

But I need to be honest with you. The first 10 times I tried to consider tailwind, I was appalled. It seemed like a bait and switch. Sure, that looks fine for a hello world app, but how can that scale? What about responsive css? Animation? I shuddered to think of what a template would look like for any moderately complex design. However, enough people have strongly recommended this that I had to at least put it into practice before I completely wrote it off. So I set out to redo this website using tailwind. Here are some lessons now that I’ve finished:


All in all, I’m pleased with the outcome. I like how DRY and fast the CSS is. I LOVE how nicely it works with purgecss. I like how quickly I can sketch out designs. The big learning curve for me, and the thing that gives me the most pause, is how gnarly the templates can get.I think the framework’s component approach by using @apply is critical to address things. However, there is a subtlety to how and when to use it that’s still not completely clear to me.

Will I be switching any big apps to it anytime soon? No. Will I evaluate it on a new project? Definitely.


Thanks to Sam Selikoff and Luke Melia for the feedback on this post.

Written by - Permanent Link

On Development

Related Posts