I think it depends on what you’re actually trying to solve and for me it comes down to the following:
- a way to manage design tokens, with sensible defaults and naming conventions
- utility classes for layouts/positioning and one-off visual changes
- a maintainable & readable way to manage CSS for reusable components
So then you naturally arrive at something like this: stylesheets just for components (using some naming convention such as BEM, CSS Modules, etc.) in combination with PostCSS/Tailwind.
Via theme or @apply you can reference design tokens from Tailwind.
.heading { font-size: theme('fontSize.xl') }
.card { padding: theme('spacing.4') }
The beautify of this is that you can now combine these components with utility classes:
<h1 class="heading flex gap-2">Heading <svg ... /></h1>
<div class="card mt-4"></h1>
Since the composition of components differs page it makes a lot of sense to use utility classes instead of writing additional CSS for each situation.
On top of that you can even make one-off visual changes to components, until it makes sense to introduce a new component property:
<h1 class="heading border-b">Heading with border bottom</h1>
There are a lot of things that Tailwind does that you would otherwise end up doing yourself, just with more code to maintain and probably less well thought out.
It’s a bit unfortunate that Tailwind has become a bit of a religion and there isn’t always a ton of discussion about what styling problems we’re actually trying to solve
(not talking about this thread, just in general).
So I’m not married to a specific framework, it’s just that I found that this is sensible way to go about things.






















