I find Tailwind's claim that you can "build modern websites without ever leaving your HTML" to not be entirely correct. Instead of context switching from my `.html` to a `.scss` file, I just end up context switching to their documentation website to find the syntax they used.
It's internally inconsistent, so you can't guess what the Tailwind class name is for styling, while you can do this for CSS on the majority of properties. In Tailwind, font weights are just `font-bold` for `font-weight:bold`, while font variants drop the `font-` prefix part, and become `ordinal` instead of `font-variant-numeric:ordinal`. That's not an isolated example, it does the same with text-color versus text-decoration, and text-decoration-color adheres to neither of those systems.
It's quite close to learning an entire new styling language on top of CSS. It may be the case that putting everything into the HTML is more efficient from a productivity point of view, but I don't think Tailwind's specific implementation achieves that.
It's the minor inconsistencies that prevented me from using Tailwind on any serious projects. I've never been able to get past their choice to use text-{color} instead of font-{color}.
That isn't an inconsistency, it's an intentional choice. The color of the text is an aspect of the text, not of the font. The corresponding property in CSS is color, not font-color.
But "color" doesn't apply to just text. Changing the color of an element affects the currentColor and applies to default border colors. The property name "color" makes more sense than "text-color" imho.
Because text-{color}-{shade} is more descriptive of what the color affects. Again color is not an aspect of the font (which is the typeface plus styling like weight, size, etc.) so naming it font-{color}-{shade} would be technically incorrect. (You can argue that ignoring this technicality would result in a cleaner API, but the comment I was replying to was suggesting it was a mistake, which it isn't.)
The difference is that I can write Tailwind faster, without switching files, and in a way that's always consistent with the rest of the team. That makes it worthwhile for me.
To enjoy tailwind you have to install the vscode plugin so it will speed things up when searching for the right class.
Also watch some short tutorial to get an overview. If you don't appreciate it after this then it really isn't for you
And for those that prefer a different editor? Just saying, if a tool then pushes you into another specific tool for maximum efficiency using it, that alone gives me pause.
Someone who uses a hammer all day may very well decide to use gloves - you'll see a lot of them on construction sites - and they'll probably also opt for a hard hat and safety glasses. Consider these their plugins.
I don't think that analogy holds. If my special hammer let's you go 10x as fast as a regular one, but you need to wear special gloves because otherwise it'll cause blisters, I think I still made a good hammer, just wear the gloves!
I suspect the number of developers with zero plugins in their IDE of choice is vanishingly small.
That said, it's not needed. It's just a quality-of-life improvement, like most other IDE features. You can write a Tailwind site in Notepad, if you prefer.
Oh for sure, and devs should do what is needed to be more efficient and to make their development enjoyable. The poster I was responding to said "you have to install the vscode plugin" to enjoy using Tailwinds. So that's the specific part I was responding to.
I should have said intellisense. Without getting suggestions you do have to go to the docs a lot in the beginning and it is frustrating, but with intellisense I found myself proficient in a couple days and I was among those that din't give an opportunity to tailwind for years. I really wasted time, it works great
I work every day with web projects, and the notion "Tailwind won" in any capacity sounds like a thunder from a clear sky.
If we see more articles to that effect and this is not an outlier, it means the Tailwind cult is in its "red dwarf" stage, where the community becomes smaller, but denser and more convinced than ever that the entire world is a copy of their small bubble.
That's good, it means in a few years Tailwind will be considered a dead tech. Tech bubbles are so weird. It's like the tulip mania or the NFT craze. It all makes sense when you're in the bubble. While those outside are looking at it, and seeing what is clearly mass psychosis.
It is good because Tailwind actively fights the engineering choices behind the web platform, it doesn't understand them, it doesn't build on top of them in synergy and alignment, but it counteracts and nullifies them with religious fervor and zeal.
Tailwind projects read like the wall writings of a mad man, who is convinced they've discovered the secret of the Universe. And that secret is compiling absurdly large, GIGANTIC lists of CSS rules, trying to reinvent the concept of a "syntax" within the constraints of an identifier name, then copy-pasting them inline all over your HTML code, with great redundancy and repetition, obscuring the actual DOM, and then treeshaking the gigantic class lists, so your browser doesn't immediately crash while opening a basic homepage.
It's good because projects like Tailwind are built on marketing and emotion, they rely on ignorance and the web design equivalent of a "get rich quick" scheme that promises great results with no effort or skill, they seek to be viral, and when they succeed, engineering arguments about the merits of good design, or even basic logic cease to have any effect, and then these projects realign the rest of the community, so you see other projects "built on Tailwind", often not even for any reason other than it's cool to be built on Tailwind.
So as the bubble grows, you start also seeing jobs requiring "10 years of Tailwind experience" more and more often, the projects you rely on are starting to switch to Tailwind, and now you have to use Tailwind, like it or not, because everything is glued to Tailwind. If the bubble keeps growing, then we also see a myriad of "like Tailwind but for JavaScript", "like Tailwind, but for SQL", "like Tailwind, but for web services" and there's no end to how far it can go, because bubbles, driven by the aligned wide-eyed stupidity of millions of delusional people can grow to wrap around the entire industry, before they pop.
And when they pop, the damage and loss of value and productivity is immense. Having to redo big parts of an ecosystem, so you can scrub away all the millions icky sticky pieces of Tailwind mania off things, that is splattered on everything, and the smell is completely unbearable.
So. When the bubble of BS stops growing, and starts shrinking, without massive damage: it's good.
I'm not sure I fully agree with your view on what tailwind is and why it is growing.
In my opinion, tailwind is gaining some popularity because some people find it faster and easier to use than writing traditional CSS files.
I realise it also has some downsides, and seeing all those class names in the html is particularly ugly, but if the people using it got their project out faster, then surely there is a place for it?
Technology choices, and life's choices in general are like a spectrogram of different wavelengths with positive and negative values... Like "this will help you today, but bite you in the rear tomorrow", or "this will help you tomorrow, but be annoying today". And it also varies by different conditional developments, if this happens, if that happens, can you implement a change, or the solution is "write-only" and so on.
One of the tests of intelligence is can you defer immediate gratification, so you can reap higher rewards in time that compound themselves, or you lack impulse control and therefore you essentially have the model behavior of a house fly.
This incessant focus on "here, now, me" that I see glorified, which doesn't consider at all anything outside a point in time and space that demands the impulse to be immediately satisfied... is not a good direction for tech, or for society at all. It's like choosing porn over a family.
Obviously, I'm describing a broader problem here, not just some CSS tool, but Tailwind and many of the "frameworks" we see pushed in the industry do also embody this philosophy, quite clearly. Many things do these days. Ship faster, do less, faster, faster, faster. To what end? Are your projects so worthless, that you need to ship them today and then leave hell to yourself and others few months down the line? Not to mention that all the claims Tailwind is "faster", somehow, are written in weasel language to hide the fact Tailwind adds tangible, often significant lag and load to people's devices when they use your site. Does this matter?
Of course, a fancy experiment is all good. You won't see me writing long posts about how Brainfuck is the end of humanity. But Tailwind has a good size community that actually believes their approach is superior, they're on a mission from God, and it's become viral, dragging in more and more people in, and influencing other projects into the same stupidity. What else does it mean to write a post called "Why Tailwind won". Won what? Was there a war going on? Won over what? Bootstrap? Bootstrap is a framework. Won over CSS? It runs on CSS, it's not an "alternative to" CSS, although it sure makes it impossible to use most of the benefits of CSS in a sane way. Yay, what a win.
If Brainfuck was totally serious, and you saw your company is starting to write critical projects in Brainfuck, wouldn't that give you a serious pause?
First, the site uses some weasel language to speak about how much they're "focused on performance" in such a way as you think Tailwind is literally faster than doing normal CSS. It's not. It's a heavy approach and while you can always find edge cases to the contrary, in general it leads to pages that add lag and load to people's devices.
If you have a very simple page this doesn't matter, but as your site/business grows, it does.
Second, Tailwind obviously promotes a ton of repetition in the same way that using presentational attributes from the 90s and style="" does. This not only adds, again, burden to the CSS engine and DOM, but this "ease of copy pasting" that the author boasts about in the linked blog means you can easily end up with tons of subtle or not so subtle inconsistencies in your site's code and components, UI.
Copy pasting is easy. But there's a reason why we define classes, functions, modules, and reuse them, instead of copy-pasting our code everywhere. Copy pasting is a strategy for a quick start and a very short journey as you paste more and more variations of what you're trying to do around your site. Now change them all consistently. Oh shit, I guess... find/replace + regex? This works sometimes, but it's a deeply unserious approach to change management in an application/site at scale, and means your velocity and quality both will suffer.
I'm aware of the way to define custom classes as sort of "components" in Tailwind, but at this point... you're literally using Tailwind as you would CSS, but with a ton of indirection, gibberish, and very very unclear precedence/specificity rules.
You will also get many people complaining about compilation speed for larger sites. A problem that is quite bizarre to have for styling with a language that doesn't require compilation when you use it in a sane way (and SASS etc. are extremely fast and don't have this problem, there's even a Rust SASS parser I believe, that's even faster).
Tailwind also severely restricts your precision and expression. I probably don't have to explain the limitations of inline styles when those styles have to change from user interaction, or for different devices, and container size and so on. Tailwind makes all this extremely bizarre, if it addresses it at all. In "plain" CSS (and other more reasonable tools like SASS), it's trivial.
I would donate more upvotes to this multi-part tirade if I could.
I haven't used Tailwind, or any other CSS framework, because I have never understood why I would want to, having attended a talk about a similar system back in the day where styles were turned into weirdly specific CSS classes, as if they were trying to reinvent font tags. The way you've described it is pretty much what I would expect from such a thing.
And yet it's oddly familiar, because all of the 'MVC' frameworks that I've been forced to use and hated[1] seemed to come from the same design philosophy: Throw a bunch of shit code together, then build a cult around it so that people use it whether it makes any sense or not. Laravel's a great example of this because if you search the web for it you'll mostly get results saying that it's "elegant" and "for web artisans", but none of them can explain why it's better than...not using it. They even have some class in there called "Illuminate", which is ironically not very illuminating w.r.t. what the heck it is or does. As if writing code that actually makes any damn sense is everyone's biggest fear and the solution is to acquire a magic wand from one of the Framework Gods that does away with pesky old logic and predictability.
"What do you want to do, write everything from scratch?", your coworkers will say, as if we were making computer programs by banging rocks together before Laravel/Rails/Spring/Django/etc came along, and give you a blank stare if you try to explain that writing regular old well-factored OO/functional code is a thing you can do and that slathering culty frameworky paste all over everything doesn't make life any better or your programs any faster, even if said goo has "good documentation", by which they mean lots of activity on Stack Overflow because nobody can figure out how they're supposed to do anything without copy-pasting from some example that mysteriously worked for somebody one time.
[1] I don't remember much about the ones I didn't hate, because they did very little and stayed out of the way.
I suppose it depends if you're trying to build the perfect website, or just want to get something launched fast.
I usually build websites to solve a problem, or to try out a business idea. The structure of the HTML and whether I am using a web framework are not important to me.
The main thing is, can I get this finished and looking great in a few days.
I hear this argument a lot, on the surface it makes sense. We all want to ship fast. Right?
But then... I try to imagine how Tailwind allows you to style your site in a few days, but it'd take you, the same person, what... weeks, to style it with CSS? It's so ridiculous it's making me laugh out loud just imagining this somehow. As if CSS is this thing for rocket engineers that is way beyond a common man's grasp?
Seriously, how LOW is the bar, I don't get it? When is something as easy and basic as CSS... just easy enough? "property: value;" Or have you never given CSS a chance, and you were heavily gaslit by Tailwind marketing into thinking CSS is a scary monster and here comes the savior Tailwind? I can accept the latter, but this is also the reason why I find these fad frameworks such a harmful phenomenon. But I can't fathom the former.
Tailwind is extremely polarizing, yes like frameworks, and yes like politics. This polarization tends to happen on the two sides of "reality distortion fields", where someone's propaganda on one side, doesn't match propaganda on the other side. It's like Russians believing the West is the worst, and Putin is there to save them from The Gays. Or the West casually ignoring their impact on Russia with NATO advancing to the doorstep of an old, imperialistic, paranoid regime. What are they supposed to think?
But describing this as merely "both sides have equal merit" is really crude. Because more often than not, one side tends to be closer to the truth. Maybe Tailwind has some neat ideas. In fact I'm sure it has some neat ideas. Placed carefully somewhere in the calm eye, the dead center of this tornado of bullshit that is Tailwind overall. But then again, we can't ignore the tornado of bullshit.
This isn't correct. Tailwind removes all the cascading. And it is liberating.
All cascading styles are removed, so if you pull in a component you have already built on your site, it will be styled identically in the new location too.
"Ship faster, do less, faster, faster, faster. To what end?"
You're on hacker news, which is pretty heavily focused on startups. Startups usually have a limited runway, wherein if they don't deliver they cease to exist. That seems like a pretty reason to ship faster?
Comparing "choose a framework that saves developer time and energy" to "choose porn over your family" seems a bit much.
> So as the bubble grows, you start also seeing jobs requiring "10 years of Tailwind experience" more and more often, the projects you rely on are starting to switch to Tailwind, and now you have to use Tailwind, like it or not, because everything is glued to Tailwind. If the bubble keeps growing, then we also see a myriad of "like Tailwind but for JavaScript", "like Tailwind, but for SQL", "like Tailwind, but for web services" and there's no end to how far it can go, because bubbles, driven by the aligned wide-eyed stupidity of millions of delusional people can grow to wrap around the entire industry, before they pop.
If React dies I'll be sad. While most of React is BS, the "ReactDOM" component, the Virtual DOM model that is applied to the real DOM by "delta" diff, is a solid concept that deserved to live. Unfortunately we do tend to throw out the baby with the bathwater, when we decide something is uncool.
- Javascript evolved, so you no longer need some crazy long template to support simple sentence like class extends
- TypesScript appears, and also benefit the js eco system with d.ts files. And it even become coffeescript's short coming
- Editor evolved, the editing experience is far better than before. The time typing long keywords can mostly compensated by auto-complete
But what will be the pain point that react can't resolve, other framework can and out weight any other benefits? I don't see that as for now
> Tailwind projects read like the wall writings of a mad man
My dear pot, you should meet my friend Kettle.
Really, this is a lot of text that sums up your personal preferences as to why you don't like Tailwind. Nothing concretely objective here. And, by the way, I agree with some of it! But you're also ignoring Tailwind is used by massive, engineer-first companies (such as Stripe), and the engineers in question actually like working with Tailwind. This idea that people who use Tailwind hate it is obvious nonsense, and it's always a significant tell that someone hasn't really produced anything with it when they start claiming that about others.
Stripe is not a dude, it's a company of many people with different skills in different areas. I also often wonder how OpenAI has a team that can create the world's top AI model currently, and yet their front-end chat app and plugin model has basic injections, usability issues, accidental user information disclosures and other novice bugs, but there you go. I guess it's possible to have a company skilled in something and stupid in another.
I think my critique was sufficiently detailed, but if you like Tailwind's approach you may enjoy it coming to your language of choice, where you can code by writing very long variable names in a highly specific way, which are then read by reflection and interpreted as code.
> if you like Tailwind's approach you may enjoy it coming to your language of choice, where you can code by writing very long variable names in a highly specific way, which are then read by reflection and interpreted as code.
No need for Tailwind; in enterprisey Java land we already have Hibernate and Spring Boot for those who like long, magical method names. And if you want an extra layer of obfuscation, drop Lombok in there.
> It is good because Tailwind actively fights the engineering choices behind the web platform, it doesn't understand them, it doesn't build on top of them in synergy and alignment, but it counteracts and nullifies them with religious fervor and zeal.
Are there any CSS frameworks that are the opposite of this?
I love tailwind, and I've been writing CSS professionally since CSS2.1. I have often debated with many developer friends why it has performed so well, and this article really missed some big reasons:
1. It's works extremely well with the current component-focused UI frameworks (react, svelte, etc). Subsequently, the verboseness that is often a complaint isn't an issue at all, but a feature.
2. Does everything out of the box, and very easy to customize.
3. And, most importantly, it allows for easy art direction. Does one button need to be a slightly different size or color for this one specific element? Chuck an extra modular class on it. No need to build a complex cascasding or edge cases. (Shout out to `tailwind-merge`)
Point 3 for me speeds up production work immensely. Also, not being in JS has shrunk bundle sizes by a small amount, which is always welcome in this era.
I agree with all of your points. I am kind of shocked that I had to scroll so far down to see point #3 on this thread at all.
CSS doesn't give the best toolset in order to do styling and organize styling. The locality of HTML structure and styling makes things far easier to work with.
I would also throw in that front end coding feels far more fickle and arbitrary. Tailwind allows me to define a set of rules and then apply them directly. It ends up being more maintainable when used in conjunction with component abstractions.
1. For component usage and in this case only restricted. You can only style the top layer of a component, not each part.
But for component development, tailwind made it complex, e.g. if you want to make it possible to set / add custom styles to each sub-element.
2. Vanilla CSS too.
3. For designers with individual styling of components Tailwind is great, but not for app where elements have the same style or developed at component level.
You prefix the class with hover: or focus: etc. very powerful, although this is where a lot of people start to find it gross especially when you add breakpoints into the mix.
If css had a strong opinion and better syntax for responsiveness by screen width, css frameworks were way less popular. Tailwind, bootstrap and co. aren't used to avoid writing css. It's used because writing
`class="my-4 mb-sm-5 mb-lg-6"` is so much faster and easier then doing this with a bunch of media queries and a class name, that has to be unique, because css is a global scope nightmare.
I mean, just look at it. You have to write all this crap in css just to achieve `class="my-4 mb-sm-5 mb-lg-6"`:
This is exactly the problem. Humans write code for humans, not for tailwind specialists and bots. It should be clear and easy to read unless there is a valid reason for weird code (optimisations, hacks that don't work otherwise etc). Tailwind introduces yet another convention where it is absolutely pointless to do so.
But isn’t BEM or a custom system of CSS variables strictly worse in this regard? Instead of knowing what class=“mb-4” means in Tailwind, they now need to know what class=“news-button” means in your specific application.
These refer to customizable variables and breakpoints that everyone using the library and having done css would know and you can probably click on your IDE to get to their definition.
Personally I think that's way better than putting padding & margin in your own css classes.
It actually cuts down a lot on the custom css you need to write and also helps having a uniform design.
You're just using someone else's padding and margin classes. At least when you write your own it makes sense instead of Tailwind's alphabet soup bloat.
I already know CSS, I don't want to learn another convention. I've learned Bootstrap, Tailwind, Foundation, Tachyons, Chakra, Bourbon...at each moment in time they were to be the "last" new CSS library we'd ever use.
How many components in your application actually need the exact same layout tweaks in every use instance?
There are some properties of CSS that are more static across screen sizes. Colors, borders, backgrounds, font-size (debatable!), animations, and maybe even some high level layouts (12 column grid, etc).
The rest of CSS is minute positioning via padding, margins, and widths. Often you need to customize those details to use slightly different values dependent on context within the application itself. This is where utility classes shine.
You absolutely don't have to name everything in CSS. Naming components is sufficient. And you already need to do that. Using good HTML markup provides you with 80% of the styling hooks you need in a component. Specificity management and flexibility can be baked in too.
As for the media queries being hard/tiresome to write, don't we have IDE auto-completion for this exact purpose?
For getting designs up and running quickly, it really is great.
Being able to think "Hmmm, I want a rounded button, with a border and a blue background" and just typing class="rounded border border-blue-600 bg-blue-500" and it's done.
With lots of UI being components now, it doesn't really matter that it is verbose - I actually find that helpful. And even if you want to have a class that you use all over the place, just use @apply and create a custom class that you can use anywhere.
One place it can be hard to use, is if you have a specific design system - then yea at that point you either work with Tailwind and modify the config to match, or you just go with standard CSS - but at that point it probably makes sense.
> Being able to think "Hmmm, I want a rounded button, with a border and a blue background" and just typing class="rounded border border-blue-600 bg-blue-500" and it's done.
I'm not a frontend developer and don't really know much about these frameworks, but how is this different from just using style="actual css"? This just feels like inline styles reinvented for whatever reason.
With inline styles you can’t do media queries (e.g., so your site can look good on both phones and desktops) or pseudo selectors (e.g. :hover).
Also, though it’s lower-level than something like bootstrap, it does have a design system. Bootstrap is like building a model from a kit, plain css is like building a model from scratch, and tailwindcss is like building a model from lego.
Yes it's like inline styling, but the difference is that with Tailwind your build has just 1 CSS class with { display: flex; } used across your HTML, rather than inline styling or decoupled stylesheets with hundreds of instances of {display: flex}. If you use a framework like React, Angular, Svelte, it makes sense because your styles are usually coupled to your components anyway.
Also speaking from experience — you have to have a lot of bespoke CSS and virtually no design system / internal consistency to run into that limit (a.k.a the Movember 2013 brand refresh).
And finally, when you did run into the IE selector limit, you could just split the style sheet in two (fairly trivial if you were using Sass), because the selector limit was per stylesheet.
It's exactly the same but denser. There's no benefit that Tailwind brings that you can't get from writing your own cleaner CSS files. It's like a cult.
Styles? Doubtful. Naming components? We have to do that anyway with how JavaScript/TypeScript frameworks work these days. Tailwind is a different way of doing it that introduces unnecessary abstractions. To me, that makes it worse than writing vanilla CSS. With CSS you don't have additional dependencies and build processes. It's just CSS.
Personal choice obviously, but I work with frameworks and components if I'm doing frontend stuff, so having things as a single name for something that is consistent across everywhere I use it makes it easier for me.
CSS classes are great for that until you need to reuse HTML and/or JS, at which point you're back to square one. People are moving to components because they solve these 3 things at once.
So I still have to componentize my presentation layers to do tailwind "correctly", but instead of writing CSS in readable multiline chunks in a language every developer already knows, I need to use this cryptic one liner in any order that literally nobody can read?
What in the hell is wrong with this industry? Sometimes clever ideas aren't all that clever. Sometimes they're just dumb.
This might surprise you but most industry web development today is using components powered by a framework, and Tailwind fits in perfectly to the close coupling of styles to components.
But in components with scoped styling, you're better off just using css directly. Create a class that has all the styles you want, then use it in the HTML - nicely and cleanly separates css and HTML code.
Because they're not both style info? Html is a markup language, it applies semantic structure to your content, CSS styles html.
Classes are a tool for selecting markup to style. Sure, you can create a class for every single CSS rule you write, but just because you can doesn't mean you should.
In that case you end up with fifteen different variations of that button, class names like "button-cta__hero__overlay" and a smattering of !importants to defeat the cascade you can't chase down
I never got how is "context switching" such a problem. I mean, can't you have like, two files opened side-by-side in different IDE panels? Is it really that hard to "look jump" from one another? This justifies the amount of overhead added by a library like this?
If I can be blunt: I find this "argument" to be lazy as **. Sorry but "context switching" is just a fancy name for "having two files opened at the same time", which shouldn't be a problem, no?
PS: And almost all the other stated advantages of this approach seem to be as low value as this one considering the implied costs.
You've never had to search through multiple stylesheets and Inspect to figure out inheritance and cascading for a CSS rule that is resisting editing? I recently had to work with another developer's codebase that had four different CSS files influencing the HTML, only to find in a fifth file an !important that was mucking everything up.
If you haven't experienced costly context switching working on FE then consider yourself fortunate.
"should" is often the enemy of "speed" even when it's the _correct_ way to build a system. I think most of us here have experienced that at businesses of varying sizes.
As I said below, I don't understand how the number of team members can impede our capacity to activate source maps. Again, I may be wrong so go ahead and tell me if that's the case.
I'm not particularly interested in arguing the specifics of a solution, my point is that on a larger team especially where an individual does not get to define the approach, I'm surprised that you haven't run into issues with context switching or hunting.
But regarding one of your specifics, for example you said "the kind of help/solution that should be implemented first" before frameworks are added.
On the teams you've been on, was it easy for a developer (especially a junior) to say "Hey, we should really be implementing X, and we should have done it before I joined the team, can we restructure at this point?"
Well, I'd say yes, we welcomed and considered any proposition made by our team members, junior or not. The CTO makes the final decision. But if it's a good idea, it'll be included in the workflow, yes. Source maps would be a good example of this. And it's not hard to include in my experience, even more when considering the added value.
And, yes, I've had problems in the past with hunting rules as you say. But it's been a good long while since it happened.
Well, this is bad CSS indeed. But it does not have to be that way. A little linting with Stylelint can make sure this does not happen. As an added bonus there are less dependencies and complexity.
I suppose one of the good things that Tailwind does is it stops you having to name every element and all the different variations. So you don't end up with wrapper, container, container-thin, image-wrapper etc etc.
But you really don't have to do that. Naming components only (as you already are) really is sufficient. And yes, specificity and flexibility can easily be managed/included with CSS, particularly now, with all the new widely supported features/selectors.
These solutions to an old "problem" are lighter, simpler and easier to maintain in the long run.
If you're curious, I'll be pleased to give you more concrete examples!
Most of my HTML/CSS skills were formed when these things did not have good built-in solutions.
As someone who just wants to hack together a responsive blog that looks nice, the things that are now “simpler and easier in the long run” have not been easy or obvious to come by when looking for resources, and while I’d love a deep knowledge of CSS, the investment in time doesn’t make sense given my use case. This is why I gravitated to Tailwind - learn the conventions of the utility classes (only took a few minutes) and the rest mostly just works.
I’d love something like http://vanilla-js.com/ but for modern CSS. Something that paints a crystal clear picture about what can be done, and how to do it without bringing in $framework.
I understand this perfectly and is maybe the argument I have the most sympathy for.
And, because you are absolutely right, I'm working right now on something like what you propose.
The only way to convince people that CSS is a better (as in lighter, simpler, more efficient, etc.) solution than a framework like this, is to show and prove that it is. Arguments can only go so far...
So, as the saying goes, I'll be putting my money where my mouth is. Hehe.
It's worse than that. Tailwind imposes a ton of context switching by putting the style inline with you data. It's just that this switching happens when working on the data, instead of on the style.
Your comment was really not clear to me at all, so I think I’m missing something. Where is the context switch here?
To me, context switching is about changing what I’m currently looking at on the screen and going somewhere else to define something in some other context: a different source file, a different system, a config file, etc.
If you’re continually leaving the context of the HTML that will render your data in order to manipulate that data, that sounds like a different problem that can easily be solved by using mock data or by hooking up to a real data source. This is true regardless of CSS approach.
I think Tailwind is more accessible to many[*] less experienced or CSS-oriented developers. Big generalisation, I know, please don't yell at me, but many of us can get 99% of Tailwind's value with UI libraries supporting:
1) style encapsulation,
2) colocated presentation/content/behaviour and
3) a more minimalist mindset/habits when building UIs (e.g. relying on simpler styling hierarchies, native DOM elements, semantic HTML instead of div soup).
[*] not all, it doesn't mean that it doesn't make "senior" (whatever that means) devs more productive or that if you're using Tailwind you'll lose your 10x dev of the month badge. But, CSS is a misunderstood yet very flexible language which means it can be used or abused in a huge variety of ways.
I believe I'm convinced that if an abstraction is leaky then it's garbage.
For instance, if I really needed to know say, jvm assembler to code Java then Java would be garbage as an abstraction layer because it would simply be creating problems where they need not be.
Java however is clean, which makes it useful. I don't need to know the next level down. C is clean. JavaScript is. PHP is.
Tailwind is not. Many frameworks are not. They promise benefits but deliver complexity and programmers get invested into the system and then can't see the reality because it's a classic cult effect of giving emotional salience to a lie.
Eventually it collapses and a new one is formed.
And for some unknown reason, this. Shit. Does. Not. Stop.
It's really exhausting. Been programming nearly 30 years. So sick of it.
It would be like if I did say medicine and every 3 months or so the medical community started tripping over itself by believing in the latest weird quack with orgone energies and magnets and started writing prescriptions to their patients about chakras or astrology and then being shocked, like actually genuinely surprised when it all collapses.
Why do people run around like a bunch of frenetic teenagers to manufactured hype cycles in programming? Can we please fucking stop. Honestly.
I don't view Tailwind as an "abstraction" in the same way that you might say Java is an abstraction over the JVM. If I'm writing Java then I'm only thinking about how Java works, not about the implementation details of the JVM. But when I write Tailwind I'm still very much thinking about the underlying CSS properties. Tailwind just gives me a much more convenient way to add the CSS styles that I already know, with significant reduction to my mental overhead.
It hadn't occurred to me that people might be learning Tailwind as if it's a replacement for having to learn or understand CSS. If you treat it that way then you're bound to have a bad time, much like people who treat git as a series of commands to be memorised without any understanding of git's underlying data model.
I'll also admit that I've only ever used Tailwind on small-to-medium sized solo projects, so I don't know how it would hold up on a big team. But then the CSS has been an agonising, unmaintainable mess on every big collaborative project I've ever worked on even without Tailwind, so what is there to lose?
> But then the CSS has been an agonising, unmaintainable mess on every big collaborative project I've ever worked on
That's the other thing, tools are a really poor shortcut to competency and in practice just reflect the same level of mastery that caused the initial headache except with a different set of tools.
This isn't pure. Some things are genuinely less insane than others.
As an analogy, higher quality brushes, paint and canvases will make you a better painter but buying new brushes isn't going to be part of becoming the next Monet. Consumption isn't going to get you there.
The real competency as you point out, come at higher level coherency, which frankly takes about 5-10 years to get any good at. It's a cognitive mastery that's mostly independent of tools.
People want to seek out better tools as a proxy for the hard earned talent. It might get you further but at some point, knowing what you're doing is the only way to go.
It sucks. It's hard. It's frustrating. It's always changing and it's also unavoidable.
What's up with the colocation argument? Colocation of markup and business logic makes a lot of sense.
Colocation of presentation? Why do you even need that? Presentation is abstracted into CSS by design.
Having presentation decoupled allows you to abstract around visual elements on a page at their instead of having to sufficiently wrap everything in divs classes just to the right level to make the CSs classes work.
Your overall structure is going to be vastly different whether you use flex or grid. And if you don’t want to write overly clever CSS you’re wrapping your dt/dd pairs in divs or you put dummy elements into your sections to control where the anchor links scroll to etc. And don’t get me started on non-hierarchical layout relationships.
HTML is not flexible enough and CSS is not expressive enough for this theoretical separation to hold in practice. You would need a translation layer between pure content and layout for this to be true (like XSLT).
I never suggested decoupling html and CSS, that is always going to be coupled through selectors.
What I suggested was decoupling presentation (actual CSS rules) from structure, the blocks of html.
What I'm discussing here is if CSS rules should be inlined in html, whether through tailwind pseudo css or style tags the result is the same.
Further caveat, the article mentions that switching to a CSS file is a context switch. Put it in a style tags next to your html for all I care, colocation is great as a general rule, inlining CSS in html style attributes is not.
This is settled thinking at this point: inlining CSS results in short term benefits to productivity at the cost of long term costs due to brittle presentation that is expensive to change.
And given how low the cost of extracting reusable css classes is these days, I don't think tailwind will ever win.
Yes, it defines the structural bounds your CSS is able to manipulate. It doesn't dictate how it needs to be manipulated other than a rough idea about what things will render out in what order. (I'd hardly call that presentation)
The key point here is that CSS exists precisely because html markup isn't enough on its own to style itself. If it was, CSS wouldn't exist.
The idea that something like tailwind can come in with a bunch of fine grained CSS classes and solve this inate complexity is laughable at best and wildly unprofessional at worst.
It just shows a complete lack of understanding about what html is and isn't and why CSS even exists in the first place.
Fwiw, I get it. Tailwind is a neat shorthand script you can use to pump out trash you'll never look at again. For the rest of us doing actual work on things that we'll need to modify 6 months from now I'd much prefer something readable that I can actually have a hope of modifying even if a teammate wrote the thing.
In terms of skillset, I’m mostly a backend guy (of 20 years or so). I know my way around HTML and CSS, and I have a decent eye for design, but it’s not my primary focus.
I recently started a writing project, and found myself unhappy with choosing a standard blog theme, and decided to build my own.
For this purpose, Tailwind has been incredible. I don’t have plans to become a front end dev, and investing significant time in improving my CSS skills is not a good use of time for what will be a fairly small project. It gives me more flexibility than frameworks like Bootstrap while still offering a lot of the productivity benefits. It lets me explore concepts and ideas that I otherwise wouldn’t have the skills to play around with.
This thread reads like most $language/$framework/$os holy wars. There is an awful lot of hatred over a perceived lack of “purity”, or because of the perceived superiority of other approaches. Like most of these technology debates, the extreme binary positions really miss the value that can be found in the middle. Tailwind has been great for getting ideas out of my head to see how they look, and for staying focused on the content that I’m planning to write instead of getting stuck learning about browser edge cases.
If I start focusing more of my time on building UIs, I’ll invest more deeply in CSS.
I’m also fairly convinced that many of the negative comments filled with disgust at the resulting syntax have never tried it. After about 10 minutes, the conventions start to become obvious, and I can write visual elements mostly at the speed of thought. This is really quite enjoyable.
I’m also not suggesting it’s the right tool for every job. But the lack of nuance in much of the discussion here is pretty disappointing for the HN community.
I personally feel that the future of the (useful) web depends on more people choosing to do their own thing. Tools that lower the barrier to entry and simplify content creation will always be important.
* It removes the burden of having to come up with class names, and the mental overhead of deciding whether to create a new class or rely on the C in CSS. When writing plain vanilla CSS there's always a sense of friction and a need for careful planning (often resulting in me procrastinating it). That whole process is eliminated with Tailwind and I can just start styling the element immediately.
* The fact that you can see immediately how an element is styled. No hidden, detached or indirect styling whatsoever.
Surprised to see your comment as the only one mentioning these points. Not having to make up class names (and groups of class names – ”-container”, ”-inner”, anyone?) that are anyway only used once is the greatest liberation I’ve had in my 20+ years of web development.
For styles that are reused a lot I just create small & composable components (which are also defined by the Tailwind classes so they match distances & colors). But there are typically just a handful of these in a project.
Gray beard's 5c: Tailwind is a farce and a catastrophe.
It's as modern as the style parameter is, and it's as reusable as a moving a dirt pile from one corner to the next.
You're not learning anything valuable by learning Tailwind. Learn CSS, that will stick with you for the next 20 years.
It amuses me when a library is implemented 'with tailwind', which means it's totally useless to the people _not using tailwind_, and excruciating to clean up.
Go ahead, downvote me to hell, I'll see you in 5 years.
Let's say things how they are: Tailwind is a small catastrophe from an implementation, performance and maintenance point of views.
It got few things quite well in being a more modern bootstrap, had a stellar marketing and it's color palettes are really well done and leagues above the default material ones.
...that being said...
Tailwind's biggest pro is that it allows people that _don't_ know css that much to style stuff more consistently and easily. But that's where it ends.
Sadly there's a lot of issues when it comes to maintenance. Any small update in tailwind will break your application. !important s are shoved pretty everywhere, they will unavoidably clash, prompt you to override even more styles.
There's yet another complication with tailwind: the moment you want to do something more complex with tailwind or that it clashes with its own styles/rules you're in a bad corner where you need to know bot advanced css AND tailwind.
None of this mirrors my experience whatsoever. That’s “how things are” for me.
I know CSS very well and Tailwind is probably the largest productivity boost I’ve encountered since, I don’t know, learning vim? It’s way faster than SASS/SCSS which is itself way faster than raw CSS.
It also yields far more self-contained and more readily composable components than any other styling mechanism.
Your comment doesn’t resonate with my experience at all.
Agreed. I've been using CSS for over two decades now. The composibility, reusability, and maintainability benefits of CSS have just never materialized outside of some very tight scopes such as toy projects or single developer projects as far as I've seen. And we pay heavy costs having half of the context of whatever we're working on living in an entirely separate file (any generally multiple discrete areas within that file or even multiple files) in a way that's poorly discoverable and debuggable.
Tailwind finally throws in the towel on all of that and just brings the full functionality of CSS to inline styles and leaves reusability up to whatever framework and templating you're using on top of HTML/CSS.
When I walk into a project using Tailwind I spend way more time actually working on _the project_ and way less time looking at the browser devtools trying to disentangle and chase down the complex web of interacting styles that are somehow working on the markup. Everything I need to know is already in front of my face directly attached to whatever element it's related to.
It is another thing to learn but it's pretty darn straightforward and well documented. Coming from a solid CSS background it took in the manner of hours before it clicked in my head and I was productive. And that largely translates to whatever project I'm digging in to instead of having to spend a bunch of time learning each project's bespoke styling system.
Tailwind is way less technically elegant than CSS, but the technical elegance of CSS has always seemed more lofty and academic than anything.
Yeah it wasn't until I was reflecting and writing that comment that I realized _I don't remember the last time I had to look at CSS in the dev tools_ and how much better my life is for it.
Maybe I just suck at CSS. I mean, I've been using it for decades, but maybe I'm too stupid to actually understand it. And maybe it's the same story for everyone else I've ever worked with and that's why my experience with it has never lived up to the ideals.
... but if that's the case then at this stage of my career, with vast and varied accomplishments behind me, I think that says more about CSS than about me.
I think I'm pretty good at CSS and have been using it for maybe 15 years.
I find tailwind just makes my life easier. Sure, it's not perfect, but I really don't enjoy giving every div and container it's own unique name and hoping none of the names ever clash with my colleagues unique names etc.
Also, I came to realise that websites never strictly follow the same design rules throughout. There are always exceptions. So you are constantly creating new style classes that are slight modifications of others. And keeping this all in your head is not easy.
I know a lot of people disagree and feel like tailwind is a problem, but for me I can just concentrate on making a great site rather than worrying about how a slight change to the styles inside .container might break some obscure part of my website.
If the options are "never encounter a problem" versus "when I encounter a problem I realize that it's actually a superficial symptom of a more substantial problem someone made hours/days/weeks/months ago," I will take the former 100% of the time.
Assigning an ID to every single element means never encountering a problem? I imagine that results in everything being a special case, much of the point of CSS missed, and in this special case Tailwind might even work as it's consistent with everything being a mess.
Well it certainly means never encountering odd and complex style cascades, but Tailwind avoids that problem altogether without requiring IDs for everything.
This is where I wish we still have upvote numbers on HN. How many people agree with you vs parent and grandparent comment?
I've been doing web dev since I was a kid in mid 2000's and I think tailwind is phenomenal in enforcing style, portability, speed, etc. I recently started to writing a single .html file proof of concept for something and it was shocking how poor the experience is of `style="..."` is in comparison, or making up classes as you go.
My experience mirrors yours 100%. What the parent comments seem to be describing are Tailwind in a context where people don’t know CSS that well. Yes, that will be a catastrophe. But so will SASS or vanilla CSS — even more so. Tailwind is a utility, not a replacement for fundamental knowledge.
There are tons of people who are perfectly proficient in CSS who are not won over to utility classes. As you become more won over, you start writing files full of utility classes that… wait for it… someone else has already written! With huge coverage over CSS! And really good defaults! And lots of escape hatches!
And to top it off, nothing guarantees your colleagues are actually going to use those instead of creating their own ad hoc “semantic CSS” or whatever their preference is.
If you decide you’re a utility-only frontend, then… there’s a great tool for that!
So now why on earth are you still plugging away at that utils.css?
And people that know (Python|Ruby|PHP|Go|Etc) don't need the framework to implement a web app, yet we use them anyway.
What is the value of reimplementing a bunch of this if it already exists? What's the value of having every developer learn some poorly-documented in-house system when we can use one that's already out there with full documentation, examples, references on StackOverflow, etc?
As a programmer that likes to paint, I think the difference is that web pages are a visually artistic medium. Artists that have unique fine detailed visions often feel the need to use low levels tools to perfectly achieve those visions. I guess this this applies more to individuals than teams however.
I've been writing CSS since 2009 and I love Tailwind. It allows me to very quickly build UI that has a consistent look and feel without having to stop and think.
Yeah, I wrote CSS without Tailwind for 15 years. I don’t need it. I’m just 10x more productive with it. If you don’t want to learn new things that’s fine.
I was resistant to Tailwind for a long time, and recently I decided to try it on a recent project. IMO it lives up to its reputation and has changed the game for me.
The biggest pro for Tailwind is that it is exceptionally well designed. Aside from adding one single custom style to the Tailwind configuration, I have not needed to venture outside of the system it provides despite writing many bespoke components.
Could you explain the performance problem ? I understand how you could get to the other claims, even if i disagree.
But i sincerely do not understand the performance one. If anything tailwind approach is mostly really good for performance, as rendering utility class directly on the element is still the fastest, by far, technique.
The only slight call here could be shadow dom scoped but that necessitate declarative shadow dom and create a lot of problem for performance until we get a fetch maps equivalent to import maps.
You haven't missed anything. I swear, every time I read a thread on here about Tailwind I feel like I'm taking crazy pills. So far I've heard:
1. Tailwind allows you to not learn CSS (not even remotely true)
2. Tailwind is hard to move away from (what?!)
3. Tailwind has performance issues (lol)
>> Tailwind's biggest pro is that it allows people that _don't_ know css that much to style stuff more consistently and easily. But that's where it ends.
I'm considering advocating for a move to TW at work. Most of the devs _don't_ know CSS well enough to style stuff consistently and easily. We have very complicated cascades, and sibling style imports, and "semantic" class names.
Sure, maybe the answer is "level up your teams' CSS expertise." But I'm looking for something more pragmatic than that. I don't know if TW is ultimately the right tool I'm looking for, but the underlying ideas it uses are very appealing for this use case.
Try Tailwind. I was a complete hater before I sat down and committed to one week project with it and I am frankly ashamed at how off my assessment was prior to using it.
I think Tailwind could be made good for usage at enterprise scale, for example, as a customisable foundation for a branded design system.
If for example Figma offered first-class support for Tailwind-like utility classes in the form of a modernised "styles" or "composite tokens" feature, then mapping from a design system to Tailwind-based code could be pretty simple.
But right now, it's anything but. In my experience, designers simply aren't aware of the Tailwind structure, and it's hell trying to map their mental model onto Tailwind. Figma is built to design things that map easily to CSS at the attribute level, not the class level.
One of the things that tailwind achieves is let you ship style in a way that is encapsulated within components and works reliably across any framework (including server-side rendering frameworks, react, svelte etc).
> Tailwind's biggest pro is that it allows people that _don't_ know css that much to style stuff more consistently and easily
I have never understood this claim. You need a good understanding of CSS to use Tailwind effectively because it is CSS.
It’s not an alternative technology, it’s essentially just an alternative syntax—one that naturally leads away from footguns that many teams end up battling, like fragile CSS that everyone is scared to change.
You could just as easily define the utility classes yourself every time you need one, it’d just be a lot more work.
Tailwind is a pretty good framework for people who want to practice atomic CSS easily, and it is a bad framework for anyone trying to avoid that pattern.
The pros and cons of atomic CSS can then be argued about elsewhere.
You're not learning anything valuable by learning Tailwind. Learn CSS, that will stick with you for the next 20 years.
You can't use Tailwind without knowing (quite a lot of) CSS. There's nothing in Tailwind that makes CSS easier or that obfuscates the technical understanding you need to make things with CSS. If you want to make a horizontal flexbox layout knowing "display: flex; flex-direction: row; flex-wrap: wrap;" or "flex flex-row flex-wrap" are functionally identical. You need to know what either the CSS or the Tailwind classes are doing to use them, and there's a one-to-one mapping between them. If you learn one then you know both. It's literally just a shorthand notation, or in a few places the equivalent of a macro.
I don't imagine Tailwind is going to last another 20 years, but I do believe that people will use 'utility first' CSS libraries like it from now on. No one is going back to writing plain CSS unless they have no choice. CSS is becoming increasingly capable, and with that increasing complicated. People choose Tailwind because it affords you all the power of CSS with a somewhat less arcane syntax. Why would anyone stop using that?
I do have a caveat though: I actually think Tailwind is the CSS equivalent of jQuery. In 5 years or so a browser is going to add a Tailwind style notation to its engine, and people will be able to use it without needing an external library. In that sense, yes, Tailwind will die, because browser developers will see the benefit is so significant that they'll adopt it as well.
Except when using Tailwind, you're learning Tailwind nomenclature and syntax and approach - which really isn't modern CSS, at all.
Today's CSS - if anyone would take the time to actually learn it as they do JavaScript - doesn't need something like Tailwind to make it powerful, scalable and manageable.
I write plain CSS today, which is then scoped to components or bundles of interactivity, and all of those point to major, top-level control sheets that help determine the mode (light/dark/high contrast) and the theme. We tweak small changes up high to effect large platform changes throughout, saving time, energy and headache of the hunt/peck exercise.
I don't understand the statement "no one is going back to writing plain CSS" because plain CSS today _is complex_. It is a beast. But it is still "plain" CSS. Yes, it has evolved, it has grown, and it meets today's modern needs with excellent results.
CSS nesting is coming up soon: https://caniuse.com/css-nesting That will more than likely allow me to migrate any projects I have with Sass still in play, to remove Sass. One more dependency removed. Done.
So there's really no need for Tailwind if you know how to build with modern CSS - with the one caveat that if a project _already_ has Tailwind in it, it is a bear to work with/alongside.
That to me is the biggest con with Tailwind: it gets in your way when you don't need it.
I write plain CSS today, which is then scoped to components or bundles of interactivity, and all of those point to major, top-level control sheets that help determine the mode (light/dark/high contrast) and the theme. We tweak small changes up high to effect large platform changes throughout, saving time, energy and headache of the hunt/peck exercise.
I do similar things with Tailwind, making global changes by updating a config file instead of a base CSS file. It's not hard and it works well. To be honest, it's not something that really comes up very often. I don't see this as a particular advantage of Tailwind or CSS. I care much more about the day-to-day dev experience.
Prior to using Tailwind I spent about 20 years trying every system you can imagine to manage styles across large websites/apps. I still use the skills I learned when Tailwind doesn't cover an edge case I need. It's fine. Before that I spent about 5 years doing the same with tables and font tags (Adobe Pagemill was awesome). Of all the systems I've used, Tailwind is the easiest to keep neat and tidy. Maybe I'm a terrible dev and other people find CSS really easy to manage, but having spent two decades talking about it with other frontend engineers I'm reasonably certain that's not a common skill. Tailwind makes life much easier for most people.
One more thing I find baffling is the preference to ignore the cascade… and seeing it as a benefit.
The cascade is where the value of CSS comes from! It’s an incredibly powerful concept.
I use and love the Inverted Triangle CSS (ITCSS) approach and write a fraction of the CSS code I used to.
Having a few utility classes, using variables for project-specific colors, breakpoints, spacing, using fluid typography, grid, and flexbox, make writing well-structured minimal CSS code a pleasure.
One more thing I find baffling is the preference to ignore the cascade… and seeing it as a benefit.
Tailwind styles cascade just like any other CSS rules. No one is ignoring it. The reason it might appear not to is because Tailwind uses layers (https://developer.mozilla.org/en-US/docs/Web/CSS/@layer). Technically it's a polyfill at the moment, but v4 will use the native @layer syntax.
If anything Tailwind is actually better at using the cascade than most plain CSS approaches.
Cool hot-take but it’s not true. You’re literally learning CSS when you learn tailwind. And no one (good) picks up a tool solely because it’s shiny, they pick it up because they find it has utility, which evidently LOTS of people do.
And if you don’t think it’s reusable then you at least need to bring an argument for why that’s so because the docs, personal anecdote, and the opinion of LOTS of people is completely opposite.
So:
- You ARE learning CSS, you’re just putting it where it belongs: on the element it affects
- It’s modernity doesn’t matter at all
- It’s literally as reusable as raw CSS
I can’t downvote you, but you’re definitely wrong.
> And no one (good) picks up a tool solely because it’s shiny
The amount of cargo culting going on right now is at an all time high. People do stuff all the time that makes no goddamned sense and is defended by, “well Google is doing it!” You are not Google and you never will be.
>The amount of cargo culting going on right now is at an all time high.
In fairness, CSS is such a mishmash of things that it lends itself to cargo-culting.
You can fit the number of people who are exclusively CSS experts in a van and still have room for their luggage. Everybody else is going "that's cool, how do I do that?" and then copy/pasting it.
I mean, hell, it was years before you could reliably vertically center stuff with CSS (that we were doing with table-based layouts since the 90s). And considering the number of wonky layouts I've seen in what should be professionally done mobile Web sites, it's clear that it's hardly a Done Thing.
The nerd in me really likes SCSS, because I can more or less wrap my mind around it, but I get the Tailwind way as well. As a developer, CSS is way down my list of things to know intimately. Whatever I have to do to keep things moving, I'm good with it.
I vehemently disagree. When you're using tailwind, you're learning Tailwind, which is using CSS in absolutely the unequivocally anti-CSS way.
CSS was meant to cascade; it's what the damn 'C' stands for, and if you cannot understand the efficiency of the cascade, at scale, you are most definitely missing the entire point of CSS.
I have personally built ui libraries for boutique firms and enterprise (Apple) firms and guess what we did _not_ use in any of those instances? Tailwind. Because it's an utter toddler to manage and very definitely not efficient in its application.
There's a strong contingent of developers who would argue that the global-by-default aspect of CSS was a mistake. Hence nested selectors in Sass/SCSS, CSS modules, and so on.
Styles applied by Tailwind classes cascade. The library just makes it (intentionally) difficult to define a class that will easily collide with others.
Actually, the "C" in CSS stands for "Mistake". Cascading styles are not a good idea, and Tailwind encourages using styles in a way that makes sense for a component-first web.
If you want to cascade all your styles all the way down, by all means go for it. However, I aim for readable / scalable styles rather than dogmatically "cascading" everything just because it's in the name.
Yeah, I always describe tailwind as a lightweight classname-based abstraction over native css rules. It's a _good_ abstraction because it doesn't obfuscate the actual css rules; you're still wielding css when you use it. Colocating styles with components using short hand for css rules is brilliant and now that I've tasted it, I'm averse to our tradition of hiding things behind a bunch of subjective class names in a different file. Not too mention the optimization of removing unused styles based on the classnames used. Tailwind is good
This is not true. There's no way to create a "non-cascading style rule" unless the style rule already doesn't cascade. You still have to understand the cascade in order to use Tailwind.
> You still have to understand the cascade in order to use Tailwind.
Can you expand? I haven't used Tailwind, but from looking at the docs, it looks like a short-hand syntax for writing inline styles. Not exactly the same since it can take advantage of media queries and other things that you can't do with inline styles, but close enough conceptually.
Where is the cascade with Tailwind? Perhaps I completely misunderstood how it works, but I would say that it feels like it's purposefully trying kill cascading.
I mean, the top just happens because color has 'inherit' by default. The latter is specificity, and normally what I think of when I hear "cascading". But, it turns out that isn't cascading either [0].
Cascading refers to the order stylesheets have priority when loaded by the browser. Going to have to update my definitions for the future. I always thought cascading referred to how specificity worked.
Edit: no wait, specificity is part of cascading, cascading refers to the entire process of determining which style applies, including specificity. Inheritance on the other hand is not part of cascading. My definitions were right, don't need to relearn anything.
In truth everything mentioned above is part of the overall cascade. CSS takes almost everything into account - stylesheet ordering, rule ordering, rule specificity, etc.
You're not the first person to mention that, to which I counter: Cascading is a mistake in today's component-first web. It works at a very small scale, and _sure_ some things should be cascaded—which Tailwind absolutely lets you do. But 80% of your styles are going to end up scoped to their component—so you might as well use a tool that leverages that concept to its fullest extent.
All my "hard opinions" aside, I have anecdote that no amount of facts can change—I build things faster, more maintainably, that look BETTER than anything I did before Tailwind. Until those pillars stop being true—Tailwind will have my heart.
the cascade has as many benefits as it has drawbacks, few people like to juggle specificities.
IMHO the only important application of the cascade is in its original purpose: custom user defined stylesheets (today often via browser extension or adblockers), but you can add proper descriptive attributes to your markup for them.
In today's uses, cascade _with_ custom properties (the vars defined within :root ) are powerful and are what I leverage when providing theme-able ui libraries. Dark mode, light mode, large mode can all be solved using custom properties which to me most exemplify the power of the cascade.
that is inheritance not the cascade: Inheritance allows for DOM nodes to use properties set on their ancestors, the cascade algorithm is how multiple conflicting rules interact and are overwritten.
Custom properties are by default inherited by all descendant nodes (they also interact with the cascade, but it is less relevant) and this can be used with tailwind in a couple of different ways: https://stackoverflow.com/questions/64872861/how-to-use-css-...
This has been my general opinion on Tailwinds all along. When it first came out I thought it was kinda harmless, it's basically like some of the utility classes that always inevitably get made/used and that's great.
But this idea that all styling should be done in HTML is antithetical to the whole reason CSS came to be in the first place, IMO. I can see why people like it to an extent, but I just don't really get the arguments that switching files to write CSS is "context switching" that makes things harder. If you need to see both your HTML and CSS at the same time then get a bigger monitor (mostly kidding).
I just still see that well crafted HTML and CSS work together, make sense, and especially with all the new tools available in CSS, just isn't that hard to get right. Well structured HTML is the biggest pain point I see for those that struggle against CSS. Learn that, the cascade, learn how to encapsulate styles (there are plenty of good patterns) and it will flow just fine.
I stayed away from Tailwind for the exact reasons you described until i joined a company that used it heavily and now I really see the value of it. I’m weary of new tools and cargo cult but Tailwind won me over.
It really shines for apps that are changing rapidly and are at risk for generating dead CSS, which has been a problem in pretty much every commercial codebase I’ve ever worked on. Tailwind adds a simple, straightforward, one-way-to-do-things approach that creates a much more maintainable experience in HTML templates that results in zero dead CSS code.
It’s absolutely not for people that need fine-tuned CSS APIs like animations, etc. But for building a product rapidly, it’s become a go-to for me.
I get the challenge of dead CSS, I think there are strategies for managing that in complex apps without "ditching" CSS. And my understanding of Tailwinds is that it starts to break down for larger/complex apps also (but I've only used it on smaller things personally so that's just based on things I've read).
I never try to be dogmatic about new things - so I'd try it again. I just haven't seen the benefits yet myself and so default to the cons I expressed earlier.
True, but those usually involve adding some sort of linter to ensure that your style sheets are clean, which is an additional build step, which is an opportunity for a build to fail. Tailwind gives me this out of the box and doesn’t require any sort of manual lifting because it does this automatically.
> Tailwind starts to break down for larger/complex apps also
This hasn’t been the case for us, I’m on a team of about 50 devs contributing to a 2 year old monolith and Tailwind hasn’t once gotten in my way.
Thanks for the data point re: larger apps. Like I said, haven't had that experience with Tailwinds specifically so I can only go by the various things I read about those who have. I'm sure it's like any other tool - it can be used or abused.
Styles get stupid when they're not local, it just creates a huge hassle as projects scale. The only answer is a css file per component, or css embedded within the component directly. This css has to have a preprocessor or you won't be able to maintain a functional design system or any stylistic consistency. So you're stuck with sass/less/tailwind regardless.
Style classes are IMO the neatest way to inject styles, having elements get styles based on html structure makes code brittle and hard to reason about. If you need an example of this try playing with bootstrap forms.
I actually agree with most of your comment. Just not that Tailwinds is the best way to actually do the styling. I don't have any issue having some form of compilation/processor step that takes colocated CSS and creates a final output, that isn't my objection to Tailwinds, in case that wasn't clear in my original comment. I prefer to actually use CSS, most often via style classes.
And I did not say to base styles on html structure - you are correct, that is brittle and actually one of the things I often ask about in FE interviews as a way of determining skill level. I said that good html structure makes CSS much easier, if your structure is bad, it can significantly compound the amount of CSS needed in order to achieve the desired outcome. So I believe there is a significant distinction in those two statements.
@layer has made all this much easier using raw CSS. One creates sensible global defaults in a `@default {...}` layer, and then they overwrite in a `@custom {...}` layer.
I’ve studied and used CSS for 17 years. I’ve always enjoyed it and rarely complained. But tailwind is a joy to use and I prefer it over writing CSS.
There’s no replacement for understanding the underlying technologies of frameworks, that’s true. Compared to some frameworks, tailwind is only a small layer of abstraction, one that does not obfuscate the underlying tech away. It does not prevent you from learning or using CSS. That’s why it’s so good.
I frequently drop tailwind into projects because I know the shipped code footprint is low and it accelerates design.
Even grayer beard's 5c (well, I'm still under 40, but still):
You could not pay me enough to learn CSS. Every time I have to debug CSS there go many valuable hours of my life. With an insane amount of trial and error and judicious use of Chrome's dev tools I can usually hack some garbage together, until the next time I have to figure out how to remove the background of a button.
In the literal 90s I was building fully-featured GUI programs by dragging and dropping buttons and text boxes and inputs onto windows with Visual Basic, and the window resized nicely. Thirty years later I have to do the same thing with gazillions of arcane style sheets. It's a disaster. How did it get this way?
I'm 50 and spent most of the 90s building Windows GUI apps. I think you misremember it. As a general rule dialogs (especially the ones built with dialog builders) were static with fixed pixels sizes; double the screen resolution and the dialogs were half-size. Layouts were extremely static; even Java AWT's primitive flow layouts were almost revolutionary by comparison to what was available in MFC et al.
Modern web design is a mess, yes, but it's vastly more sophisticated than what was available in the 90s and I would not choose to go back.
It’s called “progress” apparently, and older gray beards complained about it when we reinvented the mainframe through the same methodology.
For all of the re-use that us computer folks talk about, we surely reinvent the wheel an awful lot. I’m guessing that we have some sort of stubborn creative streak that causes it all. That’s my excuse at least.
Users were enamored by custom drawn UIs, so designers started demanding custom drawn UIs instead of native widgets. Most users don't understand what they lost and now pawing at interfaces to discover how they work is the new norm.
Don't forget that every few years, some new styling standard comes out. Forget tables, everything is floating divs. Forget floating divs, it's flexbox now. Forget flexbox, we're using columns.
I’ve learned CSS, used Bootstrap, and tried a bunch of other tools. Tailwind ecosystem is the fast approach to building web UIs in my experience. It doesn’t matter if you know CSS or not. Nobody gains if you know CSS per se. People gain when you deliver finished projects. Tailwind helps ship projects faster.
You all fight, but nobody says what exactly they develop. A webpage and Tailwind is absolutely fun. An app with reusable complex components, Tailwind is a pain. Themes, dynamic tailwind is a pain, static, tailwind is ok.
There are endless possibilities. The problem is, that some people think you can use Tailwind for everything and then they made simple things unnecessary complicated.
I disagree 100% with that. I much prefer using Tailwind for complex apps with reusable components. Because then you don't have a lot of repetition, redundancy is as much as BEM.
For static webpages (unless it is assembled by a static blog engine or something), I don't particularly enjoy it, because of the repetition.
With components+Tailwind you have as much duplication as you'd have with pure BEM.
Not my experience. We built a full rather complex and feature full application using Tailwind. How? Reusable components (we use Vue, but that’s just one option).
I remember this being endorsed approached by Tailwind creator.
As a user of web sites, this attitude leads to me paying for your fast shipping in electricity for CPU usage, extra money for extra RAM, plus wear and tear on my nerves because you do what your library allows you to do instead of something usable.
Tailwind is not a performance hit, anyone who knows how it works knows that. Maybe stop throwing random accusations you can’t back up… it’s such low quality commenting.
Edit for the downvoters who don’t know how it works: there’s zero js being run at runtime, it’s a pure css framework that generates as-minimal-as-possible css files. And it’s not class lookups that cause whatever issues parent comment is talking about.
No of course I don't. And due to javascript's reputation, I assumed. Because what I said IS generally true for the js bubble.
The sad part is i don't even feel guilty for assuming, because this area of programming has a well deserved reputation.
Even if this thing doesn't use javascript, can you guarantee the generated CSS doesn't put the browser's layout engine in an infinite loop or something? Especially without knowing CSS, like the OP suggested it's normal?
> can you guarantee the generated CSS doesn't put the browser's layout engine in an infinite loop or something?
the way TW aproximatively works is to collect a set of used class names from your code (e.g. flex, min-h-screen, bg-[url(/img/grid.svg)], absolute, etc.) and produce the CSS for those classes.
I believe that CSS performance is mostly dominated by size in bytes of the stylesheet, number of properties, complexity of selectors, and frequency of updates. I suspect that TW improves most of these metrics in exchange of bigger html class attributes.
Developers gain if they know CSS. Just like JavaScript - for either, if you understand the underlying base technology, it doesn't matter what framework you are presented with, you can learn the specifics of that framework fairly quickly, in my experience.
I've been using CSS since 1997. CSS was basically a shit show for its first 20 years thanks to all the slightly differing browser implementations. I will tell you, that is what stuck with me.
Tailwind is a massive improvement in terms of maintainability across teams and tooling. Thanks to Tailwind my team hasn't had to think about CSS resets and browser shims for over 5 years now, and any bugs where an application looks different in a particular browser can be forwarded to a team who will fix it, instead of us having to maintain an ever-growing pile of special rules and feature detection code.
There is, of course, no silver bullet, but for a team building applications from components with React or Vue, Tailwind is a maintainability dream compared to stylesheets, and easier to train new devs on too.
Except if you bundle your styling with the component, like you should be doing with React or Vue, and you have two _maybe_ three over-arching foundational style directives being implemented across your build, you do not need Tailwind.
I believe both React and Vue have the capability to scope your CSS along with the components. Modular CSS has been much easier to maintain over years than fixing when Tailwind updates or finding (again) that one !important that happens to conflict with a new released component set.
I save my teams time and money by applying CSS in the manner that it should be; which means not as an inline style mechanic.
> I believe both React and Vue have the capability to scope your CSS along with the components.
While that's true, it also means you need to propagate all of your exceptions for support of old browsers. And you still need a ton of global styles so your application can be re-themed or white-labeled according to your customer specifications. And god forbid someone applies a color directly in a component and you have to grep the codebase looking for the errant code.
After 5 years of tailwind on several complex applications, I can say that it's been easier to maintain, especially as engineers come and go, than any of the applications I worked on before. Frankly, every company I've ever worked for wound up with something like their own bespoke tailwind anyway, but instead of having it well-documented, every new hire had to learn whatever naming system whoever wrote the global design styles decided on.
> I believe both React and Vue have the capability to scope your CSS along with the components. Modular CSS has been much easier to maintain over years than fixing when Tailwind updates or finding (again) that one !important that happens to conflict with a new released component set.
In my experience that's empirically false. Maybe if you only care about Chrome, but CSS is hell to maintain when you need to keep support for browsers like pre-blink Edge.
Agree 100%. CSS is so good nowadays. Tailwind is yet another over-engineered hack of a framework foisted upon us. A solution looking for a problem.
You don't need it. Do devs these days even know about Web Components and shadow DOM? You can define per-component styles now with CSS selectors to target any child elements within the component and you can do it in such a way that the styles are contained within the component... And for cases where you want to inherit styles, you can just use the regular light DOM.
All these frameworks are re-inventing the wheel and making it worse.
It's like having a perfectly good car and then attaching a horse at the front to pull it because you don't want to learn how the car works...
Web components are a decade old, what do you think has changed or will change to make them more popular than frameworks?
I think unless there are massive improvements to the developer experience the best hope for web components is as an implementation detail for a higher-level framework.
Good question. I probably should have qualified my statement. I can think of a lot of cases where an organization is better off building custom components on something like Lit (close to bare metal), rather than trying to shoehorn Angular or React into what you want. On the other hand, having a lot of predefined pieces and methods is also helpful to some people.
For me, I've been bitten and I would pick web components over a fixed framework for a clean sheet project. I don't think many devs have really tried to work with web components or they might get the bug, too!
PS: I wrote an intro series on this topic on Medium[0].
I also think not many devs have tried to work with web components and that likely explains its current lack of popularity. Many mid-level devs are not even aware of its existence or they mistakenly think of it as some low-level tech meant only for framework engineers or deep system engineering type people.
That said, having taught some introductory web development courses in the past few years, I sense that new devs entering the industry are interested in simpler solutions and not particularly keen to get into React. The React learning curve is much steeper than it once was now that it has so meany features and the benefits are not so clear to someone who is starting from scratch.
Web technologies like this take hold because they make producing something more attainable to a wider group of people. Who cares if it's "worse".
I'm a backend developer, who works mostly in python. I'm probably never going to learn CSS but I can produce a user interface that looks like I'm competent by copy-pasting tailwind divs. In 5 years, I'll hire someone who knows CSS to fix it. It'll be cheap because webflow and squarespace are allowing graphic designers to build websites, which is squeezing the demand for CSS as a skill.
I second this as a backend python dev. I’m adopting tailwind for my latest project because I don’t need to learn the intricacies of front end styling. I really care so very minimally about it, and respectfully do not think anyone is going to need to be CSS masters in 20 years. If there’s any area where LLMs show promise to write reasonably responsible code, it’s front end styling. And that is coming from a huge skeptic of LLMs.
I've been building websites since they were invented and I agree completely. CSS itself has evolved to the point where you are worse off if you use a pre-compiler or alternative.
In one sense, it was always worse to use Tailwind because if you don't learn "real" CSS you won't be able to fix anything that's broken -- and with CSS, there's always a lot that's broken.
Bootstrap and its newer counterpart Tailwind have been around collectively longer than a decade, and I can't see any reason why their popularity would die down. It's easier to learn, quicker to write, and reduces a lot of issues that arise from poor CSS. I can see why some people aren't a fan, but those people seem (from my perspective) to be either luddites or people who misunderstand Tailwind. When you have people across the entire spectrum of experience who find writing styles faster with Tailwind, I can't understand how people find themselves on the opposite side of the argument without having some underlying bias or no practical experience utilizing Tailwind.
Why should anyone care about adding third party tech?
This argument boils down to: “But you don’t need Tailwind for that. You can do more work for a (almost certainly) worse result with a designsystem.css!” Sure you can! Why?
If you really want to, you can even use Tailwind's naming for you language file. The thing is, you add complexity to do a job that could be done in the same way without adding complexity and dependencies.
Shouldn't we try to justify added complexity through added value?
Because most frontend engineers cannot make something as visually appealing as Tailwind’s defaults and most designers cannot make frontend abstractions as ergonomic as Tailwind’s.
Now it seems like you’re suggesting just reimplementing Tailwind? Or yes you can have one of your FE engineers and one designer try to dream up your own Tailwind but again: why? Now you’re consuming two people for something that can be achieved by literally zero people and “yarn add tailwind.”
It is not at all my objective to “reduce complexity” that sits behind good abstractions. My goal is to ship product and to put as much complexity as possible behind good abstractions and ideally out of my team’s maintenance burden and Tailwind helps achieve all of those.
Sure, if Tailwind provided literally zero value I would say you shouldn’t add it to the codebase. But it provides a huge amount of time-value (the best kind!) in my experience, so “there’s a package from the internet” is hardly a consideration whatsoever.
If the Tailind defaults are used in a design language file, wouldn't it be simpler? If it's only a problem of "aesthetics", 20 minutes is enough to use Tailwind's defaults in pure CSS. No need for calling a designer here either.
Side benefits include that there is then no need to update any dependencies or library, no need to run a JIT server, no need for a new syntax, no need to wait for implementation of new CSS features, better performance possibilities, etc.
Just checking that I understand your suggestion: it’s that you copy/paste Tailwind into a file called “designsystem.css” and then say that you are not using Tailwind?
Or are you saying take their design system and use your own syntax for it (so it’s less complete than TW, less well-documented, and less transferable to/from the vast resources of the internet centered around TW)?
Sure now do the same for: whitespace (margins and padding), border radiuses, shadows, opacities, font sizes, font weights, and continue playing whack-a-mole as you run into new cases.
Or just use the extremely complete, well-considered, well-defaulted, well-documented, well-supported, always-improving set of classes that took you zero hours of initial setup and will cost you zero hours of maintenance outside of your own use/application until the end of time. And it has a name so when a new engineer joins your team, you can say "we use Tailwind, go to tailwindcss.com" and they are fully read into your setup in about 15 seconds.
And the IDE will help you autocomplete it all. The same is true for all the other properties you enumerated. If it's a Tailwind design token, it can be a pure CSS design token. No "whack-a-mole" needed here.
Still, you're right about having documentation. And there has been a loooot of these kinds of doc (BEM, SMACSS, ITCSS, etc.) in the last 15 years. Nonetheless, a more modern-oriented one is indeed needed. And that's why I'm working on something like this.
As for the "15 seconds", I mean, really? If so, I beg to disagree. There is a lot to take in. And that is why numerous colleagues still have to open the Tailwind docs to know how to write a class that's not 1:1 CSS.
And lucky you if you haven't had any update and dependency issues in the medium to long term. But I know we had.
> Or just use the extremely complete, well-considered, well-defaulted, well-documented, well-supported, always-improving set "of CSS features".
The sentence above is every bit as true as yours. Add a beautiful design language and you are in business.
> 20 minutes is enough to use Tailwind's defaults in pure CSS
not 20 minutes, more. Plus all the boilerplate around @media rules
> no need to wait for implementation of new CSS features
What CSS features are you waiting for with Tailwind?
> better performance possibilities
It's very hard to beat Tailwind's performance since it's a fixed set of css classes (and a very small set in production, since it only includes classes you actually use".
Any IDE can autocomplete 90% of any media query. And, on a sidenote, I was only talking about using Tailwind's default aesthetics in pure CSS, here. That's what the 20 minutes refers to. And I think it was a conservative estimate.
As for features, it took months before grid was included in Tailwind. New powerful and useful selectors aren't there. It took years for Tailwind to support "group hovers". And I can give even more examples if you're still not convinced. Or you can have a look at the changelog.
As for performance, can Tailwind split its compiled CSS so that only rules used in the displayed components are loaded? And that's not even considering the weight difference between the "tailwinded" HTML and the one needed to support pure CSS. These things matter if performance is a goal (as it should be).
If I'm missing something, go ahead and tell me, I'll be reading with great interest!
:root {
--gap-default: 2rem;
--gap-large: 4rem;
... 30-40 more vars ...
}
.component1 {
margin: var(--gap-default);
padding: 0 var(--gap-large);
... more styles like this ...
}
@media (min-width: 640px) {
.component1 {
padding: 0 var(--gap-default);
}
}
@media (min-width: 768px) {
.component1 {
... other overrides
}
}
/* potentially repeat for other breakpoints ...*/
/* repeat for all components */
/* repeat for some internals of some components */
> As for performance, can Tailwind split its compiled CSS so that only rules used in the displayed components are loaded?
Tradeoffs.
Most existing solutions can't even detect duplicated CSS. So if your existing component already has `width: var(--some-var)`, and you load a different component with the same style... You will still load that style hidden in a different (often auto-generated unique) class name.
Meanwhile with Tailwind has a fixed number of classes that apply to all components equally.
So, if you have a complex app with multiple component variations, of course you'll need to split your CSS and only load relevant CSS for displayed components. Because your CSS grows with the amount of variations, and each of those variations becomes its own unique class.
For Tailwind though that growth slows almost immediately because... it's just a fixed set of classes.
In your code example, all that is in :root should be used from project to project. As it is Tailwind. Only values should change. Again, same as Tailwind. So I don't really see a problem.
For .component1, you would do the same in Tailwind albeit with fewer characters but as I said, your IDE should pick up the slack here.
mb<tab> --gap<tab> and it is done.
As for your duplicate width problem, it can be solved easily with a linter that prevents styling across files. I'll give you an example if you're interested. At the same time, you would be repeating "width" across components in Tailwind too.
So the duplication still exists, if I understand correctly. Same with the growth of CSS... In Tailwind you grow the HTML instead. Fixed clases or not. I don't see how it is better but, again, maybe I'm missing something.
As for the media queries, same as above: your IDE should pick up the slack.
BUT!
The thing is that by writing modern CSS, you would not need most of these media queries! Do you know "clamp()[1]"? It's magical
And unfortunately not supported in Tailwind at the moment
the above will do what you want without media queries! clamp() solves a loooot of these use cases. Honestly I don't write much media queries anymore and yes, that's great.
And if I may, I think Tailwind here prevents you from thinking about better and simpler solutions like this one. If it ain't included in what you're using, it's normal to not think about it. But really, this is a game changer. And it's been available for certainly three years. That's a lot.
And in the end, I'd say using real CSS with Tailwind kind of defeats the purpose. You end up with different styling methods for different components. I don't think that's good. More like a "hack".
But really, your example above is right on point: by excluding new approaches, Tailwind disincentivize you from using them when they would solve many of your problems elegantly and simply.
edit: the Tailwind example provided is bad CSS. As were the ones given in the first fundamental post by Mr Wathan. These are strawmen. If you're interested, I'll give you an example of good CSS producing the same output.
And, as I'm sure you know, milliseconds are important in our craft. You can easily shave or add hundreds of milliseconds with HTML or CSS.
And to be honest, I find your general line of inquiry here to be quite agressive and dismissive. I think, respectfully, a little more good faith could further our understanding of each other.
The question about what you're building such that you care about perf characteristics of CSS is an effort to understand you, I am sorry I failed to come across that way.
Outside of consumer apps I am struggling to imagine a case where the HTML/CSS perf delta would be more important to capture than faster development time. I suppose part of why that doesn't seem like a good faith question is because you don't believe Tailwind dev time to be faster, so the tradeoff that I'm trying to evaluate is totally inane.
First, sorry for the response delay. I don't know why I didn't see your answer.
As for the case in point, in fact, I think CSS can be as fast if not faster. But that's totally for me to prove. Hehe.
That's why I'm working on a set of simple rules for efficient styling with CSS. A website with documentation, examples and tools is in the works. If you're interested, I can give you a heads up when it's online.
Feedback from Tailwind users is important and would absolutely be welcomed!
Because it’s way, way faster to build with; yields more easily composable, less brittle components; and has a very solid (and rather unopinionated) design system baked in.
So glad to read comments like this. I cannot believe my eyes that most devs these days just don't get it and litter their projects with layer upon layer upon layer of unnecessary complexity.
I thought a person had to be rational to become a developer but oh my, how wrong I was.
This is the paradox of popularity. The theory goes that if you have a large pool of X to select from, then you can select the best of the best, and the quality of your selection will be amazing.
But it's exactly the opposite. Small groups are self-selecting for quality and big groups are self-selecting for quantity. O_O
English, the universal international language. The one we're speaking here, right now. The worst translators in the world are English translators. Everyone feels qualified to speak it and translate it. Finding a good English translator is like looking for a needle in a haystack.
The more "easy languages" and "frameworks" we have, the more "programmers" we also have, and 99.999% of them have the faintest clue what they're doing, but they just keep hitting their keyboard with a hammer, and it compiles and produces interesting results, so they keep doing it.
This is also why social networks have an amazing set of interactions when they're new, and in an old social network you have hundreds of millions of users, but no one writes anything interesting, anyone barely reads, and it's full of scams, bots, clickbait and garbage.
There's safety in numbers, the saying goes. Not at all. If something is universally popular, and you choose to enter it, get ready for a shitstorm.
I'll take this anecdote and counter it with the success of Bootstrap. You could have been using it for an entire decade now. There's a robust ecosystem around it to this day.
Tailwind as the "new bootstrap" makes a decent amount of sense.
These frameworks aren't an excuse to ignore and misunderstand the underlying technology. It's worth understanding CSS, but these abstractions can really speed up development time, especially if your job involves more than "front end development" (which is still true for many of us).
Tailwind is made for a component world where reusability is at the template/component level.
This also covers both scoping issue with css: the usual issues with the single global namespace for classes and the unlimited depth of the descendant selector.
That is even with scoped classes if your app has component nesting as <A id=1><B id=2><A id=3></A></B></A> then a selector like .A_box::hover .A_btn will select the class A_btn both in <A id=1> and <A id=3>.
Tailwind solution is to manually or programmatically apply the relevant style in your template.
The whole idea being that the unit of reuse is not the class name but the templating component.
I would concur that all I mostly need is CSS modules and to know when styles should be copied (most of the time) or actual utilities (rare).
Any remaining reusability can be handled with templates / components (depends on your framework).
The remaining potentially nice thing about Tailwind is that it more naturally constrains your options/syntax with utilities - when working with designers, this is probably a good thing. As always, the hardest problem of development is finding technology that best establishes the social contract.
Me: Taylor Swift’s song are bland, run-of-the-mill pop.
Swifties: Pfff *plonk gajillions for the tickets.
In cases like this I get curious and try to understand: why? I do not do CSS enough to arrive at the verdict about Tailwind, but my best understanding aligns pretty well with TFA. That and the fact that people wanted some framework that is popular and can be easily reused for results that look reasonably well. Bootstrap was it for a while, but Tailwind came and looked more modern.
After a few years, writing CSS by hand gets really old. There's always 5 different ways to do something, and I don't know which one is the most performant or portable.
As expected this dumb take shows up in every tailwind thread. Almost always by people that haven’t actually tried it.
I was skeptical at first too but after building several large and successful sites with tailwind I’ll now choose it every time. It’s the only CSS method I’ve tried that doesn’t turn into a hot mess at scale.
This attitude has become a pretty useful anti signal when considering who I want to work with though.
>You're not learning anything valuable by learning Tailwind. Learn CSS, that will stick with you for the next 20 years.
Tailwind maps onto CSS in a very straightforward way. I think you'd have to go out of your way to "learn Tailwind" without also improving your knowledge of CSS.
I think I understand tailwind, but like the parent poster I'm really not a fan, because while CSS can be a footgun, it can also be quite clean when you use a sane DOM structure, CSS variables, and well thought out CSS selectors.
> it can also be quite clean when you use a sane DOM structure, CSS variables, and well thought out CSS selectors.
This fall apart pretty quickly as soon as more developers join the project. Keeping consistency between multiple team members is hard without a reference point, which is what a framework like Tailwind provides.
I'd say that the "stylesheets" part doesn't apply either.
Tailwind creates "stylesets", and is absolutely powerless to apply them. Quite like WYSIWYG text editors. So, yeah, anybody claiming you are learning CSS by using it doesn't really know CSS. But I disagree, that kind of thing can be useful on certain contexts.
i think that’s what people’s argument FOR tailwind is:
CSS can easily be a footgun, unless everyone on the team uses a sane DOM structure, CSS variables and well thought out CSS selectors.
i’ve yet to witness a project without “!important” scattered throughout the codebase.
Exactly this. Anyone who has worked with a junior developer understands this intuitively. They spend a week smashing their head against the desk figuring something out, then in review, you (the senior dev) can look at it for 30 seconds and see all the holes they missed and think of a simpler solution that uses 1/3 the amount of code.
Simplicity is a skill and it's hard to do. There's a reason most people are not minimalists despite the almost universal western desire to "have less stuff".
Tailwind is a means to an end. If you think writing css is the best way to spend your time, go for it. But I guarantee I can ship things faster using Tailwind.
I'm sadly not surprised to hear that, same for another poster who had the displeasure of working with a codebase with !important sprinkled everywhere.
Truth is I've been spoiled on that front because I had the luck to work for many year in a company where the CTO was a very talented dude who lived and breathed HTML/CSS since the mid-2000's, and who was quite thoughtful about that kind of stuff, so I had a first-hand experience of a good codebase, mostly by avoiding external dependencies, using the standard browser behavior, and frequently consulting the MDN.
This is why it's a bit disheartening to see so many front-end framework working against the plateform, even even marketing against it, while CSS and browser tooling his so much more enjoyable and powerful than before.
True, but the thing is that it wasn't really "complicated" CSS we used, but simply a good grasp on the fundamental of CSS, which is a overlooked part of web development.
I believe it's mostly due to the fact that CSS, just like SQL, is one of those technology approachable enough to fiddle with it and get somewhat far, while not really learning it, and thus overlooking the fundamentals.
> None of the frameworks I know of do that.
I would squarely put into this category all the CSS-in-JS frameworks, such as 'styled components'. Also everything that markets the 'cascading' part of CSS as being a mistake.
Also, all the frameworks that compiles CSS without generating the CSS sourcemaps, making the debugging experience way less efficient since all the applied CSS rules shows under '<style>' (eg: 'styled-components' again, who discarded it as being 'cosmetic' in the related Github issue).
And pseudo selectors like hover, and animations. If these problems were solved in css style tags, I’m not really sure tailwind would have much to offer. It’s basically inline styles as class names
I have written more raw CSS than I have written Tailwind in my life. But I like the well thought out utility classes of Tailwind so much I only go raw when there is no option.
I also don't think about it too much and sleep well at night ;)
Tailwind 1.0 was great. Give me a few utility classes to style borders, fonts, backgrounds, and box shadows. Tailwind has descended into madness as they endlessly increase the scope.
The only thing that is true is people don't learn CSS but Tailwind syntax. But even with that, making a house of card of CSS isn't change the inherited problems of CSS.
Silly premise and vapid article. Tailwind 'won' in the same way Bootstrap 'won', i.e. it was popular for a time. $10 says Tailwind will be the Bootstrap of 2027.
Well also bootstrap "died" in the most honorable way possible, it got antiquated by the CSS standard implementing flex and grids (the original specification was based on XUL though and not bootstrap - https://medium.com/@BennyOgidan/history-of-css-grid-and-css-...)
Kind of the same with jquery (although it took quite a lot of new stuff...)
Yeah the Bootstrap story is hardly one of the frontend world changing tastes, it was the standard forever and everything else at the time was copying it. Some key fundamentals of how CSS is written in the 2020s changed quite a bit as did how people wrote HTML (as the author alludes to using smaller component UIs with build systems replaced big HTML files and big CSS files). It was good time for a rethink IMO.
Components UI systems are not going away, even as we move back to static heavy sites and minimizing JS where ever possible.
But this is how all victories work, whether it's a war or a sports competition or market share. You get to be the undisputed champion for a while, until eventually someone else comes along and beats you, or circumstances change so that your victory doesn't matter so much any more. "But Tailwind was only the dominant CSS framework for most of a decade" is not much of a criticism.
That is the point. Tailwind is just CSS. And like the article says, you can copy paste designs from examples.
The key difference between Bootstrap and Tailwind is that Tailwind designs are distributed. So Bootstrap designs feel like Bootstrap designs, while for Tailwind you can keep having new and fresh designs from different sources.
As a primarily backend person, I like it that our frontend uses tailwind due to the copy-and-pastable aspect. I can nab an element from another part of the site and adapt, or take an element from https://tailwindui.com/ and know that it will paste in and look exactly as intended. It doesn't look good, or particularly inline with the style of the rest of the site but is good enough as placeholder UI before frontend/design can come in and tidy it up.
I do constantly shudder though when reading a list of class names like this:
What causes me to constantly shudder is when I have to use project wide search to find the class name on an element so I can see what was caused the computed styles in the browser to occur.
1. Find source file with class name. See the scss extension, dread rises a bit.
2. See scss file has multiple @import directives and uses multiple custom functions.
3. Open up 4 more scss files to see what those imports and functions do. See that those files also use @import directives. Find some Malort, take a shot.
4. Repeat step 3 until arriving at root of style hierarchy or pass out.
That's why Tailwind works. It may result in a very long line of small classnames to represent all the styles across many breakpoints, but at least you don't have to deal with somebody else's own little hellish adventure into perfectly reusable scss.
But these are self-inflicted wounds. Having standards and validation for CSS is easy. No need for all of this. No need for SASS either. Install Stylelint and there you are.
I've encountered this situation in multiple projects where style lint was enabled, with only the defaults, and passed the linter without issue.
Tailwind is seeing steadily increasingly popularity (and the accompanying backlash) because it is straight forward and does not require something like stylelint to keep you from hurting yourself.
Well, that is not using Stylelint I'd say. Within half a day of configuring, you can prevent almost all of the problems denounced in this thread.
Ultimately, it really is "a couple hours of thinking/configuring a linter vs. multiple layers of abstraction, complexity and dependencies added to the codebase."
Maybe I'm missing something (and be my guest if I do!) but there is an objectively better choice here.
Well, that means stylelint has a problem. They should be talking about how to solve it, because nobody wants to not enable debuging information on a develoepr build. If the devs do not acknowledge this as a problem, this means stylelint is a bad piece of software.
I really dislike sass the way it's normally used. It was once a necessary hack, but it's mostly not useful anymore. Something that just concatenates your CSS @include on deployment would bring more value nowadays.
I'm not sure what you mean about "Stylelint having a problem".
There's a default config, with only base rules, without the more opinionated ones. Then you configure/extend it as you would with almost any other tool. Isn't it the way most tools of this kind work?
Linters default rules define almost completely how they will be used. It doesn't matter if you think this is reasonable or not.
IMO, missing some rules is better than what most tools of this kind do, but something as plain and obvious as "did you enable debugging symbols on the development build?" should be there. And most people will blame the tool if it's missing.
Sorry if I'm being obtuse but I still don't understand.
As I see it, the problem was one of SASS code architecture. What do you mean then by "enable debugging symbols"? How does that solve the "chaotic file architecture" problem?
I don't know what magic stylelint does that I'm not aware of that helps with this. We used stylelint with a massive project and everything was nice and "clean" yet CSS debugging was a nightmare. At least with Tailwind I can look at the classes and tweak exactly what I want
If you give me a couple of examples, I can give you Stylelint rules to prevent them. At least I think so... eheh.
And now that I think about it, that would be a great exercise in fact! Yes, I'd really appreciate it if you have some in mind and would post them here.
NGL tailwind is really nice to build new things and is absolutely amazing to create MVPs and small projects
...
but once you got to the point where you open a file and see 20+ classnames stacked in every div, which makes them unreadable, its just a mess. Love-hate relationships with this tool, but the idea is very good and this article mentions biggest selling points - its easy and very fast to use.
I feel like people often forget the alternative, which is opening a component and have to read 200 lines of css (possibly spread out over several files)
Even putting aside the architectural considerations, one way that standard CSS has failed, is that the naming of properties is inconsistent and increasingly difficult to remember and work with.
I find that using tailwind's flex "aliases" (which is almost what they are) is more intuitive than using the god awful standard CSS property names.
CSS standards should not just look at adding stuff, but making new versions, like newer APIs where they take a good look and rename all the properties to make them more consistent.
Hard disagree. As a web developer who has to work with the CSS monster daily, having to memorize property names between CSS versions would be a particular kind of nightmare.
There's a good article by the author of tachyons.css which is similar to tailwind, but never got that much attention:
https://mrmrs.cc/writing/scalable-css/
Progressive rendering of CSS is a great boost in performance. Tailwind can't benefit from this technique I think and as such, imposes an added cost on our users.
I don't think is accurate. While it might not be built in currently, the same is also true of something like SASS or even plain CSS.
The article describes a strategy for loading CSS in the most performant way given a variety of interconnected factors (mainly JS).
You could generate the Tailwind file, and then split it when the media queries start (they're all grouped in order of screen size) with a small bash script into separate files as a part of your build process.
You could have multiple build steps that analyze your component architecture and generate separate CSS bundles for each component. This is already done w/ most JS frameworks.
If your argument is one of the final CSS file size, that is not an issue. Tailwind only generates classes that you write in your markup. Most Tailwind bundles I have seen, are dramatically smaller than their CSS counterparts, and it makes sense when you think about how CSS is written.
Say you have a two UI elements; an article preview image and a user avatar. Say you want them to mostly display the same, but with some tweaks to the avatar to add a fancy filter on hover. Okay easy enough. Maybe you start with some sort of base mixin and then overwrite add behavior for the avatar. Over time, you add more and more tweaks to the avatar until one day, you get a call from the head of Design Department that the articles are getting their own special CSS filter. Okay, so now you extend the article. Over time the two continue to drift until you're overwriting anything that they originally shared in the beginning. The articles have different margins than the avatars and now marketing wants to allow users to upload images to comments. Does that extend the original mixin from 3 years ago? Maybe you think, "why do I even have this base class; can I get rid of it?" After some quick testing you remove the original mixin and go home for the day. Over the weekend, you get a call saying that the avatars showing user contributions from a fundraising event are all messed up. It turns out, the base mixin added `display: block` to the images, but when you tested, you really only looked at the logged in user profile photo in the navbar. Whoops.
Now take that scenario and multiply it by 100 devs on 20 different teams. We've all seen it. This is why CSS is often never deleted in large companies. Devs instead to continue writing ever increasing specific selectors or using techniques like BEM/OOCSS to stop the bleeding. It takes an insane amount of discipline to wrangle CSS on a sufficiently large project. Tailwind helps manage some of that complexity, and at least provides good guard rails for teams of developers by empowering them to know that a "small refactor" won't break an entire layout.
I'm not sure you understood correctly what I meant. Or maybe is it me. Hehe.
To reiterate: you can link and load CSS for a component just when this component is used instead of loading everything at first. So the first load of the page is faster. Same thing with media queries in link tags. Isn't that something Tailwind can't do? Tailwind will load every style, every time, right?
As for your example, I get your pain. I' ve experienced it too. But it isn't a reason for completely pushing aside CSS in favor of a framework and all that it entails. It is a reason to have good linting.
For example, no component should ever influence the "outside world". So no margins on components. Rhythm (gaps or margins) is better taken care of by the parent (a grid, a list, etc.). This is a simple linting rule in Stylelint that will prevent this development behavior.
As for the rest of your problem, I'd say the "mixin" approach is of disservice here. That and, the way you implement the filters.
Are filters to be arbitrarily applied on the whims of the designer? Creating filter classes to be applied in a singular way then may be a good approach.
Are there rules governing the usage of the filters? Then a systemic approach could be a winner, especially if you can talk with the designer.
There are simple ways of managing these issues/problems with native technology and a little linting.
PS: Sometimes the problem IS the design. If the design is irrational, the real, efficient solution is not to implement these irrational patterns but to talk with the designer and find a rational solution. I know this isn't always easy but that is the problem resolution we should strive for as it is the most efficient one.
I think we largely agree, so I'll go back to focusing on the tool.
> Isn't that something Tailwind can't do? Tailwind will load every style, every time, right?
Tailwind's only function is:
- Scan codebase
- Generate classes
- Save them in a file with the a .css extension.
Anything else that you want is outside the scope of the tool. It makes no assumptions about what your files are named, where they are, or how it's loaded in the browser. At the end of the day, it's up to the developer to write `<link rel="stylesheet" href="/path/to/my/generated/file.css">`
This is no different or made easier/harder by using Tailwind.
According to NPM download stats, it has 6 million weekly downloads, the exact same amount as Styled Components. Emotion also has around 6 million. So that's 12 million for CSS-in-JS, as opposed to 6 million for Tailwind, so how did it win?
The whole "Why _____ won" is the same as specific politically affiliated news channel trying to sway future voters by stating some inflated Exit Poll numbers in favor of the party they are trying to portray as winning the election. Same reason why you see every new graduate you see has been affected by the whole MongoDB/NoSQL, React propaganda.
I believe the primary reason that sets TailwindCSS apart is its inclusion of pre-defined margins, paddings, and colors. Starting with these built-in defaults is much simpler than having to consider all these design elements from scratch.
I always felt slightly dirty after writing a bit of inline CSS (`style=”color: red“`) instead of a proper class, yet at the same time it accomplishes the goal and it was fast. So this is basically Tailwind, right?
Basically, but with two important extras: media queries and child selectors.
It’s impossible to write a media query or target a child with inline styles. With tailwind, the first one is encouraged and the second is at least possible, and in some scenarios, encouraged (group hover).
Child selectors I can understand. But won't media queries mostly be limited to containers and thus used sparsely and those cases would warrant having a class of their own even if one decides that named classes for each element is a hassle?
Another aspect is css class reuse. Inline styles are not preprocessed so each inline style is a 1:1 increase in bundle size. In large applications this can be significant. Imagine having hundreds of popups each with 50 lines of css. It adds up.
One of the selling points that Tailwind pushes that I haven't seen other people mention here is that inline styles are _too_ flexible. You can do `style="color: red"`, but you can also do `style="color: #FE0005"` or `style="color: #FE1111"`.
While tailwind lets you write your styles in the same _location_ as the style attribute, it allows you to restrict what _values_ you can use. You can set up a colour palette so that when you say `class="red"`, it's the shade of red that you (or your designer) picked, and your colleague can't decide to pick a slightly different shade for their component.
Can't this be solved by creating small css classes for your colour palette like font-color-primary, background-color-warn, etc? The benefit being that anyone who needs to include these only needs to think about the context and have consistency everywhere.
Yup. This isn’t the killer feature of tailwind that’s impossible to get any other way. It’s one component of a bigger solution. But why it’s relevant here is it’s an example of how that bigger solution is different to just using style attributes.
There are far better ways of writing CSS than Tailwind… take a look at Stephanie Eckles, Andy Bell and others work on how little CSS you actually need for great designs
Realistically speaking, with CSS, you don't even need to use one single class inside your HTML. Every element is a child of another, up till <body>. The C in CSS is just that, CASCADING.
I find it ridiculous to attach so many classes to your HTML elements. I think it is obvious Tailwind gained popularity because people just didn't want to learn CSS. And I don't blame them, it took me years and I am still learning new ways to achieve things. In a way, CSS's flexibility is also its beauty: you can achieve the same thing multiple different ways.
You can do A LOT if you know CSS. With tailwind you can do what others have thought of you might need. This is the antithesis of programming. Programming is supposed to help you break the limitations of tools.
You really don't have to do that. It is a pseudo-problem. Specificity and flexibility can also be managed easily in CSS only. Without naming everything. Linting can be used to enforce real good practices. Without any overhead costs.
It's ironic that "costly context-switching" is listed as one of the primary reasons, as this normally is considered a "feature".
Modern front-end development heavily embraces small components, composability, clean abstractions, reusability, higher order state, decoupling of error logic, testability, and so on.
The natural consequence of this paradigm is that when your PM says "hey, can you make a small change to this online form?", you'll be context-switching between many files.
The idea that you currently can do "application logic" in your HTML/JSX is a gross misrepresentation of reality.
Folks, while we are at it, what is the best way to learn proper front end for a hobbyst? I'm a decent programmer and work with databases and backend technologies. I want to be able to build simple front ends for the stuff I work on. I've been meaning to dive into D3, but the tutorials for basic front end stuff assume I'm really starting from scratch. But what I'm blocked by is 1) what is a nice workflow for development 2) how can I build effective frontend 3) how to setup everything.
The biggest thing to worry about, IMO, if you're just working on your own on hobby projects is long-term maintainability. This gets down to tooling, which can be horrible over the long term.
Tools get updated constantly, packages get updated constantly, breaking changes get made almost constantly. Five years from now, your packages probably won't work, and it will be almost impossible to work on a project -- unless you've been maintaining it over the past five years. If your product is your business, of course you're maintaining it. But if it's just a hobby you want to work on sometimes -- then you want to be able to abandon it and then come back later without the pain of figuring out why you can't compile your SCSS, javascript, or similar things.
I think the Front-End is split into multiple different parts that work together but I sometimes think about them separately. A) The organization of the individual parts. B) The 'look' of those parts. C) Technical stuff like Accessibility, parent-child coupling, etc.
Learning A can be pretty quick for some basics, learning B is a rabbit hole that can take ages to 'learn'. The good news is most of what you need is for something 'competent' is in A
To answer your points below:
1) Front load your design. The equivalent to Pseudocode for the Front-End is to wireframe. Consider all of your pieces, how they should be grouped, and why. There are some common patterns you'll run into in everyday life. If you find those patterns, draw them on a piece of paper (or your editor of choice, you could do it with mspaint if you wanna). Then you can write out your HTML/CSS. I typically work back and forth. All the HTML, then I CSS, then more html if needed, then more css. etc.
2) An effective Front-End is one which gets the user where they want to go with as little friction *as possible*. Emphasis on as-possible because, just like asap, it doesn't mean "yesterday" it means, "Please prioritize this task above other tasks". An effective FE has a clear idea of purpose and wastes no time achieving those goals. Also, see patterns above. This might not be useful yet but one pattern is to look at the shape of what you're trying to display and allow that to dictate the FE. As an example - almost all documentation sites have a left (or right, or floating) vertical navigation, it takes up maybe 10% of screen width, and then the content of that documentation fill the rest of the width with some amount of padding on the left and right. Consider flipping this pattern. Make the Nav horizontal and the documentation full width to get a feel for why most documentation looks the way it does.
2.1) Some terms to search, "Elements of Art and Principles of Design". I recommend everyone look them up - there are ~20 ideas that reference how we go about making something aesthetic.( Art - color, form, line, shape, space, texture, and value ; Design contrast, balance, emphasis, proportion, hierarchy, repetition, rhythm, pattern, white space, movement, variety, and unity )
3) Uh this is a bit more complicated than I can do in a single comment but maybe we can share discord names if you like the cut of my jib so far.
I used tailwind for several personal projects, then realized I was spending way more time than I used to styling things.
I switched back to bootstrap for personal projects, where I make a few tweaks to the global theme, then write zero css and very little styling besides things like margins and alignment. It's way easier and enjoyable for me, though I admit that my apps all look pretty generic.
Out of curiosity, do you use react or use any components in those projects? The general consensus seems to be people who are practicing atomic design with components love Tailwind, and people who don't dislike Tailwind.
It takes some time to get used to it (basically, memorizing most import class name schemes). But this is the first time I can open an old project I haven't seen for a year and directly start changing the styles of stuff without the fear of breaking anything or having to read into how the CSS is managed again.
I also like that it lets you build anything and does not have a default look.
I feel most people who hate Tailwind never had to deal with the problems it is trying to solve.
It does things in a brain dead way to protect you from other people’s idea of cleverness.
Also in corporate settings apps and sites don’t follow sensible rules, you think you’re gonna have a few sensible classes for a few different components?
Well marketing decided that they need 50 small variations of just one component, of course it makes no sense to you, but that’s the requirement so shut up and do it.
If you’re not using Tailwind you end up with 50 exceptions and your normal CSS quickly becomes unmaintainable.
Tailwind is the mad solution perfectly suited for a mad world, and only people who hate it are those who don’t have to deal with madness.
I don't dislike Tailwind. I think it is a great tool if used correctly, but the majority of projects I've used it on, other devs eventually tend to overuse the @apply rule and end up just creating lots of custom classes. This literally defeats the entire purpose of Tailwind and I feel like that feature alone is what is most wrong about the library. If you're going to use their classes to write your own, you might as well write vanilla CSS. There's literally no upside to using Tailwind and it's actually a huge hindrance, as you now have to remember the rules of CSS plus all the Tailwind utility classes.
I strongly disagree with the usage of context-switch here. If you're writing HTML + CSS or writing HTML + Tailwind classes that's the same context. Maybe my experience with CSS is partly to blame - I can see a design and have both the HTML and CSS in my noodle at the same time because they are coupled. The phrase will lose all meaning if we're comfortable with, "Anytime I look at a different file" as a clean definition for context switching. So If I ctrl+click to read a function that I've imported or I'm checking out the type definitions for a parameter - that's context switching??
To me, this would be like saying writing a function in a React component and then writing the HTML for that same component is context switching. It just doesn't stand up to scrutiny. The tasks are related and in a similar headspace - even if they aren't connected 1:1.
> Switching to a CSS file to change styles is a costly context switch
It is?! I have an IDE with more than one pane. CSS-in-JS exists if you really don't want to switch (albeit with its own problems)
> you can just copy and paste a list of classes or an HTML block into your application
Well back in my day we called these "inline styles" and came with their own problems. CSS is copy-pastable as well, and easily composed with classes.
> Compare this to [..] CSS build systems like Saas
Tailwind requires a build step! Frankly, I haven't seen a sizeable webapp without a "build step" for incorporating even plain CSS
> The best way to write the least amount of CSS is to just compose basic styles
This feels like an argument against Tailwind? Utility classes are helpful but will never be enough to replace CSS entirely without long lists of classes on every element
CSS is moving so fast these days, can Tailwind keep up?
I see loads of comments in here using things like `.mb-sm-3` (I presume it's `margin-bottom: 3` for small screens?) as an example for how readable the classes are, but with CSS introducing logical properties I wonder if Tailwind's syntax needs to update to accommodate those changes? Using logical properties, this same example would render to `margin-block-end: 3` and already you're moving away from the easy-to-remember shorthand Tailwind created. If Tailwind's syntax needs to update, isn't that a pain in the ass to maintain?
This is just one example, but CSS is introducing loads of new stuff every few months it seems and I would hate to be limited by the constraints of a CSS library when browsers are capable of achieving so much these days. I enjoy learning CSS, not Tailwind.
In the start-up space, Tailwind is to product UI as Bootstrap was (or still is) to marketing-focused landing pages. It almost serves as a litmus test as to whether you work in a start-up like environment or an enterprise environment.
If you are in a design or product function in a enterprise company in non-tech industry, you steer clear from Tailwind. But, I appreciate its usefulness for developer's who just don't want to learn CSS or have the time to prioritise building their own design system — that comes with maturity.
In any case, Tailwind trades one CSS problem for another and it just illustrates that web development is not different than any other kind of development — it's all about managing compromises in technology and approach, based on your needs and future plans.
Purely from experience — largely, design system or development projects at large organisations are lead from a PMO, design or product teams — with technology often seen as down-stream (at least, in terms of development, there is of course technology architecture/advisory along the way.)
That means that the design/product requirements come first. The moment Tailwind's limitations meet design requirements, it'll take a back-seat.
It's basically the same reaction you'd encounter from saying "we'll build it in Bootstrap." If a company is investing in a new product or service, no one wants to be the guy that says "sorry our framework won't let us do that design" — at least, not in first year or two of a product life-cycle.
Tailwind's advantage — speed and accessibility for a range of developer backgrounds — isn't the same priority for large organisations vs. startups.
This is only 1 perspective (which is correct in most cases but not always).
It can also produce massive HTML (not CSS) making it worse than pure CSS solution.
Even when used as expected, per-page, you end up with unnecessary html and css, because tailwind can't combine the classes used from other pages. For one to be able to use tailwind as efficiently as site-covering custom made CSS, you'd need to collect the HTML or CSS Classes for the whole site and compile the CSS from that, but tailwind is waaay too slow for that to even work - not to mention, node.js can't even handle that amount of classes in memory (4GB Default).
I'm very well aware of this because I tried to make it as efficient as possible.
I don't get Tailwind. In my book, CSS is here to facilitate the style of multiple webpages by modifying a set of rules, and classes are here to mutualise said rules.
With Tailwind, it looks like you design by writing HTML, which is the opposite of what CSS aims at. So if you wish to change your design, you'll have to update multiple templates instead of one CSS rule.
Every time I've had to work with Tailwind, it felt like a chore and it was an unpleasant experience.
> So if you wish to change your design, you'll have to update multiple templates instead of one CSS rule.
Changing the CSS to apply site-wide changes sounds great in theory but after working in front-end since IE6, this almost never happens in practice. You're never certain how the styles cascade and indirectly affect things so you're afraid of changing the core CSS.
Styles isolated to components is a much more scalable approach in my opinion and then it doesn't really matter whether you use Tailwind, CSS-in-JS or scoped CSS (Vue etc).
I do use tailwind and I find it terribly convenient for some things, but this argument still seems to mostly stem from too many people doing css who are not great at designing css and are doing things they really should not.
How will I ever keep track of where I used px-6 and where md:px-4 in my templates and why, without semantic classes? Of course I can then build more solutions around that. Or I can accept that good css design is hard, just like any good software design is hard.
Let's solve that by switching to a different abstraction that proves to be more useful. In this case, isolation-by-component instead of isolation-by-class.
I'm not the person you're replying to, but I'm in a similar position, and while I'm not in love with Tailwind*, it's successful because it's oriented around components rather than classes. In every project I've worked on, it has been far easier to manage the complexity of components over classes, because components link style and structure together, which usually end up very tightly coupled anyway. This limits the scope of the CSS you're writing a lot, making it a lot simpler to understand what any individual declaration is going to do - you know exactly where it's being used, you know exactly the HTML structure it's operating on, you can see exactly what it will do as a result.
* I use it a lot at work because it's very easy to get something written, but I find the pseudo-CSS DSL irritating if I need to write more complex queries. Something like CSS modules requires a bit more boilerplate to use, but you end up writing real CSS queries, which I find more natural. But this is personal preference.
Its hard keeping track of different usernames on here.
From my perspective, "almost never" and "won't actually happen" aren't that different. Both indicate that the probability of success is very low. It seems to be, if the probability is already really low, is not worth extending effort maintaining it.
> You're never certain how the styles cascade and indirectly affect things
Then your DOM is too complex. You're formatting a text document; that shouldn't get you in a position where you lose track of what cascades where. If it is you have a bigger problem than styling.
I agree with you. As a developer I like the separation of style and content. We also gain better readability when the code says "<div class="product-price">199</div>" than a long list of tailwind classes.
CSS styles are also more reusable across different web sites. I can to some degree see that you can increase re-usability when using shared React components, but then you just create technical debt for those who want to test other frameworks
It seems to me that Tailwind is only a semi-scalable solution for those who use React components or similar. But as mentioned above, that causes problems when you want to make other webapps in another framework
Can you explain something about why you prefer the separation of style and content? From my perspective all that it accomplished is making me modify two files (html template and CSS) instead of one.
There are several advantages of separating CSS and code from my point of view.
- I generally dislike inline CSS styles, and the benefits of Tailwind is not enough to overcome that.
- Reusability across systems. At least in mature businesses, they often have CMS systems, different frameworks etc. Using Tailwind kind of encourages everyone to use the same internal React component library.
- Easier to read PR and git logs. Adding a single tailwind class to a component may mark the entire line as changed, and you need to figure out what has changed (including checking the code, because you don't know if that also changed).
- Designers can make changes in CSS without having to learn React.
As soon as you have recurring product prices, you’re encouraged to use @apply to group those classes. In practice, however, you’re using components of some sort anyway, whether in Frontend or backend code, so this isn’t really an issue.
It’s a completely viable solution for certain situations, say, having a .button class. The things mentioned in that twitter thread have nothing to do with that.
I was commenting on "As soon as you have recurring product prices, you’re encouraged to use @apply to group those classes. ". It's certainly technically possible to create a CSS class. But AFAIK the recommendation is loudly and clearly to use components https://tailwindcss.com/docs/reusing-styles#extracting-compo..., and for good reason.
I follow, but even that part of the docs acknowledges the use cases solved by @apply. No denying it’s a powerful gun to shoot your foot with, but it has its merits. Especially in the OPs context of some bespoke e-commerce CMS, which might not even have a frontend pipeline more sophisticated than grunt or something.
> if you wish to change your design, you'll have to update multiple templates instead of one CSS rule.
this comes up on every tailwind post and it isn't true. tailwind encourages you to not repeat yourself by making reusable components (or fragments etc) instead of reusable classes. that way if I want to see how the button both looks and works I only have one place to look
even if you don't do this, with tailwind you encode your design system (colours, spacing) etc in the config file so even copy pasting everything will get you something consistent
I don't feel this point is strong because when you look at some of the most popular Tailwind components or templates in the ecosystem, such as the one made by the Tailwind people, the Tailwind code is still pretty crazy.
I think your last point has legs, for sure. It makes sense that some other language will compile to wasm and make some app development more straightforward, but I don’t think the end result will be that different.
The web platform is not going to move away from current paradigm without an overwhelming shift in priorities or needs. Wasm still generates html and outputs it on the screen.
My biggest reason to use tailwind is maintainability. Having everything right in front of me with only the tiniest of abstractions, makes it really simple to refactor and maintain. I can confidently delete “CSS” and know it has no side effects. I can cut and paste a block of html and it will render EXACTLY the same. I don’t have to worry that Steve used a generic sibling selector in a CSS file 3 years ago that is screwing with my layout/design.
Is the HTML more bloated than if I had written “normal” css? Yes, but I think it’s worth the trade-off. It’s important that we can agree that their are trade-offs and then it’s up to each project to decide if those are worth it for their use case.
I’ll also mention the actual CSS file is crazy small as well since the tool only generates classes that are actually used in your project. No more ever-growing css that other people are afraid to delete for fear of breaking some legacy page!
> Wasm still generates html and outputs it on the screen
Sure it can. More usefully to my point though, it can also use any of a number of C++/Rust/etc. UI libraries to render directly to a buffer or canvas, which is in my opinion a better long term solution for true applications (vs websites).
When you do that you get total layout control with no need for CSS or worrying about browser defaults.
As a random example here is the Rust egui library demo app running in a browser using WASM (no HTML): https://www.egui.rs/#demo
The speed and “native application” feel are hard to replicate in JS/HTML, as they are just not great tools for the job or rich desktop (or desktop-like) applications.
In my understanding it somehow abstracts the process of styling a website or whatever and make it easy for people who for any reason don't want to write CSS.
Although I have the sensation many people find hard to write CSS and even despise it (I've read people here in HN who seem to think we should've kept doing layouts with HTML tables and don't agree layout is the job of CSS!) I definitely agree having dozens of classes in your HTML is messy and weird.
It’s all stuffed in classes because that’s the limitation given and this information belongs in the markup.
The above is much cleaner to me than: div.class(“primary”). I need to go find primary. What is the parent class. What happens if this isn’t a div now etc. what happens if the parent isn’t a div?
Tailwind just spells it out for you right alongside the layout so that you have all the information in one place.
For me personally, I was able to do things in tailwind I could never do in raw css, but I bet I got better at css as a result.
The docs are also incredible for tailwind. As good as mdn is, you need to already know what you’re looking for.
It's much easier in Tailwind for me to see locally what's going on with that styling. If I lived in this code all the time, or I was good at structuring CSS, then maybe the first would be more appealing. But I'm a shit at CSS, it always turns into an unmaintainable mess, and I look after a lot of different projects that I might not touch for 6 months. So Tailwind's approach is easier for me.
My solutions to the problems you raise, in order of preference:
1. Not worry about it, it probably won't happen on the projects I'm working on. YAGNI.
2. OK, it's happened. Get some coffee, make all the changes. Can I use a regex? Make the changes incrementally? Delegate it to a junior?
3. This is going to change a lot. Let's make a re-usable component, a named colour like 'primary' (in Tailwind config), or re-usable class like .button-default. The right solution will depend on the requirement.
In styling, I'd rather have 1000 obvious changes than 1 difficult one. The risk of having the wrong shade of red is not high enough for me to worry about abstracting it.
I appreciate that good, full-time CSS devs have much better solutions for this, but those solutions involve being good at CSS as a starting point. I don't have that luxury.
In tailwind you'd probably use a named color such as `primary` or `border-primary` or something like that, so you still have the ability to change it in one place. I don't really like tailwind myself, but I don't think that's an issue
1. Given the example actually provided here, do you see an opportunity to do that?
2. Suppose you change the example to use named colors. Where does this name-to-color-value mapping live?
****
> I've noticed that moving the goalposts is extremely prevalent on HN, which makes for pretty frustrating conversations (or just reading). And then sometimes it's a tag team. E.g.:
> Person A writes their comment. Person B1 offers a rebuttal. Personal A offers their response. Person B2 offers a second rebuttal that abandons the premise behind B1's rebuttal, and may actually be at odds with it. Person A ends up either deflated or looking defeated.
> It's like the cross product of a Gish gallop and a DDoS.
As stated elsewhere, if you're using a component based UI, this isn't a problem. You're also free to mix regular CSS with Tailwind.
As for the "git gud" school of CSS, should we also abandon React, Svelte and the like and revert to hand-cranking DOM manipulation like it's 1999...?
Sure, if you're manually editing a large volume of .html by hand, Tailwind is bad news, but given the plethora of static site builders out there (brief shout out to Astro which is excellent), manually authoring individual .html pages seems like masochism.
Sounds like a boring Friday afternoon job, or something I could give to a junior contractor. It's also something that doesn't happen very often on the kinds of projects I'm working on.
In React at least, often you can live with One Component = One File at least for simple components. Adding separate CSS files, as the OP says, causes context-switching.
This is not true in svelte, where a component file can have both a root tag for the component, and a <style> tag that the framework/compiler automatically scopes to this component (and a <script> tag for the code, since you don't have the JSX inversion-of-control principle).
You can utilize the Functional CSS approach to eliminate the redundancy of architecture and behavior across various instances (JSX and CSS). Furthermore, it offers superior performance when compared to OOCSS.
One example is if I was using react it would be used to encapsulate a react-router Link and an anchor tag in a component, and use props to differentiate between inbound and outbound links.
Suppose we want to change just one link? Would it be better to make a new class with all the same attributes except the color and apply that to the specific link.
> Suppose we want to change just one link? Would it be better to make a new class with all the same attributes except the color and apply that to the specific link.
Why copy the attributes? Just override the one you want to change. You can even use style="…" if you're sure that it's just one link.
The tailwind version is actually horrible, don't do this: you are supposed to style all the links in the same way, as with the css example, not style each link in it's own way; or you will get a link red, another one blue, another one yellow, and your ux will be crappy and your code unmaintainable
Horrible.... for you. For me, it's lovely. My UI productivity and satisfaction has massively increased with Tailwind, and I've been using it for 3 years now.
That isn’t a Tailwind feature though? That’s been like a basic feature of CSS frameworks for 10+ years. Even Bootstrap was going this route way back when.
Who rolls the basic boring CSS classes like border-red or border-primary by themselves? People have been doing it for free for over a decade.
That misses the point. This is still worse than seeing all your styles in the place where they apply. SASS/LESS just make it faster and more succinct to write styles in css files rather than in the components in which they live and even more importantly—on the actual ELEMENTS that they apply to.
I think the framework is meant to be used by other frameworks and not by humans.
It is an unpleasant chore if you use it by hand and I have given up on it but I can see that if it's just used in components and then html is not written by hand but made dynamically it could work better.
It's basically a CSS framework for JS frameworks and not for writing HTML.
In a recent thread someone explained Tailwind was best used with component frameworks, and that made it make a lot more sense and I could see the appeal.
It’s actually one less layer. My layout and styling are finally together, and well documented. I don’t mean in the same file like a .vue file. I mean they are TOGETHER.
I wrote CSS from scratch since version one. I know why it's called cascading, I have used many preprocessors and generally don't mind writing CSS at all. That being said, all my attempts to modularize my stylesheets looked like a incomplete and buggy version of Tailwind. I could imagine that this is the reason why it's popular. Also people seem to always be ignoring the fact that you can just use tailwind to create helper classes. Nobody forces you to repeat common styles a million times.
Modern CSS has become so simple, thanks to @layer, Flex box, Grid, and it looks much nicer than Tailwind. And, most important, I do not have to learn it, I know it already.
I like Linaria [0] because your IDE typechecks your styles and gives you autocomplete/intellisense when typing styles. With Tailwind you have to look everything up in docs because it's all strings, not importable constants. Leads to a lot of bugs from typos that aren't a thing with type checked styles.
I see there is a lot of fair critiques about tailwind, many I agree with.
But as someone who works on UIs built with react, it's nice to not have then need to leave my JSX components - html, js, and css (via tailwind) are all nicely colocated. Especially nice with the vscode extension that shows the css rules of the underlying css decleration.
I agree that fundamentals trump all, but tailwind is a nice css abstraction that hits my use case well.
Tailwind usually makes more sense with React or some other component system. If you are not using components, Bootstrap might still be a reasonable choice.
I am a not-good-at-ui dev, meaning I _can_ build UIs pixel perfect if given some exact design files, but it is incredible hard for me to come up with things on my own. So whenever I build something that is not already defined fully by designers (like: most of the time), I have to use some UI component catalog like bootstrap and start assembling my UI based on the options there, at most I switch a theme file to something more fancy.
I basically was squarely the target group of bootstrap, and used it for lots of projects in all versions. I didn't actually care much about their technical progess (float, flex, css-grid, whatever), I just copypaste from the available widgets and add in my data.
Just LAST WEEK I learned that my favorite web framework (https://phoenixframework.org/) now ships with Tailwind preconfigured by default. I also heard good things about it from trusted colleagues. So, for the next big project I decided to jump in. Still I kind of have concerns: I need "typical components" like cards/tables/grid/... to be only a copypaste away; and I need to allow some designers be able to tweak the overall look and feel, roughly like a theming file where fonts/colors/... are defined at a single place. I hope it will be smooth after all these years of bootstrap and the "muscle memory" of how to compose pages with it.
At the beginning, it's going to feel like a drop in velocity. If you only copy and paste raw code and do not make components, then it will feel like a lot of work to change the accent color from blue to yellow (unless you're really good with regex).
If you want a more Bootstrap like experience, look into something like DaisyUI. It gives you a high level primitive similar to Bootstrap, but built on the philosophy of Tailwind in regards to ultimate customization using utilities.
If/when you get more comfortable with the tailwind primitives, you can easily make your own component abstractions that work for your needs.
I made a Chrome extension called SnipCSS that is made for not-good-at-ui devs.
Instead of using a framework, I just rip other sections of website designs I like using my tool. The paid version even scopes the snippet and gets all responsive styles.
Theming abilities are on the roadmap and with AI being able to adjust my snippets eventually - I really don’t see the need for extremely verbose frameworks like Tailwind. But I could be wrong, I’m probably biased after having worked on it for a couple years.
I find it frustrating that web development moved away from encouraging developers to use a collection of consistent visual styles and basic components (like Bootstrap offered - and even Bootstrap itself is moving towards being a collection of utility classes).
It's very frustrating to have to make a lot of decisions around standard component styling on each new project.
You can just write your own styles and then use @apply <your Tailwind classes>; inside if you have the right tools. I am not sure what is this commotion about. I think that most of the critique comes from people who have never used tailwind before hence it looks foreign and grotesque to what they already know, i.e. CSS.
Yea Tailwind is so good. Yes you have to enter more class names into your html, but the payoff is you don't need to mess about with CSS at all unless you need something very specific.
It also makes it so much easer to progressively update things to a new design, without worrying about 1 change in a CSS file potentially having an effect anywhere.
>It also makes it so much easer to progressively update things to a new design, without worrying about 1 change in a CSS file potentially having an effect anywhere.
Don't you just have to worry about making sure your update is propagated to all the right class lists? Seems like trading one medium problem for 30 small ones.
Well for example if you have a style on anchors on a site. If you update the general style (even it its in a class) you have to worry about everywhere that thing is used and whether it will break it. They are all completely coupled.
I mean there are techniques to avoid that like BEM and co, but they rely on you and your colleagues following them, and in my experience are a huge ballache.
Its also sometimes hard to track styling issues down, looking through all of the properties etc. And if you get into SCSS and mixins it slowly gets out of control.
On the flip site with Tailwind, it's all there in front if you and easy to change. If you need to repeat something often, you can just create components / partials with reusable parts.
Btw Tailwind isn’t a religion…if you don’t want to use it, that’s fine.
It has helped a lot of people - myself included - write more and better CSS but I don’t understand the vitriol here. If you want to write vanilla CSS or BEM or Sass or Less, I think that’s great.
Most folks would agree with you that we can use what we like but that isn't the reason for the vitriol. I think most of the vitriol comes from the way the it is presented as "the winner" when a lot of people either actively dislike it or would never chose to use it.
I dislike Tailwind and would never choose it so seeing it presented as if it climbed to the top of some pile makes me laugh out loud and based on the comments there are a fair few people that agree. That said, use what works for you and I won't try to claim my choices as "winners" in some undeclared contest.
I think it's because the people that like tailwind really like tailwind, and they will take any opportunity to tell you how amazing it is. The evangelism gets really old after a while.
I like using Tailwind. There's good reference online to help style pages. I usually find what I need, copy it, and it works most of the time. Since I don't know much about UI, Tailwind helps me get the job done.
There is a persistent misconception that Tailwind competes with Bootstrap, but they just exist at different levels. Bootstrap provides components, but Tailwind is just a faster way to write CSS.
Components are just one part of Bootstrap nowadays, it also has helpers/utilities, the (css) grid system and flex, themes (light/dark) support w/ css vars.
Probably not granular enough for Tailwind fans though.
For me it won because I view tailwind as vanilla CSS with a nicer syntax (mostly) and sane defaults that makes your website look decent out of the box. With the prettier autosorting plugin, the classes are ordered in a predictable fashion, making it easier to read than one would imagine.
It's not a perfect replacement for vanilla CSS and I still fall back down to writing plain old CSS for stuff like box shadows or more interesting grid layouts, and using tailwind modifiers like different screen sizes is less than ideal with having to prefix every single CSS property with the same modifier.
The "default" (no css) look of HTML pages with black on white Serif text with default paddings / margins / spacing...must also have been picked at the time to make web pages look pretty (in a generic sense) out of the box? Just that we have now evolved in our sense of visual design tastes / whats possible has changed over the decades, maybe.
if your main argument is that the value tailwind is something you couldn't do with "style" or inline attributes you've missed the point entirely.
only thing worse than a comment made out of ignorance is one with that additional amount of hubris attached. this point somehow seems to always float to the top of every tailwind post. not surprising to see it as the top comment.
It's true that, as the OP claims, many developers are not writing HTML/CSS, they are writing JSX (or similar) so maintaining a separate CSS file is a context switch. Point taken, and well made. Also, the original HTML/CSS split made more sense when one was writing documents, not applications, and the author and designer/typesetter were separate people.
However, svelte (my current favourite framework) gives you the option of putting a CSS block in a component source file, which is compiled to be local to the component. For example if you put "h1 { color: red }" in a <Warning> component, then effectively what you get is some kind of "h1.warning" rule. It just works in the background how you expect it to, doesn't interfere with anything else, and you don't have the context-switching overhead of separate files.
I know that svelte has a lower market share than some, and of course you can use tailwind together with svelte, but the claim that "writing CSS = switching files" is only true within the scope of e.g. React, not in general.
It's internally inconsistent, so you can't guess what the Tailwind class name is for styling, while you can do this for CSS on the majority of properties. In Tailwind, font weights are just `font-bold` for `font-weight:bold`, while font variants drop the `font-` prefix part, and become `ordinal` instead of `font-variant-numeric:ordinal`. That's not an isolated example, it does the same with text-color versus text-decoration, and text-decoration-color adheres to neither of those systems.
It's quite close to learning an entire new styling language on top of CSS. It may be the case that putting everything into the HTML is more efficient from a productivity point of view, but I don't think Tailwind's specific implementation achieves that.