As a once-strident critic of Tailwind for its many failings and incompatibilities with the state of the actually-modern "vanilla" web art, I am very pleased to see the huge strides they've made with v4. Being able to access the Tailwind theme through native CSS variables (they even have an example in the docs of a button component written in native CSS in an external stylesheet using native variables! Oh happy day!) is absolutely massive, and being able to use a CSS-only config is equally amazing. Finally, Tailwind feels more like it's a utility (ironic, since its claim to fame is utility classes!) which you can add to any project, rather than some bizarro "viral" framework that wants to eat sensible architectures and lives in its own JavaScript-y silo.
Perhaps all the criticism over the years actually had an effect. Or maybe they finally arrived at good conclusions on their own. Either way, I suspect many of the pro/anti-Tailwind arguments are no longer relevant, and that's a Very Good Thing. Now we can get down to business and ship product.
I'm still a critic in terms of actually using it, but what I find amazing about tailwind is how amenable it is to AI-generated workflows. It seriously works _so good_. Anything can be expressed, and systematically. There's something amazingly useful there.
> what I find amazing about tailwind is how amenable it is to AI-generated workflows
It's highly amenable to human workflows as well. Of course, humans are more disparate than AIs so it doesn't suit all humans - no tool can. But it sure does seem like a majority of humans web developers like it.
> I suspect many of the pro/anti-Tailwind arguments are no longer relevant
I feel there are two issues with Tailwind for me as a designer / design engineer.
* First, JavaScript/Tailwind engineers have hijacked the conversation on design. Instead of "utility-first," "dead code elimination," and "type-safe CSS" I focus more on desing systems. Whether to use Perfect Fifth or Perfect Fourth in typography for example.
* Second, Tailwind makes it impossible for me to participate in the actual craft. Design decisions get buried in React components with cryptic expressions like `flex items-center shadow-lg p-6 hover:bg-gray-50 dark:bg-gray-800 py-[calc(theme(spacing[2.5])-1px)]`. This might make sense for JavaScript engineers, but blocks/makes it hard for systematic design. Instead of expressing precise mathematical relationships through CSS, we're essentially writing inline styles with better ergonomics.
Tailwind has solved a lot of problems. And this is coming from someone who doesn't use it half the time.
Some thoughts about this topic, not necessarily in disagreement:
- Designers seldom think in the way you describe (explicit computer-readable rules, systems of design). A lot of designers are coming from crafts that are more implicit. It doesn't surprise me design business logic is not the topic of conversation.
- You need to update your tailwind classes to reflect your design business logic. Don't do "bg-gray", do "on-surface-emphasis" or whatever business logic. This is just a simple config change.
- You probably brought up modular scale as just one example, but modular type has become near myopic dogma of frontend engineers who haven't had any typesetting experience. A scale of 1.25 vs 1.5 is so in the weeds as to be useless. There are so many alternative ways to set type (e.g. take lessons from CJK typesetting) or innovate typography on the web (e.g. build your own leading-trim implementation!).
I'm a designer, so I absolutely think in terms of design systems where typography is just one part of the puzzle. There are, of course, many ways to set type — but the point was: no Tailwind engineer talks about typographic scales in the first place. Systematic thinking is absent, which is naturally built in CSS.
Tailwind itself is a design system. The authors actually put together a short book explaining their point of view on design systems (without referencing Tailwind) and I found it very difficult to argue with any of their points.
Then you look at Tailwind and realize it’s almost entirely that book packaged for others to use.
The Tailwind library names grades of colors and sizes for you, but the book is ultimately about iterating design so that you can create your own design system. From the perspective of the book, the Tailwind defaults are inadequate as a design system.
Not really the same, although I realize it can seem that way.
If you go low level enough everything technically fits that bill, it’s just a matter of how much work you have do to put the structure in place and what the burden is for other people to learn it.
It’s akin to raw Perl vs Ruby on Rails. You can do it that way, nothing is stopping you…but there are compelling reasons not to.
That's exactly the argument I'm making about Tailwind. Inadequate as a design system. You have these bundles of rules just a thin step above CSS and there's nothing obvious about how things should look.
I'm kind of surprised why this is even relevant to you. The designers I know work in Figma. The designer and the engineer collaborate to make sure the design isn't too hard to implement, but other than that the designer shouldn't care about whether developers are using Tailwind, StyleX, Sass, vanilla, or whatever.
I hardly expect a designer to take responsibility for something as transient and idiosyncratic as "oh, but this is hard in Tailwind."
Maybe Tailwind is useful for bigger projects, but I tend to prefer component based class instead. The biggest DX for CSS is using the web inspector and directly modifying the DOM, then copying the adjusted values to the text editor. For a much serious project, I go with the balsamiq -> figma route to create an actual design system.
How can anyone prefer this gobbledygook over a nice CSS class declaration with line-separated standard CSS properties ? How can one even maintain this ?
Maybe the modern generation of web developers have IQ 200 and 20/20 vision with eidetic memory and I should just put myself to pasture.
Because your not thinking of styles practically. You don't review style declarations, you review the rendered page/component. You see with your eyes that a component has the wrong border color, and AFTER THAT you go to your component code, find the border color declaration (if any), and update it/add it. Sometimes you'll even inspect the element in browser, and find the faulty class directly, making it even easier to target in code.
The Tailwind classes are "unreadable crap", that's true, but it's not a problem because you don't "read" it, no one does. You roughly parse it and edit it.
Exactly, it's not like a novel where you are trying to read the entire thing. And it's an advantage because it is easier to parse. If I'm trying to change the color on that element, I have a very good idea what controls that. As opposed to something like "card_wrapper card_wrapper--striped". That certainly looks better, but if I'm just there to change the grid, now it's a more complicated change. In Tailwind, I can just look, see "grid-cols-[1fr_2.5rem_auto_2.5rem_1fr]" and know that not only that's where to change it, but that I can also change the classname there without worrying about a regression in some other element somewhere else. Whereas with "card_wrapper card_wrapper--striped", well what controls the grid? I have to look in another file, and I also have to be concerned about every other place those classes are used. (Or I have to add new one-off classnames, at which point the complaint about long classnames holds less weight.)
Personally I prefer how PandaCSS does it - similar end result with atomic css at compile time but it just lets you write your styles as readable objects instead of as insane strings.
Take a guess at what “dark:bg-gray-950”, “bg-white” or “min-h-screen” means. You get them from context.
Imagine if you put a little bit of effort into learning Tailwind. You’d get the more complex declarations as well.
As to why it’s better than a class declaration, a lot has been written about using atomic, composable utility classes over reams of “write-once” class declarations.
I do not disagree that there are one or two recognizable elements in that encoded line-noise. Not sure what is the "terrible take" about it - if you take a poll, most would agree that it requires far too much eye-strain to read, far too much cognitive burden to parse, decode and mentally map to concepts.
Its like deciding to code your entire your app using regexes - all in long single lines without comments.
No one cares what your typography ratio is if you can’t get it in front of a user quickly enough (dead code elimination), reliably enough (type safe), or cost effectively enough (i.e. if you have to pay for more developer time to implement the same work).
Tailwind is a tool for craftspeople, not artists. It democratises design by making it simpler. For folks that are really good designers, they should be happy that they can up their prices knowing that customers are paying for their expert eye, rather than just the basics again and again.
Tailwind does not democratize design. Tailwind is generally 1:1 to CSS, sometimes 1:2 or 1:3. It's such a thin layer over CSS that you have to remember all the CSS. That does not make design easy or hard. You don't give people Tailwind and end up with design as beautiful as ShadCN, even though ShadCN in some perspective is just another wave of stereotypical startup design. The ability to go from blank button to beautiful Tailwind button is all on the author, not the fact that you're writing in a new lightweight inline syntax.
When I read the Tailwind book, my takeaway was their design philosophy was about the speed of iteration and how that interacts with designs whose parameters are too interdependent. Tailwind follows that philosophy by encouraging ad-hoc repeated edits over DRY. In that sense StyleX also fits the Tailwind philosophy very well even though StyleX is an even thinner layer over CSS.
I don’t really agree. You have curated colour palettes, so if you want a red, you’ve got red-50 to red-950, rather than an entire RGB colour space.
Similarly for font sizes, you don’t have to decide on a pixel size, just whether it’s small, large, extra large, etc. Border radii. Border widths. Padding.
There are lots of “sensible” defaults so you don’t have to pick even the units (should I use px or pt or em or rem or vw or ch or…) before we even talk about the numbers associated with those units.
The Reactoring UI book would find whatever structure of defaults given to you as very inadequate for a design system. The book is about an iteration process for creating your own design system. The Tailwind library happens to empower that design process.
But by default there's basically no opinion on what even a button should look like or how colors should be used on your website. You have to create your own abstraction such as "brand-color" and "brand-primary". You have to create your own design system, as there is no Tailwind default button or anything.
If you talk about a default Tailwind look people might be confused and think of ShadCN.
Just because you can build great things with Tailwind doesn’t mean it’s not democratising design. In the same way as putting frets on a guitar helps amateur players make better music without stopping great players doing their thing, Tailwind is the “frets” on CSS that make sure your hands play the right notes. You can still get it wrong, and you can do inspired or uninspiring design with Tailwind, the same as any tool.
Ok fair enough. I was actually talking about the whole of Tailwind rather than just the typography ratios, but I can see how I could be understood in that way. My mistake. Either way, Tailwind works in exactly the way OP describes as their counter example.
Their palette is really neat. I always check it out when I need colour inspiration, especially for "cold greys" and other "state" colours (green for success, red for error, yellow for warning...).
I actually did this for a former company that had a Bootstrap-based app - the designers started bugging that "we need to use Tailwind", and I couldn't figure out why they cared what tech we used.
In talking with them, realized they just were bored with our theme, ha. Not publicly accessible though, sorry. I should probably recreate this.
yeah, the palette is neat. My main gripe with Tailwind is that it blends a set of design tokens (which I like) with a technology to apply them (which I don't like)
CSS has become significantly more user-friendly than in the past, with most browsers now behaving consistently. It's worth learning as there is no build step involved, and it avoids cluttering your markup with excessive code.
You could opt to use style attributes directly within your HTML. Historically, we avoided this to maintain a separation of concerns, but it's puzzling why some prefer reintroducing similar methods. Is it just to save a few keystrokes?
Using style attributes even seems more straightforward since it doesn't require translating code in your head.
These days tailwind is often paired with a component abstraction system that takes place of css classes as an abstraction system. Component abstraction achieves an even more powerful separation of semantics from styling, compare:
<h1 class=hero>Cool page</h1>
vs:
<Hero>Cool page</Hero>
In both cases you need to go find the “hero” abstraction, but in component world we are also abstracting over the HTML tag name in addition to whatever styling stuff.
When it comes to defining the “stylistic detail” in either case, it has been separated from the “content” which is our page source file. I am happy to pay a build step to get better separation of concerns - content from presentation.
no, a single html attribute containing "relative before:absolute before:top-0 before:h-px before:w-[200vw] before:bg-gray-950/5 dark:before:bg-white/10 before:-left-[100vw] after:absolute after:bottom-0 after:h-px after:w-[200vw] after:bg-gray-950/5 dark:after:bg-white/10 after:-left-[100vw]" is not "easier to read" (example taken at random from the Tailwind homepage)
Individually applied styles kinda defeats the purpose of cascading style sheets though.
As someone who's quite conversant with regular CSS, I really did like the ease of applying whatever style I wanted right in the code without needing to "worry" about whether this div is a "panel" or a "hero" or whatever, but it really does tend to make a huge mess of my HTML in very short order.
You might like Styled Components then, if you're using React anyway. Not sure if there's similar systems for other frameworks. I don't consider it pointless make-work to develop a consistent stylesheet to use throughout your app though.
I believe the Babel plugin eliminates most of the performance cost.
The naming is double-edged. Often you want to re-use your styled element, so the fact that it has a name from the get-go makes that really easy. But you're right, sometimes it's annoying to pull bits out that you didn't really want to.
Ultimately I went back to CSS Modules. I just don't understand why I'd want to the appeal of Tailwind.. I'd have to learn a new DSL that ultimately gives me less control.
The problem is that with bootstrap I have card, table, etc. With tailwind I have an unreadable alpabet soup when I am not a designer but a developer and am not familiar with tailwind.
And then you build on that, and you have card-alert, card-message card-message-small, card-body-alert, card-body-message, card-form, card-login-form together with extra sass variables for them.
And then you ask "why not just have variable for each component, not each component's style?" and this is where tailwind steps in.
This is the big one for me.
In any big enough or unfamiliar frontend project, my go-to way to explore the codebase is to launch the front-end, and use the inspector to check the elements, and then search-back in the codebase the relevant classes to see what page/component display that, and how does it fetches the data.
If there is only an alphabet soup, I no longer have a simple set of classes I can grep the codebase with to quickly find the relevant components.
This is just not true. You can absolutely grep the soup (I do it daily). Most UI components share a lot of common baselines but include a specific modification for use in place (often a color or extra spacing). That means most of the time, the entire class string is unique to that element, even if the classes themselves are not. At most, you might have a couple of duplications, but then you should probably be looking at a template level component if the functionality is related.
`mx-4 py-2 rounded-xl shadow bg-green-500` is just as easy to global-search for as `notice--success`
I greatly agree with you, but should mention that there is DaisyUI which is a Tailwind plugin that adds these for you. It seems inspired by Bootstrap and others: https://daisyui.com/
It's because we've normalized React and tight coupling. Styling belongs to components, not in design systems. I feel the JavaScript-first engineering ecosystem needs brave new design-led companies, who see the power of modern CSS and systematic design.
> Historically, we avoided this to maintain a separation of concerns, but it's puzzling why some prefer reintroducing similar methods. Is it just to save a few keystrokes?
In bigger projects, if we start looking at the amount of files one has to deal with, Tailwind becomes very appealing.
We've went through the regular `.css` route but then you have weird names, and, potentially, duplications or even conflicts.
`css modules` is an option but you've now essentially duplicating the number of files that you have for each component / page.
`sass` or `less` essentially bring the problems from `css modules` and regular `.css` into one.
I don't inherently like or dislike Tailwind (although I very much started by absolutely disliking it) but you feel its value in a project with 200+ files composed of components and pages
My initial reaction to Tailwind was: what a pain. I already know CSS, now I have to learn CSS again...
I imagine its how parents might feel when they go to help their children with math homework only to find the math is now totally different from when they were in school and their methods (while still valid) for solving problems are no longer accepted by the school and their child is annoyed by having to reconcile the two systems...
I get the, tailwind works well in a team and scales nicely and you just have to use it, mentality. I've experienced it.
I still prefer a plain style sheets that targets elements by a class or tag (especially since CSS supports nested selectors!).
There is an issue in managing stylesheets, and for that I really like how Remix/React Router manages CSS where CSS flies are defined and applied at the route level. Where that isn't enough or dynamic styles are too complex for a .css file:
style={{...}}
is always available.
CSS is so powerful, flexible, and extensible, tailwind feels like a limitation rather than an enhancement. I don't understand the continued appeal, but clearly many others do. I'm not sure why, but I am confident we'll all have moved on to something else in another 3 or 4 years too.
I agree it’s frustrating initially to re-learn CSS… I used to make the same arguments. But after contributing to an open-source project using Tailwind I got up to speed, and now I feel differently.
Tailwind is essentially just stenography for style={{…}} - a single utility takes 15 characters that would take multiple lines in a .css file or style object. It greatly reduces the amount of time I need to spend googling stuff like “visual text replacement css” or perusing various css cheat sheets or skimming through css-tricks blog posts from 8 years ago. Instead I always go to tailwind docs, and quickly learn the utility class that just does the thing I want. A surprising amount of it fits in my brain cache, much more than trying to cache the css for all the tasks I might need to do in a layout.
I think it’s because now your entire component is contained in a single file. No more separately messing around with CSS. The styles are right there on the element they apply to without having to cross reference anything.
You could do this with just the css attribute, but that has the issue that everyone has always been taught it is wrong to do that, and a list of strings that contain a bunch of utility is easier than writing those plain CSS objects.
> But why is it wrong to use the style attribute? What makes using tailwind to do the same thing "not wrong"?
The time people were taught it was wrong is thr time when all your elements were rendered on the server and the style was duplicated for every component it applied to.
Client rendered JS only sends it over the wire once and then duplicates it on the client.
Tailwind only allows a few options, so it’s less likely you have slightly different styles everywhere.
I think the awful syntax you talk about is really nice, since it covers 99% of everything I ever need to do with it. The cascading part of CSS is really cool, but 99% of the time it’s confusing when I don’t need it.
Tailwind I use for hobby projects but we’re still sticking with style={{…}} at Notion. Since the app launched there’s been many generations of CSS-for-React (Airbnb Aphrodite era, styled-components/Emotion era, styled-jsx/linaria era, CSS modules era, Tailwind era) come up, get hype, and then thrown in the trash heap. Probably the best move for us would be an optimizing compiler for style={{…}} or our useStyles hook.
Limitation reduces available complexity and that’s why tailwind wins. It’s a composable, standardized, and modularized wrapper around a very massive and complex system. That’s a big advancement.
I'm learning math with my kid and it's not different to what I learned. Can still solve everything quickly.
On the other hand there are those posts on social media mixing multiplication and division and telling you there is only one true answer to those. Tailwind isn't that bad, but it's more into this direction for me as an old fart ;)
I love tailwind, used in 3 projects in the past 4 years, it’s intuitive, well documented, simple. I don’t miss the days of emotion and styled components where I would have to think of a name for every styled div in the project, with tailwind a container is just a div and a few classes nothing else. Less bike shedding discussion, less brain cycles spent naming things, less time wasted in reviews.
> I don’t miss the days of emotion and styled components where I would have to think of a name for every styled div in the project
I see people mention this issue fairly frequently, and it puzzles me a little. I have never once spent probably more than 1 second thinking about what to name something. Is it actually a blocker for some people? Are you really paralysed by this?
What I don't understand is why BEM is scarring. If you're talking about the reason or timing something looks different, you must have named it in that conversation. Just use that name.
"When the menu is wide, the items' icons and text should be visible. When it's skinny, only the icons should be visible. This button toggles between them."
Or I could just express this in code once - in the spot where I attach the class names to the HTML - instead of attaching class names, just attach styles.
You must be working with very good product owners then. The ones I've worked with love to specify the hell out of every possible detail. Like a web form is their personal HGTV renovation. I tried tailwind once and the classes ended up being an order of magnitude more than the markup. It got hard to read, quickly.
"Whatever you do, don’t use @apply just to make things look “cleaner”. Yes, HTML templates littered with Tailwind classes are kind of ugly. Making changes in a project that has tons of custom CSS is worse."
Reasons:
* You have to think up class names all the time — nothing will slow you down or drain your energy like coming up with a class name for something that doesn’t deserve to be named.
* You have to jump between multiple files to make changes — which is a way bigger workflow killer than you’d think before co-locating everything together.
* Changing styles is scarier — CSS is global, are you sure you can change the min-width value in that class without breaking something in another part of the site?
Yet... my experience using projects that use tailwind is that every button everywhere is styled the same way, but it's repeated in multiple areas. The 'kinda ugly' part, but also... it's repeated in multiple places. Trying to change the universal focus behaviour of buttons in a project like this is hard, because... I can't search focus:outline-none without finding everything that has 'focus:outline-none' on it. I can't just search/replace, because it'll impact other stuff.
So I end up spending way too much time trawling through way too many scattered specific styles all over a codebase, vs having a defined 'btn' style someplace. "well, that's just the project's fault"... possibly, but it seems to be the promoted/preferred/evangelized way of using tailwind, judging by the projects I've had to get involved with the past few years. IME, this approach may have good short term benefits, but poorer longer term maintenance, doubly so when the original people are no longer involved in the project, and outsiders have to come in to deal with it.
I agree with Tailwind's stance on this. You really don't need @apply if you're breaking things down to smaller components. I often see people have things like <ul><li className="long_list_of_classes">text1</li><li className="long_list_of_classes">text2</li>...</ul>. This is where I think we need a linter to warn against things like that. Make those <li>'s a component!
I have bern heavy Tailwind user from before v1.
It actually doesnt matter where you make the class grouping. You can make it in your templating language or you can make it in @apply. I prefer @apply because the same grouping can be reused if done correctly. @apply is great.
The reason they are discouraging @appply is because its hard feature to implement and many people dont understand how it works so they get to problems and create issues. It bothers Authors so much they have always been considering taking @apply out but i think they know big chunk of the userbase would leave to different similar project.
For buttons, I think the 'blessed' way to do it is to use (react) components and have the tailwind classes encapsulated there. It makes sense; you have a layer of abstraction where the implementation of your theme is in the "lower level building blocks" of your components. (Call it a component library if you want)
I generally only use @apply when there are some heavier external interactive libraries that are hard to style. Like for example if you're embedding markup in your application, and you need to apply a set of styles to the markup it generates, and you can't do that directly in react because you don't control that part.
Gave it a go for several projects, but didn't like it... for big projects it gets messy, fast. It also feels like it has become the new bootstrap.
I'm very happy with my current CSS-in-JS workflow. Crafting good old css with LLM help. You just show the LLM a pic, ask for the components.... boom, done (with proper naming, etc)
This is actually one of the main reasons I avoid react when I have the option. Styling in react is terrible, I'll use tailwind with it but only as the least bad option.
If I am using a frontend framework and a build step, svelte and astro are nice depending on the use case. I can style with plain old CSS and rarely have to reach for class names, if you keep components small you can get away with element selectors and let the framework scope styles at build time.
I used tailwind for my site and ended up liking it a lot, but maybe for reasons that are not often mentioned? The real value of tailwind is being able to read all the styles that affect a an element in one place. Sure the classnames can get long, but it’s still a lot faster to read that long line, than open the browser tools each time or scroll up and down one (or many) stylesheets.
Then when you come back to that code later, you can confidently edit it without worrying about causing changes to other elements.
The cascading nature of CSS is still helpful, but I find that I usually want to limit my styling to just one element. For all the rest I go back to css but I wrote very little css because I usually just want to get the whitespace right.
I think that is exactly why tailwind is good and nice. Although I also like that it makes “how do I do X?” a quick doc search instead of a 30 minute research project
> real value of tailwind is being able to read all the styles that affect a an element in one place
there are helpers for that in the IDE (e.g., "Show Applied Styles for Tag" in Intellij) or even in chrome dev tools that show all this in a readable way. Tailwind snippets mentioned in this HN topic look kind of scary in comparison.
The difference is with tailwind that information is stored as text in source control. So you can parse it with nothing but your eyes in GitHub or by looking at a diff, without relying on any extra tooling.
I kind of agree but the same problem exists. If you add text-xl to a div and have nested divs and spans, they'll all be inheriting text-xl so for these nested elements, you also have to look up the element's lineage to find what's causing the text-xl.
There's a clear pattern in every "Tailwind or not tailwind" conversation (which happens everytime Tailwind is mentioned).
There's those that never used it for more than 30 minutes, that just tried it out or just skimmed through the docs. Those are the people that hate it and prefer "vanilla CSS" or similar.
Then there's the people that actually used it for a real project, within a team with more than 1 single person. Those are the people that understand its value, accept its trade offs and love it.
I've seen a lot of people jump from the first group to the second group. I've seen almost none jump from the second to the first.
That's why Tailwind is so successful.
It might not be beautiful in the eye of the purist, but it's absolutely fantastic in the eye of the builder and pragmatic.
I’m not against Tailwind, but I didn't used it yet because I struggle to see why it's a better approach compared to other options like Web Components or React Styled Components.
The biggest issue I have with Tailwind is how it clutters the HTML with a ton of utility classes making the HTML harder to read and maintain. Of course I see Tailwind being better than using large global CSS files with the classic CSS approach of naming html tags. But we do have ways where the CSS is scoped to a component without polluting the global namespace. Like Web Components and Styled Components. Both keep styles tied directly to the component (or more general, a specific group of html tags), making it easy to see which styles apply where.
And yes, with them there’s no need for global class names, without having to worry about unwanted side effects or clashes. If I remove a component, I also remove its associated styles without worrying about unused CSS being left behind since both are tied together. Plus, there’s no risk of one component's styles unintentionally affecting another (thanks to shadow DOMs).
I really value keeping HTML very short and readable by not mixing presentational styles directly in the markup. Tailwind’s approach, where the styling is all in the class attributes, makes the HTML feel cluttered, especially when you have long class lists on a single line, and GOD forbid you have actual class names to use there. It’s harder to understand what styles are applied at a glance since you cant even have it well indented, and it clearly reminds many reasons why we moved away from the inline style attribute in HTML in the first place. (Yes, we didn't left it for its limitations like pseudo classes and @media queries, they didn't even exist, we didn't add those new features because no one wanted to get back to those inline styling)
So, while I don’t hate Tailwind, I just don’t see the clear advantages over Web Components or Styled Components in terms of readability, maintainability, and separation of concerns, while I do have important unanswered important concerns about using it...
Yes, I've read the docs but never tried it out, I don't hate it, but I can't understand why I would choose it over other options. The fact of having a million classes in the middle of plain HTML makes them both unreadable for me.
And No, I don't like huge CSS files either, or the classic approach of using them. But it is hard for me to see why tailwind is a better approach than working with Web Components, or React with Styled components.
These two approaches allows me to not have to read presentational things in the middle of my html, and allow my html to be more clear and readable. I don't have to use CSS class names, it's easy to identify which CSS applies where, so, if you remove the component, you remove the CSS too, you don't end serving unused CSS rules. Each can have CSS not leaking to the global scope, and there is no risk on changing styles of another element...
So, there is no hate for me, but it is very hard for me to see the benefits of tailwind over these two approaches, and I really dislike the idea of having to read html elements with huge styling rules cluttering my html files, and worse, having all of them in a single line makin it hard to understand all the applied styling.
We left using style tag from HTML mostly for that reason, and not because of its current limitations (like not being able to use pseudo classes, media, etc)
> I’m not against Tailwind, but I didn't used it yet because I struggle to see why it's a better approach compared to other options like Web Components or React Styled Components.
> The biggest issue I have with Tailwind is how it clutters the HTML
You're 100% clearly in the first group. Maybe I shouldn't have said "hate" in that group, just people that don't like it or see its benefits.
> Like Web Components
That's a nice solution, but in practice as of today and relatively speaking: nobody is using them.
> and Styled Components
Except the performance is a lot worse. And you still have to come up with names for every single div that needs a minimal one line style.
And both of these solutions end up with huge CSS files. Huge CSS files are worse than having larger HTML markup, because CSS is a blocking resource and HTML is not.
> I really value keeping HTML very short and readable by not mixing presentational styles directly in the markup
People used to say this about React, they preferred their HTML separate from their JavaScript, all nice and clean. I'm now 150% sure you're in the first group.
> Yes, I've read the docs but never tried it out, I don't hate it, but I can't understand why I would choose it over other options. The fact of having a million classes in the middle of plain HTML makes them both unreadable for me.
Alright, now you've recognized it.
> These two approaches allows me to not have to read presentational things in the middle of my html, and allow my html to be more clear and readable.
That's a non issue. There are extensions that will just hide classnames. You're just blending your mind looking for reasosn to justify your "I don't like it".
I promise the day you use it in a real life project where you're working with > 3 other people you will understand it's benefits, and how having "large class lists" is a non-issue and a totally acceptable trade off over the practical benefits it provides. Both on performance of the resulting CSS and maintainability over a large period of time. And think in the insane amount of discussions you'll avoid regarding if we're calling this div "styledDivWrapper" or "WraperContent" or "CardWrapper" or ".card__item--dark". Not an issue if you work alone, but when working with others this becomes a real annoyance that tailwind completely removes.
Tailwind is not for your, don't use it.
Tailwind is not for purists and architecture philosophers.
Tailwind is for pragmatic people, working on real life projects within teams where they have to ship and spend less time philosophizing on the purity and beauty of things.
As someone who made a competing product along these lines (that got no attention or traction): Tailwind gives CSS a "place" in the codebase. It benefits orgs, not necessarily apps. I didn't get it at first either. But it's very useful to the people to whom it's useful.
> Tailwind gives CSS a "place" in the codebase. It benefits orgs, not necessarily apps.
That is a better argument. But couldn't we be able to achieve that by, e.g:
- Create one standard HTML document with a predefined structure and including all the web components needed by your product.
- Having all designers and frontend developers developing their CSS (or SCSS) against this single base document
This would be basically the CSS Zen Garden approach. It would still keep separation of content and styling and it would create a "place" for styling code.
This works for products with a very limited scope that are mostly content focused, with a very small design team so everyone can agree to use the very limited toolkit in standards.html. The approach of saying “All ui shall only use these 29 components, anything else is forbidden” is not going to fly in a company with 10s of designers and 100s of engineers.
We tried this style at Airbnb and it turns out forcing all UI changes - from either designers or engineers - to acquire a single exclusive lock on standards.html leads to a fuckton of contention and frustration, and soon people are just going to yolo their own thing totally ignoring the pristine blessed system because the system doesn’t work.
The art of design systems isn’t a single technical approach - it’s finding an optimal workflow so your design engineers can build a UI toolkit that your product teams will actually adopt and contribute to, within the constraints of your existing tech stack & organization.
There are more "modern" ways to do this for large organizations like Storybook. Tailwind is a proposition for a small business that has a very small budget, want to buy a ready-theme and then make slight modifications. In a sense, no, it doesn't make any sense beyond that to use it. And once you use a good React/web-components framework, you realize there isn't really much value there as you shouldn't be really changing the CSS from page to another.
The process for large orgs is tedious and too lengthy/expensive for the small ones. Imagine having to go through planning, visualization, creating the component (or adding props for customization, writing e2e tests, publishing it to storybook with docs, and then finally adding it to your page and get it pipelined in the merge CI/CD process. A small org with tailwind just open the page in question and add a class to the html element.
As others have said, this is exactly what many large orgs do, but in a slightly higher-tech / more polished way with tools like Storybook, essentially creating their own CSS libraries and component libraries.
IMO a decent analogy is that Tailwind is to the above as something like Shopify is to being large enough to build your own ecommerce platform from scratch.
Does Ruby have an ORM/HTTP request handler/URL router in the standard library?
I am not sure I follow the analogy. If all you are taking from tailwind is the utility classes, fine. This is the part that provides value. But tailwind is not just that, is it?
Rails is a fully formed opinion on how you should write a web app in Ruby and all the various technical components you need to fully realize that opinion.
Tailwind is a fully formed opinion on how to use CSS (utility classes etc.) and all the various technical components you need to fully realize that opinion.
Thinking of Tailwind as just a bunch of regular CSS utility components is misunderstanding the scope of the project. That alone has a lot of tradeoffs and compromises - the file size is absurd and you can't bundle things into components, you also can't have arbitrary values in the utility classes. It wouldn't be a complete opinion on 'the best way to use utility classes', or however you want to frame Tailwind.
"Basically just inline CSS, but less fiddly and much more optimizable than the style attribute" was always the selling point of Tailwind in the first place.
CSS has become more confusing over time, not less confusing, so the upside of a utility class approach like Tailwind is also improving over time rather than decreasing.
Tailwind solves css confusion by presenting a “paved road” for many tasks. Want to do “thing”? Just look up “thing” in the tailwind docs, add “thing-2” to your class, done in 2 minutes. Rather than look up “thing” on google, skim several articles, then write 4-10 lines of CSS, done in 30 minutes.
As CSS has gotten more complexity from new capabilities, solving various tasks with it feels more and more like a research project. Like centering a div vertically and horizontally - there’s now 3-4 generations of solutions for this task:
1. Hacky stuff with position: absolute or floats
2. Flexbox approach. Hope you remember the 6 different attributes you need to set! Oh, there’s a new shorthand for flex now? Cool! More stuff to learn.
3. Grid approach. There are a bunch of different ways to structure a grid centering approach. Hope you remember how grid templates work!
But you can do that with a library of SASS mixins as well.
Going through some of the answers I'm noticing that another "issue" I have with the tailwind approach is that it works by providing a post-processor when in reality most people just need a simple preprocessor and macro system.
Sure? I don’t see how that’s an argument for CSS “being advanced enough” - SASS ain’t CSS.
I like SASS (I wrote a lisp in SASS in 2011 lol) and that’s actually how I think about Tailwind utilities - it’s just using SASS mixins directly in your HTML. I would rather use Tailwind because it will take 1/3 the levels of abstraction, 1/4 the keystrokes and 1/2 the files to do the same job to:
1. Pick a class name (myclass) if people are using BEM or something this requires some algebraic thinking.
2. Write the class in file.scss to define the class and include mixins A, B, C
3. Add class=myclass in my html.
Vs tailwind:
1. Add class=“A B C” to my html.
I don’t really get pre processor vs post processor, it’s a build step to run at some point before I deploy with either tool that will produce some css files. ¯\_(ツ)_/¯
> I don’t really get pre processor vs post processor, it’s a build step to run at some point before I deploy with either tool that will produce some css files.
Not quite the same. If it's only a preprocessor, the tool is only dependent on your styling code. A post-processor needs the whole application.
It's a lot easier to add or remove a pre-processor from your development process, and for those that want to consume your styles it is a lot nicer when you don't have to adopt their tooling as well. E.g, I can create a "utility class library" in SASS, generate the CSS and let people just import that directly into their web pages. Is that possible to do with tailwind?
> I don’t see how that’s an argument for CSS “being advanced enough”
That's a separate argument.
I hear mostly two justifications for tailwind:
1. It is (or used to be) hard to do things in CSS like variables, calculated properties, themes, scoped rules / namespacing. (Pre/Post) Processors are going to be required anyway, so we might as well use Tailwind
2. It gives frontend developers and designers a common language (the utility classes) which makes it easier to establish workflows.
My argument for (1) is that CSS already supports a lot of things that used to require processors, and (2) could be achieved with a simple "library" that could just be imported directly.
I agree neither of those seem like good reasons to pick tailwind.
My take is that it removes needless indirection in any codebase that already has “components” - react/vue/solid/etc, template partials, functions that return html strings, whatever. See comment here: https://news.ycombinator.com/item?id=42804831
For that reason, plus it’s concision, I find it more productive use of time compared to css-in-separate-file.
If you don’t have components for separating semantics from presentation, then tailwind is less a good fit.
A concrete example that seems like a no-brainer to me: let's add a little padding to the top and bottom of an element. "py-2" Done. In CSS, specifying padding (or margins) is 4 values... except I forget which is the first one. And what units should I use... px, pt, rem, em. Inline, same-page style, or an external .css file? If not inline, what should I name the class? Vanilla CSS literally requires 10x more time and mental attention.
> "py-2" Done. In CSS, specifying padding (or margins) is 4 values... except I forget which is the first one.
False dichotomy. You are not stuck between tailwind and "Vanilla CSS", and one can solve the issue you are presenting with any reasonable set of SASS mixins.
Do you have any links describing what you mean? I'm not a CSS guru, and perhaps I know only the "old" CSS. I did recently learn Tailwind and it's way nicer than the "old" CSS.
If modern CSS makes styling as easy as Tailwind does, I'd love to read about it.
Because of multitude of reasons. One of the big ones being never having to search through a style tag or finding a CSS file. 100% of the element styling is described in the element markup.
That is atomic CSS, and it predates tailwind by quite a bit. There is a huge marketing push behind tailwind. If you look into who made it, you'd see it wasn't their first attempt.
Why do you keep saying CSS has “caught up”? Tailwind has always just mapped to CSS, so you’ve always been able to do anything in CSS that you could do in tailwind. What has CSS done that makes you see no value in Tailwind today where you used to see value?
Oh gotcha, I must have just misunderstood the previous comment.
I want to say that tailwind also can't do inline media queries, but that's getting really nitpicky and pedantic. You can at least add a class inline that Tailwind creates a media query for in CSS, that is really handy.
It's a horrible way to do what css can do but in a dumber way with added tooling.
It is used by people that don't know css and this is where the problems start
I’ve been writing css/scss/stylus/linaria/whatever styling stuff for 18 years and I think tailwind improves life much more for css knowers than for css noobs. I prefer it over raw css for sure - I’ve written the same shit enough times that I’m happy to take some shortcuts and more than willing to pay for some tooling to do so. Tailwind hands out less abstraction rope compared to vanilla css and sass and all the rest, so much lower chance I open up a file and find some convoluted special little kingdom of abstractions that need to be handled carefully. Reduced cognitive load in the long run for a small up front learning/setup cost.
"What I don't like about Tailwind" has less to do with Tailwind itself and more about the violation of separation of content and presentation that they push so hard.
> poo-pooing on someone else's open source project
This is not some young kid doing free software out of kindness. This is a company making millions of dollars in revenue in a closed source product (tailwind UI), which is built on a foundation (tailwindCSS) that is becoming less and less needed.
> and more about the violation of separation of content and presentation that they push so hard.
As someone who's done it both ways with web sites, that separation sucked. Having to figure out which style in my CSS file was messing things up was always a pain. And Tailwind tends to be "local" by default, limiting the damage done to other elements when I style an element.
In my larger experience (not just with web sites), whether separating content and presentation is a good idea varies widely from use case to use case.
Yeah, I tried (not so hard) to like and use tailwind, but I've been using bootstrap for so long, and for my very simple needs, bootstrap was a better choice. But I wouldn't go around saying, "tailwind is unnecessary for everyone."
I'm with you. Tailwind would be great if it could be SASS'd but Tailwind is a post processor and it would be silly to build a post-post processor just to make tailwind reusable. It simply isn't a good tool for large enterprise applications. Toys, home projects, sure. But then, why learn CSS twice for occasional use? Until they solve the post processor problem, I'll stick with bootstrap. But if they do, I would definitely switch. That would be the best of both worlds.
Question for people who are good at CSS stuff. I am not.
I'm upgrading a personal Phoenix project to 1.7, and Phoenix now uses Tailwind by default. So I thought I'd try and update my one page thing to use it instead of Bootstrap.
So far, it looks like crap whereas the Bootstrap one looked 'good enough'.
What's the easiest way to get something that looks kinda sorta decent, with some nice defaults, without trying to become a designer?
Or should I just reinstall Bootstrap and be done with this.
> Or should I just reinstall Bootstrap and be done with this.
That one.
Tailwind gives you tools when you want to control the design, but you’ve got to control the design.
When you just want something that looks good and don’t mind that bootstrap-y feel, bootstrap is the way to go.
(There are projects that essentially recreate bootstrap on top of tailwind, which, in theory, might give you something like bootstrap as a starting point with the power of tailwind, but I haven’t seen it work better in practice than just using bootstrap.)
Just get one of the tailwind UX kits and use their classes as your standard style guide. I personally use flowise as it’s free with paid more complex components if needed, but there are a bunch of others out there that fill the same space.
On a new project, sure maybe going with tailwind + a theme/kit is a bit more up to date than using bootstrap. But on an existing page that already looked fine with bootstrap, why bother with the extra work?
The same can be said about Bootstrap, though. Just get a theme to make it look less bootstrapy. I think both viable ways to go, and it just boils down to personal preference (especially for hobby projects).
They are cryptic but the learning curve is not that steep. Once you get the idea, it becomes much easier (and quite pleasant for a CSS hater like me).
For example px-3 means "padding on the x axis 3 (spacing values)" and gives you padding on both left and right.
There is a (rather simple) language that you need to learn and at least for me it made things much, much better. You can probably get the feel for it in several hours of building a basic website with Tailwind (and DaisyUI I would recommend).
I am not going to argue whether that's the case, as I never managed to learn CSS enough to be productive in a convenient (for me) way. Despite of trying many times. Whereas tailwindcss "clicked" right away and gave me the awesome superpower to build whole products without having to depend on other people. Before that I hated myself for the horrible, unmaintainable mess that I created, and double hated myself later when I had to revisit the project. Since I am using tailwindcss, I never had bad experience. Of course I still have to spend time wondering how to center some element and why it doesn't work, but that's not what I am complaining about.
It might be just a personal defficiency, but it is how it is (for me).
One of the reasons Tailwind became so popular - even more so than preceding frameworks like Bootstrap - is that a lot of people who normally liked working with CSS directly fell in love with it. It removes the extra step of editing a separate CSS file without straying far from a 1:1 mapping and eliminates most of the cascading rules that have plagued frontend for decades (`group:` and friends notwithstanding). The latter is important when working on large teams because it eliminates the name bikeshedding and conflicts.
sorry, but this is just not true. The cascading issue is still there, and it gets even worse because if you have an element with class "p-1 p-0" you cannot know in advance which will take precedence.
Of course you shouldn't do that, but it happens to be the case that Phoenix does exactly that
This is not a cascading issue. This is a "You're holding it wrong" issue. And when Phoenix does write 'p-0 p-1', Phoenix and Tailwind are not a good match.
You suddenly reminded me about another good Tailwind thing: linter will highlight "p-1 p-0" as a mistake. I've never seen linters that warn on "your-custom-p1 your-custom-p0", but Tailwind makes it possible.
As someone who used and knew CSS very well, and reluctantly used tailwind, yes. I don't strongly prefer one or the other. But I will say now that I know Tailwind, when I see those large class name strings, my brain parses them shockingly fast, and they kind of melt into the background similar to comments. Also, common linter rules will order the classnames, and that they are always the same between disparate tailwind projects, all together its not nearly the annoying mess I thought it would be on first sight.
it's quicker to write, though. and many of these class names are the same in bootstrap, so I've been seeing stuff like 'p-0 m-1' in frontend projects for decades.
another huge benefit these days is with the styling living alongside the markup, it is very easy to use chatGPT or other AI tools to copy/paste and have changes made, etc. it is much less work with one file vs multiple. you can give the context super easily and take the results very quickly.
If your looking for components like bootstrap try https://flowbite.com/ for free. Tailwind also has paid components. You just copy and paste. The cool part is once you get more comfortable you can start to tweak the flowbite components.
I’d say it depends on who is paying you. If you have job security and want to tinker, then play with tailwind if you want (most trendy / loud people seem to like tailwind). If however you are working on your own project / are self funded / or have a deadline just stick with bootstrap that you know, and focus on getting your work done instead of bike shedding on the UI
Tailwind and Bootstrap and are kinda apple vs apple pie. Tailwind provides classes that still need to be stacked to build components.
It'd be easier if you were using some source for UI components, I've used TailwindUI in the past, but that's paid. I'm sure there are good free alternatives.
reinstall bootstrap and be done with it. You can look at daisyui it is closest to bootstrap. There is also shadcn ui, ui looks good but it would take you effort to port styles to your phoenix project.
I appreciate there are people who find Tailwind useful and are productive with it, but it has this clean yet generic look that I now see everywhere, because Tailwind is now everywhere.
This is conflating Tailwind and TailwindUI/shadcn/etc.
For the most part, Tailwind offers no more influence over style than normal CSS (okay, there's some exceptions... things like shadows are a bit more standardized, and indigo has gotten outside influence on color palettes as of late).
Tailwind gives you sensible defaults, but doesn't really influence your design too much. People just tend to design the sites a certain way. Especially, with ShadCn.
I feel like that's a good thing, because Tailwind's options are well-thought and work well.
I like to think of it in the same way as Inter being the new Helvetica when it comes to choosing a font for a website: lots of people do it, and it looks great, so why not?
I heard this comment about Bootstrap back this in the day but none of my Bootstrap sites looked like each other. Bootstrap saved me a lot of time because it had a lot of utility classes (like Tailwind way before Tailwind) and it never enforced a certain look.
You just loaded the classes that you wanted (unless you didn’t download the source Sass files, but that would have been silly).
My take on this problem is, good UI frameworks (i.e. tailwind + components) are still rare. So the vast majority of projects use a very small number of them. If 4-5 new quality UI projects popped up, especially if they departed more in their styling, we'd see more diversity.
I've come to realize with design, like much creative work, the trends really do seem to be set by a shockingly small number of people. I wish more people realized this, because I feel there are talented individuals out there not making their own, thinking they'll never be heard. But I suspect some of those people would be unlocking new UI's for a large chunk of the web if they would give it a go.
Tailwind is a testament to the greatness of inline styles (styling a thing without naming it), the universality of strings and also the limits of strings.
I am excited for what comes after it, until then I'll use Tailwind (reluctantly)
Was it really necessary to break all existing apps using `npx @tailwindcss`?
It's an easy enough change to `npx @tailwindcss/cli` but we now have to go back and update all Apps and templates and since it uses v4 we now have to test every App to see if anything's broken with a v4 major release.
Given its massive install base, surprised they wouldn't maintain backward compatibility with v3 and have an explicit opt-in upgrade path to v4.
Edit:
v4 did actually break all our Tailwind Apps which doesn't support `@import "tailwindcss"`, likely because we use `npx tailwindcss` without any local npm dependencies. Trying to use the existing v3 `@tailwind components` renders a useless app.css. Only solution atm is to explicitly use v3 and change all our build scripts to use `npx tailwindcss@v3`.
You’re doing something silly living without a lock file to use a tool as part of your build process. Why don’t you actually include the version of the tool you want in your dev dependencies + lock file? That way, you don’t get broken. We’ve had the solution to this problem - lock files - for 15ish years, since Ruby’s `bundle` introduced it.
Not everything is a node App. We don't have a lock file because we don't have any local npm dependencies (as already mentioned). We're using `npx tailwindcss` as-is.
You clearly have a dependency on tailwindcss (if it can break you, you depend on it), and are using npm to fetch it (npx uses npm internally, they are installed together) so you can easily solve your problem by adding a couple json files with some version numbers in them. npx will pick up and use the version from your package.json, so no workflow change other than running `npm install …` once to generate package.json for your preferred semver specifier, and package-lock.json to guarantee your builds use a known-good version from now on.
I don’t care how you do it, just make getting your dependencies deterministic based on files committed to your repo!
Happily the Tailwind hex package encourages you configure a fixed version number, so you’ll never get surprise breakage as long as you’re committing your mix.lock file as well.
I’m only suggesting package.json/package-lock.json because their projects are already using the npm ecosystem to fetch the tailwind dependency. A Makefile that does `curl $TAILWIND_GITHUB_RELEASE_URL -o ./departing/tailwind` is fine too (this is what Tailwind.hex is doing under the hood).
FFS we don't have local dependencies. Which means we don't have any local node_modules and have never ran npm install (there are no dependencies to install!). There is no lock file or dependencies.
Our Apps don't have any npm dependencies nor needs to run npm install by design, we're not going to start now, as already stated we're switching to `tailwindcss@v3` instead.
The point is this was a documented supported use-case which all our non node.js Apps used, which have now broken as a result of this release.
I also use tailwindcss in a non-node project, but use npm package / lock files to easily lock javascript / css dependencies and make renovate able to update them for me.
I've linked to why. We prefer #NoBuild solutions where we'd only use local npm deps/node_modules if we absolutely have to, and for non JS Apps we don't.
The node_modules folder is still somewhere on your system (~/.npm/_npx probably?) containing the same tailwindcss dependency files, but if it helps you sleep easier at night it’s okay to pretend it doesn’t exist.
No kidding, I thought global tools worked with fairy cloud dust, now I wont be able to sleep! But knowing there's not a going to be a bloated node_modules folder and local dependencies running different versions unnecessarily maintained in every project will definitely help.
Thanks Tailwind devs! It’s a testament to the success of the concept and the quality and consistency of execution over a seriously long time, that Tailwind became how LLMs write code for the web.
Yes, I’m a huge fan of how easy it is to whip up quick isolated prototypes in Claude artifacts.
There’s a risk of breaking changes in libs causing frustration in larger codebases, though. I’ve been working with LLMs in a Nextjs App Router codebase for about a year, and regularly struggle with models trained primarily on the older Pages Router. LLMs often produce incompatible or even mixed compatibility code. It really doesn’t matter which side of the fence your code is on, both are polluted by the other. More recent and more powerful models are getting better, but even SOTA reasoning models don’t totally solve this.
Lately I’ve taken to regularly including a text file that spells out various dependency versions and why they matter in LLM context, but there’s only so much it can do currently to overcome the weight of training on dated material. I imagine tools like Cursor will get better at doing that for us silently in the future.
There’s an interesting tension brewing between keeping dependencies up to date, especially in the volatile and brittle front end world, vs writing code the LLMs are trained on.
Question for those developers who, like me, have no f/end build step: How would I use tailwind without a f/end build step? All the examples of using tailwind 4.0 on the linked site assume a f/end build step.
My project does not use (and I have no plans to include) npm, or PostCSS, etc.
I'm pretty sure the point of using TailwindCSS is to use build step. There is another way, it uses Tailwind's CDN. But I think even the developer don't recommend it outside of development phase
If you don't want to use NPM, I can recommend Tailwind's standalone CLI
Renaming utilities like flex-shrink-* makes existing LLMs emit deprecated code today and broken code tomorrow. I wonder what the rationale is behind the renaming of various utilities (e.g. shadow-sm -> shadow-xs, flex-shrink -> shrink, decoration-slice -> box-decoration-slice, ...)
In new projects, I will probably use Tailwind v4 and constantly provide the upgrade guide as context to an LLM. In existing projects, I will continue to use Tailwind v3 until I am certain that it works alongside the tools used by my framework (React Router / Remix).
This reservation has taken firm hold on me and has made me a slower adopter of shiny new things.
I feel alright about it from a local perspective (I'm a lot more productive now than I was before), but I do wonder what it does to the overall dynamic and incentive to write shiny new things or generally update the ecosystem.
The LLMs will get more powerful, but to what extent will their work be dominated by existing tools (with lots of existent human-generated exemplar)?
There’s far less reason for humans to contribute code examples, answer questions, work on open-source projects, or even produce content knowing it’ll immediately be slurped up and resold.
Web dev will be stuck with React and Tailwind circa 2021 for a very long time.
We shouldn't really have to retrain models for them to be able to work with new versions of libraries or frameworks. That seems like a flaw in the LLM (only?) setup. One should probably be using RAG at a minimum to pull in the correct documentation and references. Something like Kapa, but not limited to a single project https://www.kapa.ai/
I’m a recent convert to tailwind. I’m very comfortable with css and I was initially turned off on the huge horizontal lines I saw in tailwind projects.
However, more and more component libraries are based on tailwind so I decided to try some immersion therapy.
Here are the top things I enjoy that was not obvious to me:
1. The class names are css shortcuts. Using them save you a lot of time. This is probably obvious to anyone who’s seriously looked at tailwind but I didn’t see that browsing the docs. I just saw nightmarishly long lines.
2. The lines look longer when you are not familiar with the class names. I initially pulled all of my class names out into a string outside my markup and included similar to how I’m used to using emotioncss. This made tailwind tolerable for me at first. However after several days I started to feel less turned off by those lines. I think it’s because I could recognize them. I will still break down a line with something like clsx.
3. clsx helps so much vs trying to entirely rely on tailwind syntax. The docs don’t discourage this at all but for some reason I thought it wasn’t idiomatic tailwind at first.
4. My app has to support a very large number of themes. Tailwind has proven to be a very attractive way of solving this problem. CSS variables are cool but the long syntax of using them is helped a lot in tailwind.
5. Adding my own custom variants is so easy and made me feel like a power user with such a small learning curve.
All of this is just my two cents to guide anyone who is like me watching from the sideline and wondering why? Why would anyone ever want to tolerate those “disgusting long lines mixed into the html”. Neo, all I see is the lady in the red dress now
It's sort of like javascript devs ignoring typescript because they never felt like they needed it. But once you start using it, it's difficult to go back.
I was in never ts/tailwind gang for a few years until I tried them.
I think the reason why tailwind is as popular as it is, is because it really ties in with the "change something, save, then immediately see the result" loop and dx of modern day web development.
Yes, this works with regular css too but it's the fact that you can do bigger changes inline quickly without making up a class (and god forbid you already have a different class affecting the same element and it gets hairy). Personally I think this is nice, it's great to immediately see results and then adjust. But dx is not the only thing that matters and there are tradeoffs too. Personally I would use tailwind for personal projects but I don't think I would try to introduce it at work.
I'll stick with 3, not rewriting so much of the codebase because taking away features is now an improvement. Not sure where dogma and performance overlap but it isn't in making @apply a hassle.
Tailwind and Sveltekit are the reason why I still love doing FE after all these years. Initially I was so sceptical of TW. I simply can't work without it now. Huge thank you to authors for their hard work.
Anyone who has ever had to deal with CSS over time knows that the biggest issue is having leftover classes. Utility first approach means this never happens.
Last time I tried v4 the automatic content detection was pretty bad. It would falsely detect tailwind classes if it seen a similar name in a string in a code file. It seemed pretty dumb.
That is more or less how it worked in v3 already, because any string could be used as a CSS class.
"The way Tailwind scans your source code for classes is intentionally very simple — we don’t actually parse or execute any of your code in the language it’s written in, we just use regular expressions to extract every string that could possibly be a class name."
The only difference in v4 is that scanning is so fast, they just scan roughly everything by default. You can still opt into manually specifying which files to scan.
In v3, one can use `blocklist` in the config to eliminate false-positives, but with the config file gone, this seems no longer possible, so I won't be upgrading.
In one project, roughly 75% of the detections were false-positives, unnecessarily bloating the CSS.
Heck yeah, cool to see Tailwind add support for transitions without Javascript.
As a burgeoning web developer, dealing with animation libraries seems like it's not worth the effort (or at least not for something as simple as a blog), so this is much appreciated.
Did they really nuke the entire js config file? I have a number of advanced use cases that depend on it, like eliminating false-positive content matches.
Tailwind suits the kind of developers who hack things together and build up technical debt and spaghetti code rather thinking about things first and designing things properly.
I don't know. In 20+ years I have seen way more abominations and spaghetti CSS using other every CSS technique.
With Tailwind at least I know what to expect, and the code in practice rarely deviates from what it's supposed to look like.
I'm all for "not building up technical debt" and "thinking about things first" but in my personal experience the anti-Tailwind crowd doesn't have much to show here in this regard. Sure: it's theoretically possible to build a perfect CSS ivory tower, I just haven't seen even a passable one in a non-trivial project, it always devolves into a mess for various reasons... often breaking the rules of the paradigms like BEM and OOCSS, often because of cutting corners here and there.
Addendum: I'm all for criticising techniques, but it's interesting that the anti-Tailwind crowd always resorts to attacking the character of the developers that use it.
I feel like it is the same with ORMs argument is always "they don't know proper SQL so they use ORM instead".
Which usually from people I know is they do know SQL and ORM and "no ORM crowd" doesn't have much to show.
Exactly the same with Tailwind, I see coworkers doing Tailwind and knowing CSS well and not being "pure vegan CSS developers".
But on the other hand we don't hire people who would utter such things like "no ORM" or "no framework" because those were also as in experience people who would create technical debt for others to deal with.
Same. Been doing this for 20+ years. I’ve worked at companies whose names are recognized and respected. My current Tailwind project is by far the most maintainable one I’ve worked on when it comes to CSS.
Hard disagree. Vanilla BEM + CSS produces a parallel component system that I find very unwelcome since React (or Vue/Svelte/etc.) already accomplishes this.
Tailwind removes this burden and helps you focus on writing actual React components when needed.
To some extent, reading between the lines of many of these comments, I think “pure CSS” designers are feeling threatened by the quality level of Tailwind sites designed by the rest of us.
Design engineers still exist, they just write more JS these days. They are still building UI and design systems and teaching craft & supporting full stack teams. The craft is there, but the tools are different.
I think the approach is different. Component style applications have to thing about all component presentation separately, web apps ressemble apps more than documents (d’uh) so it makes sense that they are designed as such.
Documents are designed holistically, you don’t care that much about how a thing (say, an image that is an aside) would look on the next page because on the next page there would be something completely different.
I think much of the debate and contention comes from the fact that many developers only worked on either web apps, or documents (e.g.: static blog, cms) and each try to convince the other group that their approach is the best.
As a once-strident critic of Tailwind for its many failings and incompatibilities with the state of the actually-modern "vanilla" web art, I am very pleased to see the huge strides they've made with v4. Being able to access the Tailwind theme through native CSS variables (they even have an example in the docs of a button component written in native CSS in an external stylesheet using native variables! Oh happy day!) is absolutely massive, and being able to use a CSS-only config is equally amazing. Finally, Tailwind feels more like it's a utility (ironic, since its claim to fame is utility classes!) which you can add to any project, rather than some bizarro "viral" framework that wants to eat sensible architectures and lives in its own JavaScript-y silo.
Perhaps all the criticism over the years actually had an effect. Or maybe they finally arrived at good conclusions on their own. Either way, I suspect many of the pro/anti-Tailwind arguments are no longer relevant, and that's a Very Good Thing. Now we can get down to business and ship product.
I'm still a critic in terms of actually using it, but what I find amazing about tailwind is how amenable it is to AI-generated workflows. It seriously works _so good_. Anything can be expressed, and systematically. There's something amazingly useful there.
> what I find amazing about tailwind is how amenable it is to AI-generated workflows
It's highly amenable to human workflows as well. Of course, humans are more disparate than AIs so it doesn't suit all humans - no tool can. But it sure does seem like a majority of humans web developers like it.
So, I wonder how AI is going to work with the new upgrade. Are teams going to delay upgrading until there is proper Claude support, for example?
Should work well since there aren’t any removal of old features and classes.
Its horrible, annoying and gets in the way
> I suspect many of the pro/anti-Tailwind arguments are no longer relevant
I feel there are two issues with Tailwind for me as a designer / design engineer.
* First, JavaScript/Tailwind engineers have hijacked the conversation on design. Instead of "utility-first," "dead code elimination," and "type-safe CSS" I focus more on desing systems. Whether to use Perfect Fifth or Perfect Fourth in typography for example.
* Second, Tailwind makes it impossible for me to participate in the actual craft. Design decisions get buried in React components with cryptic expressions like `flex items-center shadow-lg p-6 hover:bg-gray-50 dark:bg-gray-800 py-[calc(theme(spacing[2.5])-1px)]`. This might make sense for JavaScript engineers, but blocks/makes it hard for systematic design. Instead of expressing precise mathematical relationships through CSS, we're essentially writing inline styles with better ergonomics.
Tailwind has solved a lot of problems. And this is coming from someone who doesn't use it half the time.
Some thoughts about this topic, not necessarily in disagreement:
- Designers seldom think in the way you describe (explicit computer-readable rules, systems of design). A lot of designers are coming from crafts that are more implicit. It doesn't surprise me design business logic is not the topic of conversation.
- You need to update your tailwind classes to reflect your design business logic. Don't do "bg-gray", do "on-surface-emphasis" or whatever business logic. This is just a simple config change.
- You probably brought up modular scale as just one example, but modular type has become near myopic dogma of frontend engineers who haven't had any typesetting experience. A scale of 1.25 vs 1.5 is so in the weeds as to be useless. There are so many alternative ways to set type (e.g. take lessons from CJK typesetting) or innovate typography on the web (e.g. build your own leading-trim implementation!).
I'm a designer, so I absolutely think in terms of design systems where typography is just one part of the puzzle. There are, of course, many ways to set type — but the point was: no Tailwind engineer talks about typographic scales in the first place. Systematic thinking is absent, which is naturally built in CSS.
Tailwind itself is a design system. The authors actually put together a short book explaining their point of view on design systems (without referencing Tailwind) and I found it very difficult to argue with any of their points.
Then you look at Tailwind and realize it’s almost entirely that book packaged for others to use.
https://www.refactoringui.com/
The Tailwind library names grades of colors and sizes for you, but the book is ultimately about iterating design so that you can create your own design system. From the perspective of the book, the Tailwind defaults are inadequate as a design system.
But the Tailwind configuration provides a solid structure for your own though.
just like CSS
Not really the same, although I realize it can seem that way.
If you go low level enough everything technically fits that bill, it’s just a matter of how much work you have do to put the structure in place and what the burden is for other people to learn it.
It’s akin to raw Perl vs Ruby on Rails. You can do it that way, nothing is stopping you…but there are compelling reasons not to.
That's exactly the argument I'm making about Tailwind. Inadequate as a design system. You have these bundles of rules just a thin step above CSS and there's nothing obvious about how things should look.
I'm kind of surprised why this is even relevant to you. The designers I know work in Figma. The designer and the engineer collaborate to make sure the design isn't too hard to implement, but other than that the designer shouldn't care about whether developers are using Tailwind, StyleX, Sass, vanilla, or whatever.
I hardly expect a designer to take responsibility for something as transient and idiosyncratic as "oh, but this is hard in Tailwind."
I'm (not) surprised typographic scales are non-relevant for Tailwind developers
Maybe Tailwind is useful for bigger projects, but I tend to prefer component based class instead. The biggest DX for CSS is using the web inspector and directly modifying the DOM, then copying the adjusted values to the text editor. For a much serious project, I go with the balsamiq -> figma route to create an actual design system.
You can allow the inspector to access the filesystem and modify the files without having to copy/paste for even better DX.
Man their very playground at https://play.tailwindcss.com/ gives this unreadable crap (sorry for swearing) for the very first `div` on the first line:
How can anyone prefer this gobbledygook over a nice CSS class declaration with line-separated standard CSS properties ? How can one even maintain this ?Maybe the modern generation of web developers have IQ 200 and 20/20 vision with eidetic memory and I should just put myself to pasture.
Because your not thinking of styles practically. You don't review style declarations, you review the rendered page/component. You see with your eyes that a component has the wrong border color, and AFTER THAT you go to your component code, find the border color declaration (if any), and update it/add it. Sometimes you'll even inspect the element in browser, and find the faulty class directly, making it even easier to target in code.
The Tailwind classes are "unreadable crap", that's true, but it's not a problem because you don't "read" it, no one does. You roughly parse it and edit it.
Exactly, it's not like a novel where you are trying to read the entire thing. And it's an advantage because it is easier to parse. If I'm trying to change the color on that element, I have a very good idea what controls that. As opposed to something like "card_wrapper card_wrapper--striped". That certainly looks better, but if I'm just there to change the grid, now it's a more complicated change. In Tailwind, I can just look, see "grid-cols-[1fr_2.5rem_auto_2.5rem_1fr]" and know that not only that's where to change it, but that I can also change the classname there without worrying about a regression in some other element somewhere else. Whereas with "card_wrapper card_wrapper--striped", well what controls the grid? I have to look in another file, and I also have to be concerned about every other place those classes are used. (Or I have to add new one-off classnames, at which point the complaint about long classnames holds less weight.)
Personally I prefer how PandaCSS does it - similar end result with atomic css at compile time but it just lets you write your styles as readable objects instead of as insane strings.
Terrible take.
Take a guess at what “dark:bg-gray-950”, “bg-white” or “min-h-screen” means. You get them from context.
Imagine if you put a little bit of effort into learning Tailwind. You’d get the more complex declarations as well.
As to why it’s better than a class declaration, a lot has been written about using atomic, composable utility classes over reams of “write-once” class declarations.
I do not disagree that there are one or two recognizable elements in that encoded line-noise. Not sure what is the "terrible take" about it - if you take a poll, most would agree that it requires far too much eye-strain to read, far too much cognitive burden to parse, decode and mentally map to concepts.
Its like deciding to code your entire your app using regexes - all in long single lines without comments.
No one cares what your typography ratio is if you can’t get it in front of a user quickly enough (dead code elimination), reliably enough (type safe), or cost effectively enough (i.e. if you have to pay for more developer time to implement the same work).
Tailwind is a tool for craftspeople, not artists. It democratises design by making it simpler. For folks that are really good designers, they should be happy that they can up their prices knowing that customers are paying for their expert eye, rather than just the basics again and again.
Tailwind does not democratize design. Tailwind is generally 1:1 to CSS, sometimes 1:2 or 1:3. It's such a thin layer over CSS that you have to remember all the CSS. That does not make design easy or hard. You don't give people Tailwind and end up with design as beautiful as ShadCN, even though ShadCN in some perspective is just another wave of stereotypical startup design. The ability to go from blank button to beautiful Tailwind button is all on the author, not the fact that you're writing in a new lightweight inline syntax.
When I read the Tailwind book, my takeaway was their design philosophy was about the speed of iteration and how that interacts with designs whose parameters are too interdependent. Tailwind follows that philosophy by encouraging ad-hoc repeated edits over DRY. In that sense StyleX also fits the Tailwind philosophy very well even though StyleX is an even thinner layer over CSS.
I don’t really agree. You have curated colour palettes, so if you want a red, you’ve got red-50 to red-950, rather than an entire RGB colour space.
Similarly for font sizes, you don’t have to decide on a pixel size, just whether it’s small, large, extra large, etc. Border radii. Border widths. Padding.
There are lots of “sensible” defaults so you don’t have to pick even the units (should I use px or pt or em or rem or vw or ch or…) before we even talk about the numbers associated with those units.
The Reactoring UI book would find whatever structure of defaults given to you as very inadequate for a design system. The book is about an iteration process for creating your own design system. The Tailwind library happens to empower that design process.
But by default there's basically no opinion on what even a button should look like or how colors should be used on your website. You have to create your own abstraction such as "brand-color" and "brand-primary". You have to create your own design system, as there is no Tailwind default button or anything.
If you talk about a default Tailwind look people might be confused and think of ShadCN.
Just because you can build great things with Tailwind doesn’t mean it’s not democratising design. In the same way as putting frets on a guitar helps amateur players make better music without stopping great players doing their thing, Tailwind is the “frets” on CSS that make sure your hands play the right notes. You can still get it wrong, and you can do inspired or uninspiring design with Tailwind, the same as any tool.
You should really not do it like that,
--corporate-main-primary, secondary etc
Then map that to red-50 if you really want to.
but a design lives in cmyk/ral/rgb/hex not red-650
The go
--action-button-cta-hover etc that could map to corp primary or some other stuff
> Type safe typography ratio
Please explain how this is better than expressing typographic scales with CSS variables and calc()?
You're using a right angle bracket there like I said that. I didn't.
I would find it difficult to explain, especially given that this is exactly what Tailwind does: https://tailwindcss.com/docs/font-size.
> No one cares what your typography ratio is if you can’t get it in front of a user [...] reliably enough (type safe)
i mean it's not exactly what you said, but c'mon, that's obviously what they meant.
Ok fair enough. I was actually talking about the whole of Tailwind rather than just the typography ratios, but I can see how I could be understood in that way. My mistake. Either way, Tailwind works in exactly the way OP describes as their counter example.
I just want the color palette of the Tailwind CSS.
Their palette is really neat. I always check it out when I need colour inspiration, especially for "cold greys" and other "state" colours (green for success, red for error, yellow for warning...).
Yes, someone should make a tailwind inspired bootstrap theme.
I actually did this for a former company that had a Bootstrap-based app - the designers started bugging that "we need to use Tailwind", and I couldn't figure out why they cared what tech we used.
In talking with them, realized they just were bored with our theme, ha. Not publicly accessible though, sorry. I should probably recreate this.
yeah, the palette is neat. My main gripe with Tailwind is that it blends a set of design tokens (which I like) with a technology to apply them (which I don't like)
Maybe check out Open Props?
https://open-props.style/
Just copy and paste them out?
tailwindcolor.com is good for that
Radix Colors ?
I don't want to use React
CSS has become significantly more user-friendly than in the past, with most browsers now behaving consistently. It's worth learning as there is no build step involved, and it avoids cluttering your markup with excessive code.
You could opt to use style attributes directly within your HTML. Historically, we avoided this to maintain a separation of concerns, but it's puzzling why some prefer reintroducing similar methods. Is it just to save a few keystrokes? Using style attributes even seems more straightforward since it doesn't require translating code in your head.
I simply don't see the appeal.
There's a bunch of things you can't do with style attributes, just to pick a few:
- Pseudo-classes (e.g., :hover, :focus)
- Pseudo-elements (e.g., ::before, ::after)
- Media queries
- Keyframes and animations
And the DX in a larger project isn't great either.
On the other hand, this upcoming standard is a great addition for collocating styles https://developer.mozilla.org/en-US/docs/Web/CSS/@scope
https://developer.mozilla.org/en-US/docs/Web/CSS/@layer also solves a lot of problems.
Indeed, it also solves a lot of problems
These days tailwind is often paired with a component abstraction system that takes place of css classes as an abstraction system. Component abstraction achieves an even more powerful separation of semantics from styling, compare:
vs: In both cases you need to go find the “hero” abstraction, but in component world we are also abstracting over the HTML tag name in addition to whatever styling stuff.When it comes to defining the “stylistic detail” in either case, it has been separated from the “content” which is our page source file. I am happy to pay a build step to get better separation of concerns - content from presentation.
> I simply don't see the appeal.
- Not having to name CSS classes
- Easier to read as it's inline with the rest of your HTML
- Standardised way of naming so that everywhere uses the same conventions
- Not having to manage a separate file and remove unused components
- Being able to use media queries, which I couldn't do in a style tag
- No risk of changing a class that is used elsewhere. CSS has global scoping which has its benefits but is risky.
no, a single html attribute containing "relative before:absolute before:top-0 before:h-px before:w-[200vw] before:bg-gray-950/5 dark:before:bg-white/10 before:-left-[100vw] after:absolute after:bottom-0 after:h-px after:w-[200vw] after:bg-gray-950/5 dark:after:bg-white/10 after:-left-[100vw]" is not "easier to read" (example taken at random from the Tailwind homepage)
Just viewing the source of the Tailwind homepage breaks me out in a cold sweat. And then there's:
Easier to figure out what to change without affecting other HTML components, though.
Individually applied styles kinda defeats the purpose of cascading style sheets though.
As someone who's quite conversant with regular CSS, I really did like the ease of applying whatever style I wanted right in the code without needing to "worry" about whether this div is a "panel" or a "hero" or whatever, but it really does tend to make a huge mess of my HTML in very short order.
Have y'all not heard of css modules or BEM?
pointless make-work compared to inline-styles-like workflow like tailwind, if you have a component framework
You might like Styled Components then, if you're using React anyway. Not sure if there's similar systems for other frameworks. I don't consider it pointless make-work to develop a consistent stylesheet to use throughout your app though.
Styled Components is too low-level (let’s name every div!!!) and comes with a substantial performance cost. Tailwind is a much better option.
> a substantial performance cost
I believe the Babel plugin eliminates most of the performance cost.
The naming is double-edged. Often you want to re-use your styled element, so the fact that it has a name from the get-go makes that really easy. But you're right, sometimes it's annoying to pull bits out that you didn't really want to.
Ultimately I went back to CSS Modules. I just don't understand why I'd want to the appeal of Tailwind.. I'd have to learn a new DSL that ultimately gives me less control.
Use PandaCSS, the result is similar but the syntax is a readable object instead of… that
The problem is that with bootstrap I have card, table, etc. With tailwind I have an unreadable alpabet soup when I am not a designer but a developer and am not familiar with tailwind.
And then you build on that, and you have card-alert, card-message card-message-small, card-body-alert, card-body-message, card-form, card-login-form together with extra sass variables for them.
And then you ask "why not just have variable for each component, not each component's style?" and this is where tailwind steps in.
This is the big one for me. In any big enough or unfamiliar frontend project, my go-to way to explore the codebase is to launch the front-end, and use the inspector to check the elements, and then search-back in the codebase the relevant classes to see what page/component display that, and how does it fetches the data.
If there is only an alphabet soup, I no longer have a simple set of classes I can grep the codebase with to quickly find the relevant components.
This is just not true. You can absolutely grep the soup (I do it daily). Most UI components share a lot of common baselines but include a specific modification for use in place (often a color or extra spacing). That means most of the time, the entire class string is unique to that element, even if the classes themselves are not. At most, you might have a couple of duplications, but then you should probably be looking at a template level component if the functionality is related.
`mx-4 py-2 rounded-xl shadow bg-green-500` is just as easy to global-search for as `notice--success`
Use the component library’s inspector/devtools to identify components. Eg in a React app, look at the React component tree rather than the DOM tree
I greatly agree with you, but should mention that there is DaisyUI which is a Tailwind plugin that adds these for you. It seems inspired by Bootstrap and others: https://daisyui.com/
> Easier to read as it's inline with the rest of your HTML
I really don't think a big blob of text with a bunch of unnamed divs is easier to read.
The styles night be easier to find but they're absolutely not easier to read.
Big one: Way smaller CSS bundle size.
It's because we've normalized React and tight coupling. Styling belongs to components, not in design systems. I feel the JavaScript-first engineering ecosystem needs brave new design-led companies, who see the power of modern CSS and systematic design.
> Historically, we avoided this to maintain a separation of concerns, but it's puzzling why some prefer reintroducing similar methods. Is it just to save a few keystrokes?
In bigger projects, if we start looking at the amount of files one has to deal with, Tailwind becomes very appealing. We've went through the regular `.css` route but then you have weird names, and, potentially, duplications or even conflicts. `css modules` is an option but you've now essentially duplicating the number of files that you have for each component / page. `sass` or `less` essentially bring the problems from `css modules` and regular `.css` into one.
I don't inherently like or dislike Tailwind (although I very much started by absolutely disliking it) but you feel its value in a project with 200+ files composed of components and pages
You're seriously advocating for inline styles in the year 2025, it does not surprise me you are confused.
My initial reaction to Tailwind was: what a pain. I already know CSS, now I have to learn CSS again...
I imagine its how parents might feel when they go to help their children with math homework only to find the math is now totally different from when they were in school and their methods (while still valid) for solving problems are no longer accepted by the school and their child is annoyed by having to reconcile the two systems...
I get the, tailwind works well in a team and scales nicely and you just have to use it, mentality. I've experienced it.
I still prefer a plain style sheets that targets elements by a class or tag (especially since CSS supports nested selectors!).
There is an issue in managing stylesheets, and for that I really like how Remix/React Router manages CSS where CSS flies are defined and applied at the route level. Where that isn't enough or dynamic styles are too complex for a .css file:
is always available.CSS is so powerful, flexible, and extensible, tailwind feels like a limitation rather than an enhancement. I don't understand the continued appeal, but clearly many others do. I'm not sure why, but I am confident we'll all have moved on to something else in another 3 or 4 years too.
I agree it’s frustrating initially to re-learn CSS… I used to make the same arguments. But after contributing to an open-source project using Tailwind I got up to speed, and now I feel differently.
Tailwind is essentially just stenography for style={{…}} - a single utility takes 15 characters that would take multiple lines in a .css file or style object. It greatly reduces the amount of time I need to spend googling stuff like “visual text replacement css” or perusing various css cheat sheets or skimming through css-tricks blog posts from 8 years ago. Instead I always go to tailwind docs, and quickly learn the utility class that just does the thing I want. A surprising amount of it fits in my brain cache, much more than trying to cache the css for all the tasks I might need to do in a layout.
I think it’s because now your entire component is contained in a single file. No more separately messing around with CSS. The styles are right there on the element they apply to without having to cross reference anything.
You could do this with just the css attribute, but that has the issue that everyone has always been taught it is wrong to do that, and a list of strings that contain a bunch of utility is easier than writing those plain CSS objects.
> You could do this with just the css attribute, but that has the issue that everyone has always been taught it is wrong to do that
But why is it wrong to use the style attribute? What makes using tailwind to do the same thing "not wrong"?
Also this https://tailwindcss.com/docs/hover-focus-and-other-states#us... and https://tailwindcss.com/docs/hover-focus-and-other-states#st... look like reinventing the Cascading of CSS with an awful syntax.
> But why is it wrong to use the style attribute? What makes using tailwind to do the same thing "not wrong"?
The time people were taught it was wrong is thr time when all your elements were rendered on the server and the style was duplicated for every component it applied to.
Client rendered JS only sends it over the wire once and then duplicates it on the client.
Tailwind only allows a few options, so it’s less likely you have slightly different styles everywhere.
I think the awful syntax you talk about is really nice, since it covers 99% of everything I ever need to do with it. The cascading part of CSS is really cool, but 99% of the time it’s confusing when I don’t need it.
Tailwind I use for hobby projects but we’re still sticking with style={{…}} at Notion. Since the app launched there’s been many generations of CSS-for-React (Airbnb Aphrodite era, styled-components/Emotion era, styled-jsx/linaria era, CSS modules era, Tailwind era) come up, get hype, and then thrown in the trash heap. Probably the best move for us would be an optimizing compiler for style={{…}} or our useStyles hook.
I think it's also about automatically purging and slimming down your CSS, which is easier to do when you're just comparing tokens.
Although nowadays I'm sure they could technically do the same thing with the built in parsers without having to rely on just simple tokens.
Limitation reduces available complexity and that’s why tailwind wins. It’s a composable, standardized, and modularized wrapper around a very massive and complex system. That’s a big advancement.
I'm learning math with my kid and it's not different to what I learned. Can still solve everything quickly.
On the other hand there are those posts on social media mixing multiplication and division and telling you there is only one true answer to those. Tailwind isn't that bad, but it's more into this direction for me as an old fart ;)
In the US you can get all the right answers on a test and still fail
I love tailwind, used in 3 projects in the past 4 years, it’s intuitive, well documented, simple. I don’t miss the days of emotion and styled components where I would have to think of a name for every styled div in the project, with tailwind a container is just a div and a few classes nothing else. Less bike shedding discussion, less brain cycles spent naming things, less time wasted in reviews.
> I don’t miss the days of emotion and styled components where I would have to think of a name for every styled div in the project
I see people mention this issue fairly frequently, and it puzzles me a little. I have never once spent probably more than 1 second thinking about what to name something. Is it actually a blocker for some people? Are you really paralysed by this?
especially since with any decent CSS solution (any css in js, or CSS modules) you can reuse names
Like really, I use Styled Components, just call it a Wrapper or InnerWrapper or Row or whatever and move on
There was a time when BEM ruled (and scarred) the world. But names aren't a problem if you abandon the C in CSS and scope all styles to component.
What I don't understand is why BEM is scarring. If you're talking about the reason or timing something looks different, you must have named it in that conversation. Just use that name.
"When the menu is wide, the items' icons and text should be visible. When it's skinny, only the icons should be visible. This button toggles between them."
Or I could just express this in code once - in the spot where I attach the class names to the HTML - instead of attaching class names, just attach styles.
I'd say BEM was a passing fad, but didn't rule the world. I also think tailwind will suffer the same fate, but we'll see how it plays out.
> a few classes
You must be working with very good product owners then. The ones I've worked with love to specify the hell out of every possible detail. Like a web form is their personal HGTV renovation. I tried tailwind once and the classes ended up being an order of magnitude more than the markup. It got hard to read, quickly.
you can use @apply to merge the various utility classes together in to something resembling a name, like
.btn-primary { @apply py-2 px-5 bg-violet-500 text-white font-semibold rounded-full shadow-md hover:bg-violet-700 focus:outline-none focus:ring focus:ring-violet-400 focus:ring-opacity-75; }
But their v3 docs seem to be very against this.
"Whatever you do, don’t use @apply just to make things look “cleaner”. Yes, HTML templates littered with Tailwind classes are kind of ugly. Making changes in a project that has tons of custom CSS is worse."
Reasons:
* You have to think up class names all the time — nothing will slow you down or drain your energy like coming up with a class name for something that doesn’t deserve to be named.
* You have to jump between multiple files to make changes — which is a way bigger workflow killer than you’d think before co-locating everything together.
* Changing styles is scarier — CSS is global, are you sure you can change the min-width value in that class without breaking something in another part of the site?
Yet... my experience using projects that use tailwind is that every button everywhere is styled the same way, but it's repeated in multiple areas. The 'kinda ugly' part, but also... it's repeated in multiple places. Trying to change the universal focus behaviour of buttons in a project like this is hard, because... I can't search focus:outline-none without finding everything that has 'focus:outline-none' on it. I can't just search/replace, because it'll impact other stuff.
So I end up spending way too much time trawling through way too many scattered specific styles all over a codebase, vs having a defined 'btn' style someplace. "well, that's just the project's fault"... possibly, but it seems to be the promoted/preferred/evangelized way of using tailwind, judging by the projects I've had to get involved with the past few years. IME, this approach may have good short term benefits, but poorer longer term maintenance, doubly so when the original people are no longer involved in the project, and outsiders have to come in to deal with it.
I agree with Tailwind's stance on this. You really don't need @apply if you're breaking things down to smaller components. I often see people have things like <ul><li className="long_list_of_classes">text1</li><li className="long_list_of_classes">text2</li>...</ul>. This is where I think we need a linter to warn against things like that. Make those <li>'s a component!
I have bern heavy Tailwind user from before v1. It actually doesnt matter where you make the class grouping. You can make it in your templating language or you can make it in @apply. I prefer @apply because the same grouping can be reused if done correctly. @apply is great.
The reason they are discouraging @appply is because its hard feature to implement and many people dont understand how it works so they get to problems and create issues. It bothers Authors so much they have always been considering taking @apply out but i think they know big chunk of the userbase would leave to different similar project.
Why not just do <ul class="my-class">…</ul> and then apply the styles to ul.my-class > li ?
Wait, what? You want to make every li/dt/etc. component? That's insane.
For buttons, I think the 'blessed' way to do it is to use (react) components and have the tailwind classes encapsulated there. It makes sense; you have a layer of abstraction where the implementation of your theme is in the "lower level building blocks" of your components. (Call it a component library if you want)
I generally only use @apply when there are some heavier external interactive libraries that are hard to style. Like for example if you're embedding markup in your application, and you need to apply a set of styles to the markup it generates, and you can't do that directly in react because you don't control that part.
> I can't search focus:outline-none without finding everything that has 'focus:outline-none'
Would a regex not work? Something like <button[^>]*?focus:outline-none
I generally use tailwind in combination with daisyui, and I don’t think about styling a lot any more beyond choosing the proper theme.
Gave it a go for several projects, but didn't like it... for big projects it gets messy, fast. It also feels like it has become the new bootstrap.
I'm very happy with my current CSS-in-JS workflow. Crafting good old css with LLM help. You just show the LLM a pic, ask for the components.... boom, done (with proper naming, etc)
This is actually one of the main reasons I avoid react when I have the option. Styling in react is terrible, I'll use tailwind with it but only as the least bad option.
If I am using a frontend framework and a build step, svelte and astro are nice depending on the use case. I can style with plain old CSS and rarely have to reach for class names, if you keep components small you can get away with element selectors and let the framework scope styles at build time.
I used tailwind for my site and ended up liking it a lot, but maybe for reasons that are not often mentioned? The real value of tailwind is being able to read all the styles that affect a an element in one place. Sure the classnames can get long, but it’s still a lot faster to read that long line, than open the browser tools each time or scroll up and down one (or many) stylesheets.
Then when you come back to that code later, you can confidently edit it without worrying about causing changes to other elements.
The cascading nature of CSS is still helpful, but I find that I usually want to limit my styling to just one element. For all the rest I go back to css but I wrote very little css because I usually just want to get the whitespace right.
I think that is exactly why tailwind is good and nice. Although I also like that it makes “how do I do X?” a quick doc search instead of a 30 minute research project
> real value of tailwind is being able to read all the styles that affect a an element in one place
there are helpers for that in the IDE (e.g., "Show Applied Styles for Tag" in Intellij) or even in chrome dev tools that show all this in a readable way. Tailwind snippets mentioned in this HN topic look kind of scary in comparison.
The difference is with tailwind that information is stored as text in source control. So you can parse it with nothing but your eyes in GitHub or by looking at a diff, without relying on any extra tooling.
I kind of agree but the same problem exists. If you add text-xl to a div and have nested divs and spans, they'll all be inheriting text-xl so for these nested elements, you also have to look up the element's lineage to find what's causing the text-xl.
But overall it's a bit easier yes.
That's the css cascade, not a tailwind issue.
There's a clear pattern in every "Tailwind or not tailwind" conversation (which happens everytime Tailwind is mentioned).
There's those that never used it for more than 30 minutes, that just tried it out or just skimmed through the docs. Those are the people that hate it and prefer "vanilla CSS" or similar.
Then there's the people that actually used it for a real project, within a team with more than 1 single person. Those are the people that understand its value, accept its trade offs and love it.
I've seen a lot of people jump from the first group to the second group. I've seen almost none jump from the second to the first.
That's why Tailwind is so successful.
It might not be beautiful in the eye of the purist, but it's absolutely fantastic in the eye of the builder and pragmatic.
I think I don't fit in either of your groups.
I’m not against Tailwind, but I didn't used it yet because I struggle to see why it's a better approach compared to other options like Web Components or React Styled Components.
The biggest issue I have with Tailwind is how it clutters the HTML with a ton of utility classes making the HTML harder to read and maintain. Of course I see Tailwind being better than using large global CSS files with the classic CSS approach of naming html tags. But we do have ways where the CSS is scoped to a component without polluting the global namespace. Like Web Components and Styled Components. Both keep styles tied directly to the component (or more general, a specific group of html tags), making it easy to see which styles apply where.
And yes, with them there’s no need for global class names, without having to worry about unwanted side effects or clashes. If I remove a component, I also remove its associated styles without worrying about unused CSS being left behind since both are tied together. Plus, there’s no risk of one component's styles unintentionally affecting another (thanks to shadow DOMs).
I really value keeping HTML very short and readable by not mixing presentational styles directly in the markup. Tailwind’s approach, where the styling is all in the class attributes, makes the HTML feel cluttered, especially when you have long class lists on a single line, and GOD forbid you have actual class names to use there. It’s harder to understand what styles are applied at a glance since you cant even have it well indented, and it clearly reminds many reasons why we moved away from the inline style attribute in HTML in the first place. (Yes, we didn't left it for its limitations like pseudo classes and @media queries, they didn't even exist, we didn't add those new features because no one wanted to get back to those inline styling)
So, while I don’t hate Tailwind, I just don’t see the clear advantages over Web Components or Styled Components in terms of readability, maintainability, and separation of concerns, while I do have important unanswered important concerns about using it...
Yes, I've read the docs but never tried it out, I don't hate it, but I can't understand why I would choose it over other options. The fact of having a million classes in the middle of plain HTML makes them both unreadable for me.
And No, I don't like huge CSS files either, or the classic approach of using them. But it is hard for me to see why tailwind is a better approach than working with Web Components, or React with Styled components.
These two approaches allows me to not have to read presentational things in the middle of my html, and allow my html to be more clear and readable. I don't have to use CSS class names, it's easy to identify which CSS applies where, so, if you remove the component, you remove the CSS too, you don't end serving unused CSS rules. Each can have CSS not leaking to the global scope, and there is no risk on changing styles of another element...
So, there is no hate for me, but it is very hard for me to see the benefits of tailwind over these two approaches, and I really dislike the idea of having to read html elements with huge styling rules cluttering my html files, and worse, having all of them in a single line makin it hard to understand all the applied styling.
We left using style tag from HTML mostly for that reason, and not because of its current limitations (like not being able to use pseudo classes, media, etc)
> I’m not against Tailwind, but I didn't used it yet because I struggle to see why it's a better approach compared to other options like Web Components or React Styled Components.
> The biggest issue I have with Tailwind is how it clutters the HTML
You're 100% clearly in the first group. Maybe I shouldn't have said "hate" in that group, just people that don't like it or see its benefits.
> Like Web Components
That's a nice solution, but in practice as of today and relatively speaking: nobody is using them.
> and Styled Components
Except the performance is a lot worse. And you still have to come up with names for every single div that needs a minimal one line style.
And both of these solutions end up with huge CSS files. Huge CSS files are worse than having larger HTML markup, because CSS is a blocking resource and HTML is not.
> I really value keeping HTML very short and readable by not mixing presentational styles directly in the markup
People used to say this about React, they preferred their HTML separate from their JavaScript, all nice and clean. I'm now 150% sure you're in the first group.
> Yes, I've read the docs but never tried it out, I don't hate it, but I can't understand why I would choose it over other options. The fact of having a million classes in the middle of plain HTML makes them both unreadable for me.
Alright, now you've recognized it.
> These two approaches allows me to not have to read presentational things in the middle of my html, and allow my html to be more clear and readable.
That's a non issue. There are extensions that will just hide classnames. You're just blending your mind looking for reasosn to justify your "I don't like it".
I promise the day you use it in a real life project where you're working with > 3 other people you will understand it's benefits, and how having "large class lists" is a non-issue and a totally acceptable trade off over the practical benefits it provides. Both on performance of the resulting CSS and maintainability over a large period of time. And think in the insane amount of discussions you'll avoid regarding if we're calling this div "styledDivWrapper" or "WraperContent" or "CardWrapper" or ".card__item--dark". Not an issue if you work alone, but when working with others this becomes a real annoyance that tailwind completely removes.
Tailwind is not for your, don't use it.
Tailwind is not for purists and architecture philosophers.
Tailwind is for pragmatic people, working on real life projects within teams where they have to ship and spend less time philosophizing on the purity and beauty of things.
"Build times reduced", "no more @tailwind directives", "No more js configuration", "Designed for the modern web".
To me, this screams "CSS now can do everything we used to do ourselves, but let's keep pretending that we are still needed somehow"
If you going to hate on it, at least try understand what it is and why people use it.
It's not "hate". It's just that I don't see the value that it brings today.
Whether you enjoy utility classes isn't really related at all to what css supports.
Maybe you are making my point?
If tailwind was "just utility classes", fine. But what business would it be there if they just published a bunch of CSS files with their styles?
With modern CSS, what problem are they really solving now?
As someone who made a competing product along these lines (that got no attention or traction): Tailwind gives CSS a "place" in the codebase. It benefits orgs, not necessarily apps. I didn't get it at first either. But it's very useful to the people to whom it's useful.
> Tailwind gives CSS a "place" in the codebase. It benefits orgs, not necessarily apps.
That is a better argument. But couldn't we be able to achieve that by, e.g:
- Create one standard HTML document with a predefined structure and including all the web components needed by your product.
- Having all designers and frontend developers developing their CSS (or SCSS) against this single base document
This would be basically the CSS Zen Garden approach. It would still keep separation of content and styling and it would create a "place" for styling code.
This works for products with a very limited scope that are mostly content focused, with a very small design team so everyone can agree to use the very limited toolkit in standards.html. The approach of saying “All ui shall only use these 29 components, anything else is forbidden” is not going to fly in a company with 10s of designers and 100s of engineers.
We tried this style at Airbnb and it turns out forcing all UI changes - from either designers or engineers - to acquire a single exclusive lock on standards.html leads to a fuckton of contention and frustration, and soon people are just going to yolo their own thing totally ignoring the pristine blessed system because the system doesn’t work.
The art of design systems isn’t a single technical approach - it’s finding an optimal workflow so your design engineers can build a UI toolkit that your product teams will actually adopt and contribute to, within the constraints of your existing tech stack & organization.
There are more "modern" ways to do this for large organizations like Storybook. Tailwind is a proposition for a small business that has a very small budget, want to buy a ready-theme and then make slight modifications. In a sense, no, it doesn't make any sense beyond that to use it. And once you use a good React/web-components framework, you realize there isn't really much value there as you shouldn't be really changing the CSS from page to another.
The process for large orgs is tedious and too lengthy/expensive for the small ones. Imagine having to go through planning, visualization, creating the component (or adding props for customization, writing e2e tests, publishing it to storybook with docs, and then finally adding it to your page and get it pipelined in the merge CI/CD process. A small org with tailwind just open the page in question and add a class to the html element.
As others have said, this is exactly what many large orgs do, but in a slightly higher-tech / more polished way with tools like Storybook, essentially creating their own CSS libraries and component libraries.
IMO a decent analogy is that Tailwind is to the above as something like Shopify is to being large enough to build your own ecommerce platform from scratch.
What is stopping from someone just turning all those utility classes into a single CSS file and completely get rid of the post-processor stuff?
> I didn't get it at first either.
maybe you got it wrong? CSS already have its place and work great as .css files
In my experience, the main problem it solves is the fact that styling in react is still a pain in the butt.
What value does Rails provide to Ruby?
Does Ruby have an ORM/HTTP request handler/URL router in the standard library?
I am not sure I follow the analogy. If all you are taking from tailwind is the utility classes, fine. This is the part that provides value. But tailwind is not just that, is it?
Rails is a fully formed opinion on how you should write a web app in Ruby and all the various technical components you need to fully realize that opinion.
Tailwind is a fully formed opinion on how to use CSS (utility classes etc.) and all the various technical components you need to fully realize that opinion.
Thinking of Tailwind as just a bunch of regular CSS utility components is misunderstanding the scope of the project. That alone has a lot of tradeoffs and compromises - the file size is absurd and you can't bundle things into components, you also can't have arbitrary values in the utility classes. It wouldn't be a complete opinion on 'the best way to use utility classes', or however you want to frame Tailwind.
"Basically just inline CSS, but less fiddly and much more optimizable than the style attribute" was always the selling point of Tailwind in the first place.
But it's not just inline css though. The length of inline css string would almost always be 3 times longer than tailwind classes string.
Also inline css doesn't allow media queries, pseudo classes, etc., which is a big deal.
Then, yes. But nowadays CSS is a lot more powerful and has caught up. So why bother with Tailwind?
CSS has become more confusing over time, not less confusing, so the upside of a utility class approach like Tailwind is also improving over time rather than decreasing.
Tailwind solves css confusion by presenting a “paved road” for many tasks. Want to do “thing”? Just look up “thing” in the tailwind docs, add “thing-2” to your class, done in 2 minutes. Rather than look up “thing” on google, skim several articles, then write 4-10 lines of CSS, done in 30 minutes.
As CSS has gotten more complexity from new capabilities, solving various tasks with it feels more and more like a research project. Like centering a div vertically and horizontally - there’s now 3-4 generations of solutions for this task:
1. Hacky stuff with position: absolute or floats
2. Flexbox approach. Hope you remember the 6 different attributes you need to set! Oh, there’s a new shorthand for flex now? Cool! More stuff to learn.
3. Grid approach. There are a bunch of different ways to structure a grid centering approach. Hope you remember how grid templates work!
With tailwind, just add 2 classes, done.
> With tailwind, just add 2 classes, done.
But you can do that with a library of SASS mixins as well.
Going through some of the answers I'm noticing that another "issue" I have with the tailwind approach is that it works by providing a post-processor when in reality most people just need a simple preprocessor and macro system.
Sure? I don’t see how that’s an argument for CSS “being advanced enough” - SASS ain’t CSS.
I like SASS (I wrote a lisp in SASS in 2011 lol) and that’s actually how I think about Tailwind utilities - it’s just using SASS mixins directly in your HTML. I would rather use Tailwind because it will take 1/3 the levels of abstraction, 1/4 the keystrokes and 1/2 the files to do the same job to:
1. Pick a class name (myclass) if people are using BEM or something this requires some algebraic thinking.
2. Write the class in file.scss to define the class and include mixins A, B, C
3. Add class=myclass in my html.
Vs tailwind:
1. Add class=“A B C” to my html.
I don’t really get pre processor vs post processor, it’s a build step to run at some point before I deploy with either tool that will produce some css files. ¯\_(ツ)_/¯
> I don’t really get pre processor vs post processor, it’s a build step to run at some point before I deploy with either tool that will produce some css files.
Not quite the same. If it's only a preprocessor, the tool is only dependent on your styling code. A post-processor needs the whole application.
It's a lot easier to add or remove a pre-processor from your development process, and for those that want to consume your styles it is a lot nicer when you don't have to adopt their tooling as well. E.g, I can create a "utility class library" in SASS, generate the CSS and let people just import that directly into their web pages. Is that possible to do with tailwind?
> I don’t see how that’s an argument for CSS “being advanced enough”
That's a separate argument.
I hear mostly two justifications for tailwind:
1. It is (or used to be) hard to do things in CSS like variables, calculated properties, themes, scoped rules / namespacing. (Pre/Post) Processors are going to be required anyway, so we might as well use Tailwind
2. It gives frontend developers and designers a common language (the utility classes) which makes it easier to establish workflows.
My argument for (1) is that CSS already supports a lot of things that used to require processors, and (2) could be achieved with a simple "library" that could just be imported directly.
I agree neither of those seem like good reasons to pick tailwind.
My take is that it removes needless indirection in any codebase that already has “components” - react/vue/solid/etc, template partials, functions that return html strings, whatever. See comment here: https://news.ycombinator.com/item?id=42804831
For that reason, plus it’s concision, I find it more productive use of time compared to css-in-separate-file.
If you don’t have components for separating semantics from presentation, then tailwind is less a good fit.
A concrete example that seems like a no-brainer to me: let's add a little padding to the top and bottom of an element. "py-2" Done. In CSS, specifying padding (or margins) is 4 values... except I forget which is the first one. And what units should I use... px, pt, rem, em. Inline, same-page style, or an external .css file? If not inline, what should I name the class? Vanilla CSS literally requires 10x more time and mental attention.
You can using padding-inline and padding-block with var(--spacing-2).
Tailwind is styling utility classes and design tokens in one. There are premade design tokens you can use the CSS styling though.
> "py-2" Done. In CSS, specifying padding (or margins) is 4 values... except I forget which is the first one.
False dichotomy. You are not stuck between tailwind and "Vanilla CSS", and one can solve the issue you are presenting with any reasonable set of SASS mixins.
> If not inline, what should I name the class?
Also solvable with good old SASS.
Do you have any links describing what you mean? I'm not a CSS guru, and perhaps I know only the "old" CSS. I did recently learn Tailwind and it's way nicer than the "old" CSS.
If modern CSS makes styling as easy as Tailwind does, I'd love to read about it.
Because of multitude of reasons. One of the big ones being never having to search through a style tag or finding a CSS file. 100% of the element styling is described in the element markup.
Tailwind was never about filling gaps in CSS.
That is atomic CSS, and it predates tailwind by quite a bit. There is a huge marketing push behind tailwind. If you look into who made it, you'd see it wasn't their first attempt.
Why do you keep saying CSS has “caught up”? Tailwind has always just mapped to CSS, so you’ve always been able to do anything in CSS that you could do in tailwind. What has CSS done that makes you see no value in Tailwind today where you used to see value?
What did you need Tailwind for before that you couldn't do in normal CSS? Doesn't Tailwind map pretty much 1:1 to CSS?
Every programming language maps 1:1 to CPU instruction sets, but very few humans want to speak CPU language directly…hope that helps.
Programming languages are more human-readable than CPU instructions, as opposed to Tailwind, which is less human-readable than CSS.
> Doesn't Tailwind map pretty much 1:1 to CSS?
Much of it does, but not all of it.
Do you have an example that Tailwind can do that can't be done in CSS?
I'm going off a claim from the Tailwind site :-)
The original question wasn't whether Tailwind can do something CSS can't, but whether it was a 1:1 mapping.
Can regular CSS do media queries all within the element's style attribute?
I believe Tailwind also utilizes JS to get some convenience features to work.
Oh gotcha, I must have just misunderstood the previous comment.
I want to say that tailwind also can't do inline media queries, but that's getting really nitpicky and pedantic. You can at least add a class inline that Tailwind creates a media query for in CSS, that is really handy.
Tailwind doesn't generate any JS at all. The final build is 100% CSS.
It's a horrible way to do what css can do but in a dumber way with added tooling. It is used by people that don't know css and this is where the problems start
I’ve been writing css/scss/stylus/linaria/whatever styling stuff for 18 years and I think tailwind improves life much more for css knowers than for css noobs. I prefer it over raw css for sure - I’ve written the same shit enough times that I’m happy to take some shortcuts and more than willing to pay for some tooling to do so. Tailwind hands out less abstraction rope compared to vanilla css and sass and all the rest, so much lower chance I open up a file and find some convoluted special little kingdom of abstractions that need to be handled carefully. Reduced cognitive load in the long run for a small up front learning/setup cost.
Yes.
Really!? Is that really what you got out of it?
I understand you're not a fan of Tailwind, so perhaps say what you dont like about Tailwind instead of creating a strawman and attacking it.
Also, shame on you for poo-pooing on someone else's open source project and people find useful.
"What I don't like about Tailwind" has less to do with Tailwind itself and more about the violation of separation of content and presentation that they push so hard.
> poo-pooing on someone else's open source project
This is not some young kid doing free software out of kindness. This is a company making millions of dollars in revenue in a closed source product (tailwind UI), which is built on a foundation (tailwindCSS) that is becoming less and less needed.
> and more about the violation of separation of content and presentation that they push so hard.
As someone who's done it both ways with web sites, that separation sucked. Having to figure out which style in my CSS file was messing things up was always a pain. And Tailwind tends to be "local" by default, limiting the damage done to other elements when I style an element.
In my larger experience (not just with web sites), whether separating content and presentation is a good idea varies widely from use case to use case.
Often content and presentation are part of the same package. In these cases, separating them makes maintenance of sites harder.
Yeah, I tried (not so hard) to like and use tailwind, but I've been using bootstrap for so long, and for my very simple needs, bootstrap was a better choice. But I wouldn't go around saying, "tailwind is unnecessary for everyone."
I'm with you. Tailwind would be great if it could be SASS'd but Tailwind is a post processor and it would be silly to build a post-post processor just to make tailwind reusable. It simply isn't a good tool for large enterprise applications. Toys, home projects, sure. But then, why learn CSS twice for occasional use? Until they solve the post processor problem, I'll stick with bootstrap. But if they do, I would definitely switch. That would be the best of both worlds.
Question for people who are good at CSS stuff. I am not.
I'm upgrading a personal Phoenix project to 1.7, and Phoenix now uses Tailwind by default. So I thought I'd try and update my one page thing to use it instead of Bootstrap.
So far, it looks like crap whereas the Bootstrap one looked 'good enough'.
What's the easiest way to get something that looks kinda sorta decent, with some nice defaults, without trying to become a designer?
Or should I just reinstall Bootstrap and be done with this.
> Or should I just reinstall Bootstrap and be done with this.
That one.
Tailwind gives you tools when you want to control the design, but you’ve got to control the design.
When you just want something that looks good and don’t mind that bootstrap-y feel, bootstrap is the way to go.
(There are projects that essentially recreate bootstrap on top of tailwind, which, in theory, might give you something like bootstrap as a starting point with the power of tailwind, but I haven’t seen it work better in practice than just using bootstrap.)
Disagree.
Just get one of the tailwind UX kits and use their classes as your standard style guide. I personally use flowise as it’s free with paid more complex components if needed, but there are a bunch of others out there that fill the same space.
On a new project, sure maybe going with tailwind + a theme/kit is a bit more up to date than using bootstrap. But on an existing page that already looked fine with bootstrap, why bother with the extra work?
The same can be said about Bootstrap, though. Just get a theme to make it look less bootstrapy. I think both viable ways to go, and it just boils down to personal preference (especially for hobby projects).
That's fine (I've done it). It's just that bootstrap is better at it.
Can you suggest which of these kits are good?
DaisyUI
I use DaisyUI to accomplish that goal, here is my demo site for an example: https://nwk-landing-kit.netlify.app
and here are the docs for DasiyUI: https://daisyui.com
The DaisyUI description of the Tailwind button made me laugh:
"bg-indigo-600 px-4 py-3 text-center text-sm font-semibold inline-block text-white cursor-pointer uppercase transition duration-200 ease-in-out rounded-md hover:bg-indigo-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-600 focus-visible:ring-offset-2 active:scale-95"
Yeah, that's not making my life easier is it. Also some of those class names are super cryptic.
They are cryptic but the learning curve is not that steep. Once you get the idea, it becomes much easier (and quite pleasant for a CSS hater like me). For example px-3 means "padding on the x axis 3 (spacing values)" and gives you padding on both left and right. There is a (rather simple) language that you need to learn and at least for me it made things much, much better. You can probably get the feel for it in several hours of building a basic website with Tailwind (and DaisyUI I would recommend).
ia that really easier than learning css directly? since you have to understand 'paddding'and 'px' ?
see https://developer.mozilla.org/en-US/docs/Web/CSS/padding
vs https://tailwindcss.com/docs/padding
I am not going to argue whether that's the case, as I never managed to learn CSS enough to be productive in a convenient (for me) way. Despite of trying many times. Whereas tailwindcss "clicked" right away and gave me the awesome superpower to build whole products without having to depend on other people. Before that I hated myself for the horrible, unmaintainable mess that I created, and double hated myself later when I had to revisit the project. Since I am using tailwindcss, I never had bad experience. Of course I still have to spend time wondering how to center some element and why it doesn't work, but that's not what I am complaining about.
It might be just a personal defficiency, but it is how it is (for me).
One of the reasons Tailwind became so popular - even more so than preceding frameworks like Bootstrap - is that a lot of people who normally liked working with CSS directly fell in love with it. It removes the extra step of editing a separate CSS file without straying far from a 1:1 mapping and eliminates most of the cascading rules that have plagued frontend for decades (`group:` and friends notwithstanding). The latter is important when working on large teams because it eliminates the name bikeshedding and conflicts.
sorry, but this is just not true. The cascading issue is still there, and it gets even worse because if you have an element with class "p-1 p-0" you cannot know in advance which will take precedence.
Of course you shouldn't do that, but it happens to be the case that Phoenix does exactly that
This is not a cascading issue. This is a "You're holding it wrong" issue. And when Phoenix does write 'p-0 p-1', Phoenix and Tailwind are not a good match.
You suddenly reminded me about another good Tailwind thing: linter will highlight "p-1 p-0" as a mistake. I've never seen linters that warn on "your-custom-p1 your-custom-p0", but Tailwind makes it possible.
If the alternative is:
.foo { padding: 0; padding: 1rem; }
then I can see the precedence but I don’t see how it’s an advantage. You can write bad code in any methodology.
That seems like an issue with Phoenix and not Tailwind or the Tailwind approach.
As someone who used and knew CSS very well, and reluctantly used tailwind, yes. I don't strongly prefer one or the other. But I will say now that I know Tailwind, when I see those large class name strings, my brain parses them shockingly fast, and they kind of melt into the background similar to comments. Also, common linter rules will order the classnames, and that they are always the same between disparate tailwind projects, all together its not nearly the annoying mess I thought it would be on first sight.
it's quicker to write, though. and many of these class names are the same in bootstrap, so I've been seeing stuff like 'p-0 m-1' in frontend projects for decades.
another huge benefit these days is with the styling living alongside the markup, it is very easy to use chatGPT or other AI tools to copy/paste and have changes made, etc. it is much less work with one file vs multiple. you can give the context super easily and take the results very quickly.
If your looking for components like bootstrap try https://flowbite.com/ for free. Tailwind also has paid components. You just copy and paste. The cool part is once you get more comfortable you can start to tweak the flowbite components.
I’d say it depends on who is paying you. If you have job security and want to tinker, then play with tailwind if you want (most trendy / loud people seem to like tailwind). If however you are working on your own project / are self funded / or have a deadline just stick with bootstrap that you know, and focus on getting your work done instead of bike shedding on the UI
Tailwind and Bootstrap and are kinda apple vs apple pie. Tailwind provides classes that still need to be stacked to build components.
It'd be easier if you were using some source for UI components, I've used TailwindUI in the past, but that's paid. I'm sure there are good free alternatives.
A friend of mine who is good at these things recommended https://mantine.dev/
You can check out Halfmoon too instead of Bootstrap: https://www.gethalfmoon.com/
Put your HEEx into a LLM. They understand both Bootstrap and Tailwind very well. It will probably not be too hard.
reinstall bootstrap and be done with it. You can look at daisyui it is closest to bootstrap. There is also shadcn ui, ui looks good but it would take you effort to port styles to your phoenix project.
I appreciate there are people who find Tailwind useful and are productive with it, but it has this clean yet generic look that I now see everywhere, because Tailwind is now everywhere.
This is conflating Tailwind and TailwindUI/shadcn/etc.
For the most part, Tailwind offers no more influence over style than normal CSS (okay, there's some exceptions... things like shadows are a bit more standardized, and indigo has gotten outside influence on color palettes as of late).
Tailwind gives you sensible defaults, but doesn't really influence your design too much. People just tend to design the sites a certain way. Especially, with ShadCn.
I feel like that's a good thing, because Tailwind's options are well-thought and work well.
I like to think of it in the same way as Inter being the new Helvetica when it comes to choosing a font for a website: lots of people do it, and it looks great, so why not?
I heard this comment about Bootstrap back this in the day but none of my Bootstrap sites looked like each other. Bootstrap saved me a lot of time because it had a lot of utility classes (like Tailwind way before Tailwind) and it never enforced a certain look.
You just loaded the classes that you wanted (unless you didn’t download the source Sass files, but that would have been silly).
My take on this problem is, good UI frameworks (i.e. tailwind + components) are still rare. So the vast majority of projects use a very small number of them. If 4-5 new quality UI projects popped up, especially if they departed more in their styling, we'd see more diversity.
I've come to realize with design, like much creative work, the trends really do seem to be set by a shockingly small number of people. I wish more people realized this, because I feel there are talented individuals out there not making their own, thinking they'll never be heard. But I suspect some of those people would be unlocking new UI's for a large chunk of the web if they would give it a go.
The same way everything looked like Bootstrap a decade ago.
Tailwind is a testament to the greatness of inline styles (styling a thing without naming it), the universality of strings and also the limits of strings.
I am excited for what comes after it, until then I'll use Tailwind (reluctantly)
Was it really necessary to break all existing apps using `npx @tailwindcss`?
It's an easy enough change to `npx @tailwindcss/cli` but we now have to go back and update all Apps and templates and since it uses v4 we now have to test every App to see if anything's broken with a v4 major release.
Given its massive install base, surprised they wouldn't maintain backward compatibility with v3 and have an explicit opt-in upgrade path to v4.
Edit:
v4 did actually break all our Tailwind Apps which doesn't support `@import "tailwindcss"`, likely because we use `npx tailwindcss` without any local npm dependencies. Trying to use the existing v3 `@tailwind components` renders a useless app.css. Only solution atm is to explicitly use v3 and change all our build scripts to use `npx tailwindcss@v3`.
You’re doing something silly living without a lock file to use a tool as part of your build process. Why don’t you actually include the version of the tool you want in your dev dependencies + lock file? That way, you don’t get broken. We’ve had the solution to this problem - lock files - for 15ish years, since Ruby’s `bundle` introduced it.
Not everything is a node App. We don't have a lock file because we don't have any local npm dependencies (as already mentioned). We're using `npx tailwindcss` as-is.
You clearly have a dependency on tailwindcss (if it can break you, you depend on it), and are using npm to fetch it (npx uses npm internally, they are installed together) so you can easily solve your problem by adding a couple json files with some version numbers in them. npx will pick up and use the version from your package.json, so no workflow change other than running `npm install …` once to generate package.json for your preferred semver specifier, and package-lock.json to guarantee your builds use a known-good version from now on.
FWIW Tailwind can be used as a standalone executable.
This is how Phoenix/Elixir bundles Tailwind without requiring npm.
I don’t care how you do it, just make getting your dependencies deterministic based on files committed to your repo!
Happily the Tailwind hex package encourages you configure a fixed version number, so you’ll never get surprise breakage as long as you’re committing your mix.lock file as well.
I’m only suggesting package.json/package-lock.json because their projects are already using the npm ecosystem to fetch the tailwind dependency. A Makefile that does `curl $TAILWIND_GITHUB_RELEASE_URL -o ./departing/tailwind` is fine too (this is what Tailwind.hex is doing under the hood).
AFAIK using the tailwindcss-cli without npm makes it impossible to use Tailwind plugins, such as DaisyUI.
This is not true, here is a demo projects which uses the Hex Tailwind and DaisyUI: https://github.com/naymspace/backpex/tree/develop/demo
I believe that is true, although there is a project which bundles Tailwinds and DaisyUI into a single standalone executable:
https://github.com/dobicinaitis/tailwind-cli-extra
I have not tried this out yet, personally.
FFS we don't have local dependencies. Which means we don't have any local node_modules and have never ran npm install (there are no dependencies to install!). There is no lock file or dependencies.
Our Apps don't have any npm dependencies nor needs to run npm install by design, we're not going to start now, as already stated we're switching to `tailwindcss@v3` instead.
The point is this was a documented supported use-case which all our non node.js Apps used, which have now broken as a result of this release.
YOU DO have a local dependency.
Just add a mostly empty package.json like this:
Run npm install once, and be done with it. You could even commit your node_modules if it helps.We don't, we use npx to avoid needing any local dependencies.
`npx tailwind@v3` is the solution, definitely wont be committing node_modules to git, ever.
I find it really hard to not immediately be reminded of this:
https://xkcd.com/1172/
We only use npm dependencies and bloated node_modules folders [1] if we absolutely have to and for our non node.js Apps we explicitly don't.
[1] https://www.reddit.com/r/ProgrammerHumor/comments/6s0wov/hea...
But why not though
I also use tailwindcss in a non-node project, but use npm package / lock files to easily lock javascript / css dependencies and make renovate able to update them for me.
I've linked to why. We prefer #NoBuild solutions where we'd only use local npm deps/node_modules if we absolutely have to, and for non JS Apps we don't.
The node_modules folder is still somewhere on your system (~/.npm/_npx probably?) containing the same tailwindcss dependency files, but if it helps you sleep easier at night it’s okay to pretend it doesn’t exist.
No kidding, I thought global tools worked with fairy cloud dust, now I wont be able to sleep! But knowing there's not a going to be a bloated node_modules folder and local dependencies running different versions unnecessarily maintained in every project will definitely help.
Shove an @ version in it
Yep `npx tailwindcss@v3` is the solution we ended up with. Just had to change this in all our Apps and project templates.
I wish @-less wasn't be allowed. Like you can do @latest but then human confirm is needed. That way you don't get this problem in scripts.
> then human confirm is needed
"Suppress this prompt with the -y or --yes option" [1]
[1] https://docs.npmjs.com/cli/v11/commands/npx
So why not npx tailwindcss@^3.0.0 (or whatever version was there when you started)?
> Given its massive install base, surprised they wouldn't maintain backward compatibility with v3 and have an explicit opt-in upgrade path to v4.
Given it's a major version change, I'd expect it to create breaking changes, otherwise it would be a minor version change.
Tailwind’s abuse of CSS classes as a DSL has always felt like a hack to me.
You shouldn’t need a special editor extension to get highlighting/autocomplete/etc, just use TypeScript and a CSS-in-TS solution.
> just use TypeScript and a CSS-in-TS solution
THIS is the definition of a hack to me, so yeah.
May be a hack but it just works.
Thanks Tailwind devs! It’s a testament to the success of the concept and the quality and consistency of execution over a seriously long time, that Tailwind became how LLMs write code for the web.
Congrats on the release.
Yes, I’m a huge fan of how easy it is to whip up quick isolated prototypes in Claude artifacts.
There’s a risk of breaking changes in libs causing frustration in larger codebases, though. I’ve been working with LLMs in a Nextjs App Router codebase for about a year, and regularly struggle with models trained primarily on the older Pages Router. LLMs often produce incompatible or even mixed compatibility code. It really doesn’t matter which side of the fence your code is on, both are polluted by the other. More recent and more powerful models are getting better, but even SOTA reasoning models don’t totally solve this.
Lately I’ve taken to regularly including a text file that spells out various dependency versions and why they matter in LLM context, but there’s only so much it can do currently to overcome the weight of training on dated material. I imagine tools like Cursor will get better at doing that for us silently in the future.
There’s an interesting tension brewing between keeping dependencies up to date, especially in the volatile and brittle front end world, vs writing code the LLMs are trained on.
Question for those developers who, like me, have no f/end build step: How would I use tailwind without a f/end build step? All the examples of using tailwind 4.0 on the linked site assume a f/end build step.
My project does not use (and I have no plans to include) npm, or PostCSS, etc.
For a static site I have, I manually run the Tailwind tool when I include new classes. It generates style css and I commit this file to git.
Thanks; I actually did not know there was one until you and the sibling poster told me.
To anyone else with the same question: See https://tailwindcss.com/blog/standalone-cli
This is what keeps me from using Tailwind too. I simply do not want to add the maintenance headaches of an npm-based build process to my project.
Vite dev, preview and build scripts make it so stupidly simple that I can’t believe people don’t pull it for all, including the simplest, sites.
Plus I couldn’t imagine developing without TypeScript and hot reloads in 2025.
> I simply do not want to add the maintenance headaches of an npm-based build process to my project.
Apparently I was just too blind to find it - here is how you can (presumably) use tailwind without pulling in npm and node.js.
https://tailwindcss.com/blog/standalone-cli
I'm pretty sure the point of using TailwindCSS is to use build step. There is another way, it uses Tailwind's CDN. But I think even the developer don't recommend it outside of development phase
If you don't want to use NPM, I can recommend Tailwind's standalone CLI
> If you don't want to use NPM, I can recommend Tailwind's standalone CLI
Didn't know there was one. Will look into it.
Migration guide, if anyone is wondering: https://tailwindcss.com/docs/upgrade-guide
Some breaking changes in there. May want to hold off on upgrading until LLMs come around to writing v4 code with ease.
Renaming utilities like flex-shrink-* makes existing LLMs emit deprecated code today and broken code tomorrow. I wonder what the rationale is behind the renaming of various utilities (e.g. shadow-sm -> shadow-xs, flex-shrink -> shrink, decoration-slice -> box-decoration-slice, ...)
In new projects, I will probably use Tailwind v4 and constantly provide the upgrade guide as context to an LLM. In existing projects, I will continue to use Tailwind v3 until I am certain that it works alongside the tools used by my framework (React Router / Remix).
This reservation has taken firm hold on me and has made me a slower adopter of shiny new things.
I feel alright about it from a local perspective (I'm a lot more productive now than I was before), but I do wonder what it does to the overall dynamic and incentive to write shiny new things or generally update the ecosystem.
The LLMs will get more powerful, but to what extent will their work be dominated by existing tools (with lots of existent human-generated exemplar)?
LLMs have already plateaued in knowledge imo.
There’s far less reason for humans to contribute code examples, answer questions, work on open-source projects, or even produce content knowing it’ll immediately be slurped up and resold.
Web dev will be stuck with React and Tailwind circa 2021 for a very long time.
We shouldn't really have to retrain models for them to be able to work with new versions of libraries or frameworks. That seems like a flaw in the LLM (only?) setup. One should probably be using RAG at a minimum to pull in the correct documentation and references. Something like Kapa, but not limited to a single project https://www.kapa.ai/
This changes the colour palette again. They do this almost every major release. Starting to become a liability: upgrading will change your colours.
I’m a recent convert to tailwind. I’m very comfortable with css and I was initially turned off on the huge horizontal lines I saw in tailwind projects.
However, more and more component libraries are based on tailwind so I decided to try some immersion therapy.
Here are the top things I enjoy that was not obvious to me:
1. The class names are css shortcuts. Using them save you a lot of time. This is probably obvious to anyone who’s seriously looked at tailwind but I didn’t see that browsing the docs. I just saw nightmarishly long lines.
2. The lines look longer when you are not familiar with the class names. I initially pulled all of my class names out into a string outside my markup and included similar to how I’m used to using emotioncss. This made tailwind tolerable for me at first. However after several days I started to feel less turned off by those lines. I think it’s because I could recognize them. I will still break down a line with something like clsx.
3. clsx helps so much vs trying to entirely rely on tailwind syntax. The docs don’t discourage this at all but for some reason I thought it wasn’t idiomatic tailwind at first.
4. My app has to support a very large number of themes. Tailwind has proven to be a very attractive way of solving this problem. CSS variables are cool but the long syntax of using them is helped a lot in tailwind.
5. Adding my own custom variants is so easy and made me feel like a power user with such a small learning curve.
All of this is just my two cents to guide anyone who is like me watching from the sideline and wondering why? Why would anyone ever want to tolerate those “disgusting long lines mixed into the html”. Neo, all I see is the lady in the red dress now
It's sort of like javascript devs ignoring typescript because they never felt like they needed it. But once you start using it, it's difficult to go back.
I was in never ts/tailwind gang for a few years until I tried them.
I think the reason why tailwind is as popular as it is, is because it really ties in with the "change something, save, then immediately see the result" loop and dx of modern day web development.
Yes, this works with regular css too but it's the fact that you can do bigger changes inline quickly without making up a class (and god forbid you already have a different class affecting the same element and it gets hairy). Personally I think this is nice, it's great to immediately see results and then adjust. But dx is not the only thing that matters and there are tradeoffs too. Personally I would use tailwind for personal projects but I don't think I would try to introduce it at work.
And thereby you kill all inheritance, that is the while point of css.
I find it more magic to change a single class at root and have the entire design reflow (on purpose) -
Its beautifull when combined with shadowdom and wc
Personally I'm not interested in using Tailwind but my main criticism is that it didn't go far enough in its approach.
Instead of using classes (which are extremely limiting) they should have created their own language like Imba did (inspired by TW).
https://imba.io/
I'll stick with 3, not rewriting so much of the codebase because taking away features is now an improvement. Not sure where dogma and performance overlap but it isn't in making @apply a hassle.
Tailwind is CSS that cleans itself up as you go
Locality of behavior can be done with few lines of js. https://github.com/gnat/css-scope-inline
I assume that you don't even need javascript after a few releases of Firefox. All other major players support scoped styles.
https://developer.mozilla.org/en-US/docs/Web/CSS/@scope https://caniuse.com/?search=%40scope
Title is: Tailwind CSS v4.0
Tailwind and Sveltekit are the reason why I still love doing FE after all these years. Initially I was so sceptical of TW. I simply can't work without it now. Huge thank you to authors for their hard work.
Recent and related:
Tailwind CSS v4.0 Beta 1 - https://news.ycombinator.com/item?id=42210553 - Nov 2024 (125 comments)
Anyone who has ever had to deal with CSS over time knows that the biggest issue is having leftover classes. Utility first approach means this never happens.
Text of TFA is cropped on my Safari (iPhone 7), a bit ironic init?
I'm not the biggest fan of Tailwind or anything, but good job on the release! Fewer dependencies and better performance are always welcome!
Looking forward to integrating this into my elixir projects!
so much love for tailwind! I've used it since version 1 and have been always my default for starting new projects.
Congrats to tailwind team!
I like tailwind but think it’s not needed anymore as CSS got better. Utility frameworks don’t necessarily need a build step.
I forked and finished Tachyons successor Tachyons 5: It has container queries built in and p3 colors.
https://github.com/gobijan/tachyons5/blob/main/tachyons5.css
If you need very sophisticated layouts write them in plain css. For quick styling utilities are awesome.
Unpopular opinion. Now downvote me to the ground.
Last time I tried v4 the automatic content detection was pretty bad. It would falsely detect tailwind classes if it seen a similar name in a string in a code file. It seemed pretty dumb.
That is more or less how it worked in v3 already, because any string could be used as a CSS class.
"The way Tailwind scans your source code for classes is intentionally very simple — we don’t actually parse or execute any of your code in the language it’s written in, we just use regular expressions to extract every string that could possibly be a class name."
https://v3.tailwindcss.com/docs/content-configuration#class-...
The only difference in v4 is that scanning is so fast, they just scan roughly everything by default. You can still opt into manually specifying which files to scan.
https://tailwindcss.com/docs/detecting-classes-in-source-fil...
In v3, one can use `blocklist` in the config to eliminate false-positives, but with the config file gone, this seems no longer possible, so I won't be upgrading.
In one project, roughly 75% of the detections were false-positives, unnecessarily bloating the CSS.
You can disable automatic detection and manually configure which files to look at:
https://tailwindcss.com/docs/detecting-classes-in-source-fil...
This seems like the best path forward if you're using v4.
See also https://daisyui.com/
I heard that Daisyui v5 is ditching Tailwind so now it's just pure CSS.
The Daisy UI 5 beta release is still based on Tailwind 4
"First Install Tailwind CSS 4 beta"
https://v5.daisyui.com/docs/v5-beta/
Heck yeah, cool to see Tailwind add support for transitions without Javascript.
As a burgeoning web developer, dealing with animation libraries seems like it's not worth the effort (or at least not for something as simple as a blog), so this is much appreciated.
Did they really nuke the entire js config file? I have a number of advanced use cases that depend on it, like eliminating false-positive content matches.
You can still use it if you want, but most of the time it’s not needed anymore.
Tailwind suits the kind of developers who hack things together and build up technical debt and spaghetti code rather thinking about things first and designing things properly.
I don't know. In 20+ years I have seen way more abominations and spaghetti CSS using other every CSS technique.
With Tailwind at least I know what to expect, and the code in practice rarely deviates from what it's supposed to look like.
I'm all for "not building up technical debt" and "thinking about things first" but in my personal experience the anti-Tailwind crowd doesn't have much to show here in this regard. Sure: it's theoretically possible to build a perfect CSS ivory tower, I just haven't seen even a passable one in a non-trivial project, it always devolves into a mess for various reasons... often breaking the rules of the paradigms like BEM and OOCSS, often because of cutting corners here and there.
Addendum: I'm all for criticising techniques, but it's interesting that the anti-Tailwind crowd always resorts to attacking the character of the developers that use it.
I feel like it is the same with ORMs argument is always "they don't know proper SQL so they use ORM instead".
Which usually from people I know is they do know SQL and ORM and "no ORM crowd" doesn't have much to show.
Exactly the same with Tailwind, I see coworkers doing Tailwind and knowing CSS well and not being "pure vegan CSS developers".
But on the other hand we don't hire people who would utter such things like "no ORM" or "no framework" because those were also as in experience people who would create technical debt for others to deal with.
Same. Been doing this for 20+ years. I’ve worked at companies whose names are recognized and respected. My current Tailwind project is by far the most maintainable one I’ve worked on when it comes to CSS.
Exactly.
I don't know why, and perhaps in theory it should suck indeed! But in the end it just works.
Hard disagree. Vanilla BEM + CSS produces a parallel component system that I find very unwelcome since React (or Vue/Svelte/etc.) already accomplishes this.
Tailwind removes this burden and helps you focus on writing actual React components when needed.
To some extent, reading between the lines of many of these comments, I think “pure CSS” designers are feeling threatened by the quality level of Tailwind sites designed by the rest of us.
It's worse. React killed the craft of design engineering because everything is JavaScript. CSS develoeprs are gone.
Design engineers still exist, they just write more JS these days. They are still building UI and design systems and teaching craft & supporting full stack teams. The craft is there, but the tools are different.
True — they just need to be more engineers than designers.
I don’t think putting html in one file and css in another file makes you more or less of a designer than putting both html and css into a single file.
I think the approach is different. Component style applications have to thing about all component presentation separately, web apps ressemble apps more than documents (d’uh) so it makes sense that they are designed as such.
Documents are designed holistically, you don’t care that much about how a thing (say, an image that is an aside) would look on the next page because on the next page there would be something completely different.
I think much of the debate and contention comes from the fact that many developers only worked on either web apps, or documents (e.g.: static blog, cms) and each try to convince the other group that their approach is the best.
Switching from CSS based design systems to large TypeScript monoliths requires you to learn one or two things about engineering
Tailwind is mind-boggling to me. Like something that would be written by someone who doesn’t actually write a lot of HTML or CSS.
Bootstrap is bad enough, where you end up using 4, 5, 6 classes for display, margin, padding alterations to existing components.
It’s just unreadable crap. No wonder it’s popular though. Most people suck at designing. The ones that don’t aren’t using Tailwind.
>The ones that don’t aren’t using Tailwind.
True. And they're not using HTML or CSS either.