Tailwind didn't invent utility classes. We've done this since the '90s.
> significantly easier to maintain
Disagree totally. Utility classes are good for rapid prototyping. But they clutter your code, mix semantics with presentation, and are a pain in the ass when it comes to code reuse. The cascade part of CSS is, believe it or not, actually useful for code reuse. Need to change a font deep in some nested component? Not a problem with CSS. Tailwind, you're fucked. You'll need to modify each component layer to pass down a class prop. Or do some ugly context hack.
* HTML has always mixed semantics and presentation.
* It’s terrific for production applications because we don’t lovingly hand-craft each DOM node. Far from being an enemy of reuse, it enables refactoring at the point of HTML generation, and aligns particularly well with partials and view helper functions/objects.
* The cascade is still there; you’re not fucked. Not even if you’ve been suckered into using some react-like framework.
no, we really didn't. tho i'll agree that utility classes have been a thing for longer than tailwind/bootstrap/tachyons/pico/etc have existed
> mix semantics with presentation
there is nothing semantic about class names: nothing, zero, zilch - using IDs are even worse due to specificity, with none of the "semantic" benefit. focus on the correct top level wrappers
part of me wonders about the extent of what HN commenters actually do on the web regarding styles, or if they just slap together some homogenous web app or static site where its rather easy to not have a design team needing flexibility on every little thing.
case in point, our main "button" has about 15 different base variants (that *3 currently) depending on context, not counting the interaction states.
But the thing is you can always do that if it’s needed. There’s no one forcing you to strictly adopt the utility pattern. It’s all just vanilla CSS at the end of the day. If a hybrid approach works best for your project then do that.
Personally I find the need for this to be quite rare, and there are actually some good arguments against writing too much specificity in to your css even if it’s more convenient up front.
I also started out thinking the whole idea seemed backward. Now I think of it this way: it works extremely well in practice, even if in theory it won't.
To fix the css + jsx in one file, just write your styled components at the bottom of your component.
If you ever seen a react component completely riddled with Tailwind, you'll realize how messy and uncoordinated it looks.
Even I would consider switching between two files just to avoid that style of css.
Furthermore the necessity to utilize horizontal scroll because adding 10+ more rules will inevitably break your prettier printWidth rule is, by far, the most annoying aspect of Tailwind.
absolute inset-0 bg-gradient-to-r from-cyan-400 to-sky-500 shadow-lg transform -skew-y-6 sm:skew-y-0 sm:-rotate-6 sm:rounded-3xl
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
linear-gradient(45deg, #fff, #000);
box-shadow: 1px 1px 1px 0 rgb(0 0 0 / 0.05);
transform: skewY(60deg);
border-radius: 4px;
transform: rotate(60deg);
Consider these two snippets, after time of not looking at your css code, do you think 10+ rules on one line is maintainable?Not even close, ask yourself to change a css property - you would have to iteratively go from left to right until you find it, whereas looking from top down you can immediately catch the css rule you want to find.
Succinct doesn't mean maintainable, and sometimes verbosity does.
Tailwindcss isn't even close to being the future.
And you can split, and sort classes with editor plugins which makes it almost equally good as your example.
Regardless of where place your tailwindcss or where you split / sort classes, reading iteratively from left to right, especially if the css rules are numerous, is not legible.
just looking at the two examples above, and already I can tell how much it would be easier to maintain verbose css.
It's much more difficult to scan a list of classes in a single line. With CSS I can quickly scan the declarations from top to bottom until I find the thing I want.
Complex nested declarations are also super easy to scan when using SCSS. When you start adding pseudoclasses with TW it becomes a shit show.
And it really makes the markup an absolute mess for anything other than trivial examples.
People complain about not knowing where the styles are, which was a valid concern when doing old school CSS (everything in a couple of files) but I haven't had that issue since I started using SCSS in almost a decade.
When doing front end with components I store the SCSS for the component in the same directory of the component file. Eg: MyComponent.svelte and MyComponent.scss. Super easy and clear. I've also written a small VSCode extension that allows me switch between the component and its SCSS file with a shortcut. I don't even have to open the SCSS file or look for it. I configure Webpack or whatever I'm using to automatically include the .scss files in the component folders. I have all the convenience and control I want without relying on something as convoluted as TW.
.class1 {
.class2 {
&:hover {
font-family: value;
}
body.some-thing & {
color: woooooo;
}
}
}The problem with Tailwind is there's nothing you can do to avoid the much more difficult to scan and understand syntax described above. I personally don't understand why people are drinking this koolaide. I really think this is a fad a lot of people are going to come to regret when they go back to maintain older projects based on it.
a) maybe you don't really know how far up the chain that tag gets called from.
b) it creates new selectors for class1 and class1.class2, as well as class1.class2's hover
c) creates a hyper specificity
now, I'm not advocating this usage of SASS - but it can be a handy hatchet when you need to support multiple themes with minimal changes/effort, much to the chagrin of specificity and maintainability
I think the reason a lot of ppl think they need tailwind, is because a) they aren't familiar enough with more current CSS techniques like CSS modules and linting which can limit stuff like nested descendant selectors and/or b) they're tricked into thinking they won't have to learn as much about CSS (a dangerous fallacy unless you're sticking to the most basic of prototypes!).
Yeah 100%
But if you look at the State of CSS survey, TW is still relatively not as popular as Twitter or HN would make you believe.
Which is technically true but irrelevant. TW doesn't prevent you from understanding fundamental CSS concepts such as the box model, cascading, etc. Anyone with even basic CSS knowledge would not write this nonsensical and malicious example you just used.
The difference between your 2 examples is that TW allowed you to handle media queries seamlessly but you couldn't do that in your styles example.
but a media query in styled components would just be
@media (max-width: 700px) {
css here
}
it's not that much harder.Also, the lack of address of real problems of tailwindcss of OPs comment in terms of mantainability is something you consider.
reading iteratively from left to right especially if it has 10+ css rules, in terms of legibility, is not really all too great.
I would absolutely hate to adjust something in tailwindcss, after not seeing the codebase in a month's time.
Whereas regular css properties, i can easily find by eye.
const inputWrapperClass = classNames(
'flex flex-col gap-y-1',
'group-focus:border-blue-500',
isDisabled ? 'opacity-50' : null
);
return (
<label className={inputWrapperClass}>
{...}
</label>
)
In practice our "full-stack" developers are writing less and less CSS because they're just using the components that encapsulate all of this, our frontend developers get code completion for our design system tokens, and we haven't had to ship any new CSS classes in the last few months.Our new hires are able to just use the design system tokens rather than going in and saying `padding: 5px` and `padding: 4px` because the designer didn't think it was a big deal. They just write `p-1` and that covers it.
All the components get tree-shaken and only ship the styles they need so bundle size gets reduced as well.
If I had my dream team of 10x frontend developers and a perfect design team who always follows the rules they create then yes I would use regular css with css variables, but I don't.
I am more than happy to sacrifice "separation of technologies" for a happier team, more consistent styling, and faster delivery times.
Not sure what you mean by that. I've been doing this since we did layouts with tables and shims in the 90s. I've found TW pretty nice to maintain myself.
"It's not that much harder", but a) it's a simple example and b) now you're going to litter your code with a load of hard coded media widths?
Let's talk about something concrete. Let's take a really simple layout that changes border and margin responsively (this, for me, is seamless).
<div className="m-8 lg:m-0">
<div className="border-2 md:border-4">
Content
</div>
</div>
How would you do that?I can go as far as using some of its standardized constants in my BEM codebases.
Snark aside, I believe the future of CSS is closer to ITCSS - working with the cascade to minimize the need to modify styles.
https://tailwindcss.com/blog/automatic-class-sorting-with-pr...
I am pretty conservative in terms of "use boring tech", because I see so much reinventing of the wheel and making the same mistakes, but Tailwind is not in that camp!
I was never happy with any of the CSS in JS solutions in React land – all of them felt tedious or boilerplate-heavy compared to Vue's CSS model, which is excellent. Writing css and getting component scoping for free are great.
But with tailwind I've minimized usage of Vue CSS too. I pull it in occasionally when I need specific overrides of the tailwind component lib I'm using, but other than that I don't even need to touch css.
I've tried multiple times to use it, but I always end up using something like bootstrap. Funnily enough, I paid for tailwindui and take the styles and reproduce them in bootstrap css.
Bootstrap community seems to have given up. They only want to sell templates. The default is ugly. Sometimes I think about going back to bootstrap 2.
I’m a huge fan but maintaining tailwind projects is actually a huge pain in the ass. I could maybe improve it by factoring out the classes from my html into a separate sheet using @apply when I’m “done” a project, but I don’t, and it defeats the convenience value anyway.
The markup is so overwhelming when there’s anything remotely complex. And sometimes components are almost identical but with slight variations. I miss seeing an element with a simple .classname to let me know what’s going on. Admittedly this is due to a lack of foresight on my part but moving forward I’m either re-thinking tailwind or ditching it.
I even have a pre-release 0.6v or something running on a production site I need to maintain. Which is stupid and my fault but demonstrates 1) that I’m a huge fan and have been using it forever and 2) it can suck maintaining if not thought out properly.
Don’t forget now you need to configure webpack for node sass and purge css and blah blah blah.
Tailwind is great for building something you never need to touch again.
I do it by refactoring my HTML.
By the way, you don’t need webpack to use Tailwind. It works great with lightweight asset handling too. In particular, there’s a stand-alone compiler.
I know you can define your own component classes in TW, but then you've just recreated Bootstrap/Bulma/etc, but with no 3rd party components available. (Tailwind UI is just some limited copy paste code snippets last I looked.)
There are a bunch of great 3rd party components available in tailwind now. https://daisyui.com/ is one I've been using. They're usually a tad bit lower level than typical framework component libs, but the flexibility is great.
A great thing about that is they're not React-specific, Vue-specific, etc. You can use them in everything from raw html to your JS library flavor of choice.
I had to do it with a BEM codebase, and I also had to do it with tailwind. The tailwind situation was by far the easiest one. And it was because I was not afraid to remove things that could break unrelated parts of the application. Not allowing developer to hand write CSS is a great restriction for a good bunch of developers. The messes out there are unbelievable.
Yes, many times, with normal CSS. It's basically the point of cascading style sheets. Sticking to proper class names and elements makes reskinning a breeze.
The "cascading" part is what makes it incredibly complicated. Keeping the "cascade" in sync with the actual markup is not a trivial task in teams with many people of different skills levels.
Not everyone is a top 1% dev, so we need easier and safer tools so that everyone can work and maintain a codebase.
> Sticking to proper class names and elements makes reskinning a breeze.
This is more easily said than done. It's like saying "Just don't write bugs". Every single project I find that has been built with BEM and similar patches after a couple years are just a mess and their CSS becomes "append only", as there's no guarantee that removing something won't break in unexpected ways.
Sorry, but this might just mean one file-include per tag if you use tailwind-css. The in-line CSS exceeds the HTML content by sometimes an order of magnitude bloating the page HTML to ginormous size.
"We all use 'cascading sheets' now. If you're working on a CSS file longer than a couple hundred lines, properly formatted, you're not abstracting enough or it's a one off marketing thing."
It's an acceptable trade off. Nothing is perfect. In exchange you're guaranteed those changes only affect this markup, and not some other li > ul > a whatever somewhere else.
> Might as well go back to doing inline styles
No, it is not. This has been explained thousands of times anyone says "tailwind is like inline styles". You can do responsive, you're limited to a consistent subset of rules, minimal output css file, caching, etc, etc. For example, here [1] is an explanation why it is not the same, but there are thousands.
By reading your answers I deduce you've not used it yet. And this is exactly what is being discussed here. Fanatics closed inward looking people will never like it, nor anything that defies what they've been taught for years. Like religion almost. You have to try it for real to see the benefits. It is not perfect, but the net result is very positive for a lot of people as you can see from the usage statistics. Just be a bit more open minded to new tech and give it a try. At least you'll understand why it is not the same as inline styles which is a pretty basic thing you understand after 1 hour of using it.
[1] https://frontstuff.io/no-utility-classes-arent-the-same-as-i...
I agree, main point is that I think there are better tools for large codebases. We had a "no CSS" rule where we used bootstrap components and utility classes only.
then i tried learning it and it turns out that Tailwind's constraints both help my design and help with the learning curve
wrote up full thoughts in an old post https://www.swyx.io/why-tailwind
Also, I'd go so far as to say that if you're not using a component based architecture for your web app's view layer, you're creating a ton of extra work for yourself.
My take on ViewComponent: it’s what helper functions become when they grow up into proper objects. Great for larger projects, may be more infrastructure than necessary for smaller ones, adopt incrementally when they seem compelling.
Isn't this at the cost of dramatically increasing HTML size ? I have seen tailwind littered HTML increase by 2x-3x the page size with all that extra-ordinary repetition.
PS: I agree it makes CSS coding quite faster due to less typing involved when designing something thanks to succinct atomic CSS classes. I am not sure less typing is better though, especially for maintainability and performance.
It tends to make the code pretty ugly.
There are ways to improve things somewhat (moving "bundles" of classNames into properties of a local or global cssClasses object and adding those to your elements' className), but you lose the intellisense when editing classes and it often ends up feeling like the extra friction isn't worth it. Having the styles right there seems to be a key part of what makes using tailwind so productive.
We have enough decisions to make regarding design as it is, adding organization, naming, selection, and attempting to maintain a sensible hierarchy into the mix leads to a fog of decision fatigue that I didn't realize existed until I tried Tailwind and it lifted.
Same. I always said they'd pry my stylesheets from my cold dead hands. But then I tried it, and I'll never go back. I feel like it's time to let go of those last vestiges of the old "web development" paradigm, and start treating the browser as what it is; a universal VM for application development.
If I'm working with a designer rather than designing my own UIs, that they have a default color palette isn't helpful, so what do I gain from Tailwind?
EDIT: Reading some other comments, I wonder if part of the reason I don't see the utility is that I use Vue, not React. It sounds like Tailwind solves a lot of the same problems that Vue+SCSS does.
Same for spacing and font sizes if you need these standardized and haven’t done it already.
Which we always did way before tailwind was invented.
This is awesome, really glad to see things have progressed from the node-sass days. Might have to give it another look.
The native libsass is much faster. The headaches come from people trying to distribute binaries and libraries through NPM.
> npm (originally short for Node Package Manager)
Acronyms can make sense to switch case, but initialisms... en-pee-em... I guess it happens. I originally was introduced it as Node Package Manager, but I'm gonna make an effort to correct this now.
Does your tooling even support embedded Sass?! Vite does not. Our version of webpack does not.. The Cenobites would LOVE Sass; never ending performance pain.
I couldn't fathom why anyone would ever use it. And then I used it. It seriously makes CSS significantly easier to maintain, dramatically reduces your CSS build size, and is really good for teams if you're trying to use consistent CSS throughout your UIs. You also don't need to go back and forth between CSS file and HTML file.
If you're on the fence, try it out. I think it's the future of writing CSS.