This approach allows tailwind to be terser than raw inline styles, while giving you the ability to write a lot of your styling inside the markup, which prevents context-switching. It's a nice balance between many of the approaches that have come before it.
If you're using styled components and you want a small margin you have to do something along the lines of.
const ThingWithMargin = div.styled`
margin: ${margins[1]}
`;
Presuming you've set up a file full of font sizes, margins, paddings.In TailwindCC you get a bunch of very sane, well picked defaults chosen for you for free, by default. You write in a simple DSL and don't have to worry. You can update the defaults as you see fit, too.
<div className="m-1" />
This has autocomplete, etc etc.IF you don't want the clutter of all these utilities, you can abstract them away into smaller components as you already should be doing. You build your component library with speed and can focus on the actually interesting parts of your system as opposed to wasting time naming stuff or pissing about with CSS.
And of course, if your div is reused a lot, you naturally abstract it into a component at a time that suits you!
I'd say try just using for a project or two and you suddently realise you were wasting a whole lot of time and effort before.
Anything truly dynamic calculated can go also into a style= prop. They work great together!
E.g. here's a progress bar I made for a thing:
<div
ref={ref}
className="w-full relative cursor-pointer -mt-1 -mb-1.5 h-3.5"
onMouseDown={onMouseDown}>
<div className="absolute h-1 top-1 bg-gray-600 bottom-0 left-0 right-0" />
<div
className="absolute h-1 top-1 bottom-0 left-0 bg-gray-200"
style={{
width: `${(currentTime / duration) * 100}%`,
}}></div>
</div>
I was so sick of working web because it felt like working in CSS was a total footgun unless you spend a lot of time making a solution that does things right. Now I find working on web projects a joy again. my-component {
margin-inline: var(--margin-thin);
}
If I want this dense notation I can name the custom property `--m-1`. In most IDEs (or language servers) I’ve tried custom properties also have autocomplete.That is I use CSS custom properties inside component scoped styles. (Component scoped styles is what I call the general idea that React’s styled components are implementing, but Vue’s SFC and the shadow DOM scope the styles to the component at hand equally well).
I’m not saying “Don’t use Tailwind; use custom properties instead”. But for those of us that don’t like the idea that Tailwind brings, there are options, and we are perfectly happy with what we got.
If you give the combination of Tailwind + Alpine.js + your favorite server-side templating engine a try, it may just click. At least for me, that was the key.
My assessment is based on the fact that when you design something, you generally have to be able to explain its value, with little exception.
As someone who’s used this approach in production for years I can vouch for it. It greatly reduces complexity and is easier to maintain. Day to day no one is writing any css at all, nor are they bogged down with naming conventions, etc. You just “snap” together your utility classes ad-hoc as needed.
Responsive breakpoints are also much easier to work with because they’re just “built in” as modifiers on all the base utility classes.
Note: I’ve written a lot of CSS and generally prefer rolling my own components to using a library... perhaps I’m not the target audience. Perhaps this is a cherry flavor to make the “designing your own UI” medicine go down more easily. Perhaps I’m mistaken and not being charitable enough, too.