14 ms·
Tailwind is the most counterintuitive yet obvious-in-hindsight CSS tool (or of any class - no pun intended) I've worked with. I know the general sentiment towa
by seancoleman 6y ago
Tailwind is the most counterintuitive yet obvious-in-hindsight CSS tool (or of any class - no pun intended) I've worked with.
I know the general sentiment towards Tailwind is "I spent years getting my separation of concerns with HTML/CSS down, but now you're telling me all that is backwards and CSS Zen Garden is blasphemy?" I was in the same boat. Tailwind just felt wrong, and with 15+ years of experience, I've come to trust my intuition. After watching several videos, and reading all the canonical articles on Tailwind, I still wasn't convinced this was anything more than a fad full of bad practices.
But the one thing I'll let trump my intuition is curiosity. So I used Tailwind on a medium-sized project for a couple months and was blown away by the productivity and maintainability. It took using it for a couple weeks to "get it". I had a positive ROI on this project, even considering the learning curve!
If you still think "Tailwind feels wrong, what am I missing?" I'd suggest reflecting on the following:
1) You probably haven't actually delved into Tailwind on a non-trivial project. I understand learning a new framework isn't a trivial undertaking, but it's the only thing standing in your way of discovering your "truth".
2) If you feel Tailwind is too much like inline styles, think of the difference between the infinite possibilities of strings defining a "type" vs. a discrete enum type. Tailwind classes are the enum type values.
3) If you're struggling to abstract reusable higher-level classes/components, the problem might actually be with inconsistent and non-modular design, not CSS tooling. If every page or section is a "unique work of art" then you may have poor UX/design.
- JMTQp8lwXL 6y agoI'll identify as in the "not yet convinced" category on Tailwind (though, I have evolved on other paradigms, which I will now discuss). JSX felt wrong (at first) due to co-mingling HTML and JS, however, I realized that's the wrong application of concerns because 1. JSX isn't HTML, it's a sugared syntax for the React.createElement API and 2. that separation wasn't meaningfully improving my architecture and in retrospect was clearly holding us back. Could anyone evaluate if these are analogous 'separation of concerns' (SoC) fallacies? I will admit, I think I never fully appreciated the intent of SoC.
- madeofpalk 6y ago> JSX felt wrong (at first) due to co-mingling HTML and JS, however, I realized that's the wrong application of concerns because The line React core team would say is that that what you're thinking of isnt "seperation of concerns" but rather "seperation of technologies". React/JSX is good because both the HTML and JS together is the view. It's the same concern. React seperates concerns much better because it so heavily promotes the functional programming approach and that the UI is a function of state.
- jfengel 6y agoAgreed. We got used to thinking of any Javascript as "business logic" rather than "presentation" because it's an imperative language, but React/JSX are tailored to using JS in a way that acts more like presentation. If you write it imperatively, it won't be idiomatic React, and sooner or later something will break. So it may help to think of JSX as using a functional subset of Javascript. It's not, and that veil gets pierced pretty often, but the better you contain it, the more you can effectively use both Javascript and HTML together as part of a single concern. Using Redux with sagas even further separates out the most side-effecty parts of it, though sagas are really heavyweight and I'm still not certain if I think they're worth it.
- acemarke 6y agoSagas are a great power tool, but most Redux apps don't need them. That's why we opted to include thunks out of the box as part of our official Redux Toolkit package: https://blog.isquaredsoftware.com/2020/02/blogged-answers-why-redux-toolkit-uses-thunks-for-async-logic/ https://blog.isquaredsoftware.com/2020/02/blogged-answers-wh... (You can still customize the middleware when using RTK to set up your store, same as always, so if you want to use sagas you still can.) That said, there's a lot of things thunks _can't_ do, and for those use cases it makes sense to use sagas or observables.
- tppiotrowski 6y agoYou could tie CSS/JS event handlers to HTML elements, but if someone edited the HTML file and changed the hierarchy, things broke. You could tie CSS/JS event handlers to class and id attributes in the HTML file, but you'd have to add those attributes into the HTML file to target the right elements. Web SoC always felt more SoF (Separation of Files) to me. There is no advantage in putting the HTML/CSS/JS into separate files if making routine changes requires visiting multiple files. React puts it all in one file, which makes me think that the concern is the Component and not the individual browser parsing libraries.
- fishtoaster 6y agoI was in the same boat. It felt super wrong. It felt like the long, slow nightmare of maintaining an early Boostrap site all over again. But I got peer-pressured into trying it on a medium-sized project and yep: I'm in love. I'm in camp Utility Classes now. The only serious issue I had was when implementing designs provided by an outside designer: 1. The design says this width needs to be 28 px 2. That'd be "w-7", which TW doesn't provide. Guess I'll add it to my tailwind config file. 3. Repeat ad nauseam until I broke down and added all "w-n" widths to my tailwind config from 1 to 500. 4. Repeat for min-width, spacing, border-radius, etc. The result is that A) I get really good at converting pixels to rems to tailwind-scale, then back again in my head and B) My tailwind config is huge - the saving grace being the purge tool that gets rid of unused styles.
- rjknight 6y agoThis won't work for everyone, but it might be possible to push your designers towards using HTML. Tailwind classes are simple enough to manipulate that you don't need to know CSS. After a while, you get the amazing benefit of simply being able to copy and paste HTML from one place to another - since the class names are common, you can copy HTML directly from a design mockup into your application, with only minimal extra work in templating. This is much more efficient than trying to figure out pixel-sizes in a PSD, then trying to figure out which combination of CSS classes will succeed in reproducing the visual appearance (most of the time, in most browsers...)
- maxgeorg 6y agoLove this idea. I do all my design in HTML+Tailwind. I wonder if all designers would use HTML+Tailwind over design software if they knew it.
- omnimus 6y agoI know you can't do much about it but i think forcing people to think about how many "values" they have in system is really helpful. Good designers will also want as few values as possible. They are creating visual system. I doub't they will want to have 20 different font sizes and padding left values. If there is fontsize 26 and 29 its most probably a mistake because nobody can differentiate the size so it has no function.
- swyx 6y agoagreed on the counterintuitiveness. I echo a lot of your points on my Why Tailwind essay: https://www.swyx.io/why-tailwind/ https://www.swyx.io/why-tailwind/
- maciekmm 6y agoWhat I'm struggling with is consistency across pages, especially if you are not using a component framework. I'll often end up with 50 similar, but different looking buttons. On the other side when using a component framework, re-implementing all components when there are solutions already available (i.e. very similar in terms of look and feel Ant [1] or even Material-Ui [2]) sounds counter-productive. Didn't you stumble upon such issue? How did you handle this? [1] https://ant.design/ https://ant.design/ [2] https://material-ui.com/ https://material-ui.com/
- keithnz 6y agoyou can make common styles for things like buttons, if you watch adams tutorials videos, they cover this reasonably early on
- maciekmm 6y agoIt works for simple single-element components. When you have things nested it gets out of control really quickly.
- keithnz 6y agohow does it get out of control? I've been using it for quite sometime now (with Vue). I really haven't experienced things getting out of control. Curious what problems you have had?
- markdown 6y ago> adams tutorials videos They're all gone. Vanished completely from the website. And I was half-way through!!! Now they link to somebody's youtube channel for random Tailwind stuff rather than the nice walkthrough/tutorial that were the originals.
- dsissitka 6y agoIs this what you're looking for? https://v1.tailwindcss.com/course/setting-up-tailwind-and-postcss https://v1.tailwindcss.com/course/setting-up-tailwind-and-po... There's a version selector in the upper right corner.
- diob 6y agoNot only is it productive and maintainable, it's super performant! I work on systems with very limited power, so it's been a godsend in fixing performance for machines that can't handle all this "CSS in JS".
- Swizec 6y agoSo what you’re saying is that Tailwind is css-in-js with pure css? I can get behind that, design systems and component libraries have completely revolutionized how I think about these things.
- kall 6y agoYes that is 100% what it is. Using theme-ui or tailwind is just a switch of technology and syntax. The development style and thinking is the same.
- christophilus 6y agoSame here. I'll add that I think the hundred bucks or so that we spent on Tailwind UI was worth it many times over.
- rglullis 6y agoI am definitely missing something. What I don't get: if tailwind provides all the preprocessor parts, why do people need to put the class definitions as part of the HTML? I would completely get behind tailwind if it was only the SASS part. Give me a bunch of mixins and consistent variable naming, which I could just `@import` into a sass file where I get the definitions for UI elements, widgets, etc... the whole "Design system" if that is the word kids use these days. All of that can (and should if you actually paid attention at the CSS Zen Garden) stay outside of the HTML. So why when I go to any introduction to Tailwind it still shows all that <div class="size-foo color-blah rounded-baz"> code, I get major WTFs on my head and then I just go back to my simple SASS-based workflow. What I'd like to see in the next generation of CSS frameworks would be for it to be able to take a completely classless HTML document (like CSS Zen Garden, modernized to HTML5?) and have it look like 3 or 4 different design systems without touching the HTML. Or for extra points, take a web application like webapp (web version of winamp) and show how you can make completely different skins just be redefining the base types and the color palette.
- darekkay 6y agoThe answer to your question is the actual confusion regarding "separation of concerns" in HTML and CSS. You can do what you've described with Tailwind: check out @apply. But now you still have the issue of coming up with CSS class names. Because CSS on its own doesn't do anything. There is a high dependency between HTML and CSS and it'a up to you to choose the dependency direction. HTML and CSS are not concerns, they're technologies. Components are a better way for separating concerns. That's why CSS-in-JS is so popular and why we're combining pseudo-HTML and JavaScript in React.
- rglullis 6y ago> But now you still have the issue of coming up with CSS class names. Not entirely true. I'd be totally fine with class names that identify what type of widget it is. <div class="card">, <div class="modal"> <button class="secondary-action">, or <span class="clipboard-copy"> are "made up CSS class names" that identify a type of widget and used without making no assumption about presentation concern. <button class="btn btn-small"> and <div class="w-12 rounded-small"> are not. And yes, I understand that tailwind allows you to create types and @apply them. What I am saying is that (1) I'd like to see this separation to be enforced and not just possible and (2) plain SASS also lets you do that already. so I don't understand what I would gain from adding tailwind. > Components are a better way for separating concerns Except when they aren't. Downthread I gave the example of a library project that I want to define the functionality/behavior but leave the looks/styling to the consumer. Desktop GUIs have theme engines for ages, yet frontend web developers want to get excited about frameworks that allow for "night mode"? "Night mode" is just a way to say "you can separate presentation and content however you want, as long you only present in two different styles".
- pembrook 6y ago> You probably haven't actually delved into Tailwind on a non-trivial project. This is precisely where Tailwind breaks down IMO. It's fast for landing pages and smaller sites--but when implementing a real design system across a complex web app, Tailwind is a nightmare. We've had to add so much custom stuff to the config file it's basically the same mess our CSS was before. I've been-there-done-that with the whole CSS framework world (have used Bootstrap, Tachyons, Bulma, Tailwind in many projects) and have completely reverted back to custom stylesheets with a few select utility classes that make sense. Padding, margins, widths, heights do not make sense as utility classes IMO. Type scales, type modifiers (like font-weight), and commonly used things like margin-x-auto and 100% width do. I wish there was a CSS framework that only contained a minimal set of common utilities (like the ones mentioned above) and required no complex build process BS or NPM. I just want a simple boilerplate, nothing else.
- stanmancan 6y agoIt sounds like you're fighting Tailwind instead of working with it. Are your designers aware of the presets and design with them in mind? I'm curious what you're adding to your custom config to make it so bloated? I've been using Tailwind on a number of sites, big and small, and have yet to run into any situations like you've described.
- pembrook 6y agoIt's not like Tailwind is SAP or something. It's just CSS. You shouldn't need to re-work your entire process around it. The custom stuff in our config was mostly the need to create standard styles for components. Eg. button large, button small, etc. to correspond with our design system. For example, here's tailwind code required to create a button large: bg-violet-100 text-violet-700 text-base font-semibold px-6 py-2 rounded-lg How the hell does that help with consistency? You have to copy paste that mess every time you create a new button, and then guess what happens if the button you copied from needed special margin? Try debugging that if something looks wrong. Also try turning that into dark mode. Now you've got to search through the spaghetti to find what's custom about this button and fix it every time. You know what's easier? Creating a ".btn-lg" style to fit our design system, and just typing .btn-lg each time. It also has the bonus of making your code actually readable. Maybe this is solved with the groups functionality in the latest tailwind, but this is just one of the frustrations I eventually developed.
- nickjj 6y agoI think the biggest pull back / time sink with Tailwind isn't the CSS, it's the (lack of) JavaScript. With Bootstrap you have a bunch of common things handled for you out of the box (dropdowns, modals, tooltips and like 100 other things you can easily find on Google since the community is massive). You can just drop these widgets into your template and get going. Often with just 1 or 2 lines code if you're using Yarn + Webpack. With Tailwind you're on your own for all of that unless you buy Tailwind UI and even then it's only JavaScript solutions with the libraries the authors have chosen to use and it's no where near as feature complete vs the JS widgets you get with Bootstrap, even if you only count what's officially bundled with Bootstrap. Both of those things are kind of problematic for someone who isn't super strong on the front-end and doesn't want to invest a lot of time designing these things from scratch (a full time job in itself). Especially if you want to use something like StimulusJS instead of Alpine or Vue, since Tailwind UI doesn't seem to include any examples for StimulusJS. There's a whole bunch of folks out there (like me) who aren't building SPAs. We're just using good old server rendered templates with sprinkles of JavaScript. With that said I still prefer using Tailwind, but it's not really near the level of productivity you get when buying a very well supported $30 Bootstrap theme (ES6 JS, Webpack, etc.) and get going on your project without having to worry about implementing every last line of JS behavior. I'm sure Tailwind will get there with better JS support. I've seen some of Adam's tweets on how he plans to address this problem but I don't think there's a time line on when all of that will be ready to go, or if it'll all be locked into Tailwind UI only (about $250).
- Scarbutt 6y agoFor a react app all what that javascript from bootstrap does is get in the way
- nickjj 6y ago> For a react app all what that javascript from bootstrap does is get in the way But don't you have the choice to not use Bootstrap's JS then, and instead use either premade React components that are vanilla JS or use React Bootstrap components if you wanted to? I'll admit I haven't written any React code but if I Google for React Bootstrap components I find a ton of resources, even 1 to 1 ports like https://react-bootstrap.github.io/components/alerts/ https://react-bootstrap.github.io/components/alerts/. I also see tons upon tons of vanilla JS React components, all ready to go where you can drop in CSS class names and you're done. Someone not using React with Tailwind is left with basically having to implement everything on their own, or try to stitch together a bunch of libs that others have written with their own individual opinions and lack of standards. It's a much different world. It's a world where you can spend 10 hours trying to get a responsive drop down working instead of 10 seconds with Bootstrap.
- seancoleman 6y agoSeveral people have pointed out the redundancy, even hypocrisy, with `@apply` and compositional classes. I like to think of `@apply` and componentization as competing solutions. Just like "composition over inheritance" I believe in "componentization over @apply / composite classes". Ideally, you don't have composite `.btn` classes. You simply have a `<btn>` component which encapsulates appropriate Tailwind CSS classes in the component (no external CSS, `@apply` required). With this framing, `@apply` is the less preferred of 2 approaches. It's good, even necessary, in some situations, but generally you should seek ways to componentize vs. abstracting compositional classes.
- mercer 6y agoAgreed. Although I'd say that in practice I often find the need to use mostly a fixed set of Tailwind classes + some adjustments. It can help to use @apply, but I think even the documentation advises against reaching for it too quickly. a <button> would be a typical use case for me. The way I see it, @apply is like a mixin, compared to CSS atrocious global inheritance. I tend to start with components (and 'micro-components') with all the Tailwind classes, but if I start seeing an obvious pattern I will consider using @apply. In practice, that's worked out very well. It really seems to help with not abstracting too early or too late.
- Latty 6y agoSo what's the answer to semantics and user styles? Just, screw it, they aren't important any more? I mean, I get it, it isn't something most people care about, but I still value them.
- leemcalilly 6y agoJust use Tailwind utility classes in the html while you’re figuring out your design. Once the design solidifies you can write clean, semantic classes for your html and move the tailwind utility classes to your css file using @apply. It’s really the best of both worlds!
- otar 6y agoFirst they ignore you, then they laugh at you, then they fight you, then you win.
- devit 6y agoIt's wrong because it's useless: you can use inline styles instead (and if you gzip the html it's probably going to be smaller as long as you factor in the framework, since essentially you are using numeric LZ backreferences instead of useless long class names). The whole point of CSS classes is that they don't map to fixed styles, so they offer a useful abstraction, allowing you to change the CSS class definition once and effect all elements it applies to.
- Atomskun 6y agoI'm not using Tailwind, but that comparison is wrong. Something like mt-2 still doesn't map to a fixed style, and it also has another specificity than inline styles which makes it easier to override. If you need to globally change the margin that mt-2 adds, you only need to change that class instead of all HTML inline styles.
- richeyryan 6y ago> 3) If you're struggling to abstract reusable higher-level classes/components, the problem might actually be with inconsistent and non-modular design, not CSS tooling. If every page or section is a "unique work of art" then you may have poor UX/design. I can't agree with this more. It is almost punishing in how it enforces consistency. You really have to try to move outside the consistent default it has set and if you find yourself having to do that, it should be setting off alarm bells. I do think it has to be used with a component system though. It provides the context that people miss when you don't have nominal class names anymore. It even encourages something close to styled components I find you have very small components that do one thing.
- red_admiral 6y agoI really like the author's explanation at https://adamwathan.me/css-utility-classes-and-separation-of-concerns/ https://adamwathan.me/css-utility-classes-and-separation-of-... - key points for me are: The question is not "semantic" or not. The question is whether your HTML depends on your CSS, or the other way round - and that depends on what you're doing. Halfway down, it feels like we've somehow managed to recreate the OOP inheritance vs composition debate in our stylesheets (with @extend as an example of inheritance). To me it depends on what you're actually writing - if you're making a reusable component for other people, say a custom DateTimePicker, then it's much more important to be able to restyle the thing Zen Garden-style, than if you're running the front page of your own organisation and want things to look exactly like your house style.
- JoshTriplett 6y agoSuppose you don't want to use a JS framework in your application, and you instead want to serve HTML and CSS via server-side HTML templating. I do understand the premise (mentioned many times in the comments here) that semantic CSS classes have somewhat limited value when you're doing all your HTML via templating. Are there CSS frameworks that help with responsiveness, and work well with templating, but are designed to work exclusively with SASS/SCSS and not leave utility classes visible in the compiled CSS? Preferably something that doesn't start with "let's make h1 and p and ul all completely unstyled", and instead has reasonable defaults that let HTML work like HTML?
- StreamBright 6y agoSorry for my ignorance, I am a backend developer and I am trying to figure out what is the best for my frontend code (when I work alone on something). So far I was using Tachyons (https://tachyons.io/ https://tachyons.io/) and elm-ui (https://elm-ui.netlify.app/ https://elm-ui.netlify.app/). Is there a chance that Tailwind would be better for small / medium sized projects than these? Based on your comment it looks like. The only problem with Tailwind just by looking at the default settings was its size. I was reading somewhere that you can greatly reduce that. Your second point sounds pretty good (almost like a discriminated union for CSS)
- mercer 6y agoOnce I properly used Tailwind for a mid-sized project, I was pretty much sold on it. Size was my main issue. With PurgeCSS the payload can be really small though. it only includes the Tailwind classes that you're actually using.
- StreamBright 6y agoThanks! I am going to check out PurgeCSS.
- Chris2048 6y agoI always felt uneasy about the "separation of concerns" with HTML/CSS/JS. I felt it was at the wrong level - a technical one. HTML and CSS are different technologies, but the domains we should be separating are logic and presentation. These don't always map, e.g. there is such as presentation logic.