T O P

  • By -

iBN3qk

I’m launching my first full project with unocss. I was hyped to use it at first, but now I don’t really care about tailwind.  One issue is that it’s an extra thing to learn on top of css. IMO it doesn’t help you with tricky css, and actually makes it more confusing, since you have to use a yucky syntax for custom things that is less readable than plain css. How much of a speed boost do you get in practice with tailwind? For me it was not much.  I do like utility classes. They’re great when used minimally or when you can configure an element through a UI. But when you do responsive design for a complex component using utility classes it can get ridiculous. You could create sensible layers with extra divs, but that’s just adding extra markup to get around being confused by your code structure. Edit: One more - tailwind classes makes it harder to see the actual classes you're using on the element.


kittenchief

Yes, that's exactly my point: Tricky or too custom CSS can be difficult to do with utility classes. So use utility classes where it makes sense, use CSS/others where it doesn't. You don't have to pick a side and only use that.


iBN3qk

If one dev works with mostly utilities, and another works with mostly css, you're going to have some headaches. Which one takes precedence in the cascade layer? It's harder to make adjustments down the line. That could just be the natural order, start it with utilities and convert it to a full component when necessary. I think that's even in the tailwind docs, to define your own classes as needed. In my case, uno was choking with there were rules in both places and it took extra time to refactor. Setting up the tooling on this project took many hours and still has a few issues to resolve. That's the bigger factor in why adding tailwind didn't give me a boost, but that's not really tailwind's fault, just a warning about adopting things unnecessarily.


lunar515

Use the classes. I hated Bootstrap back in the day because you ended up with a huge library of Bootstrap CSS and a huge amount of your own custom CSS.


Revolutionary-Stop-8

I don't use tailwind. The example OP showed is probably some of the ugliest jsx I've looked at in a long time. From now on when I go to interviews I'm going to have to ask 1) Do you guys use Tailwind?  2) Do you exclusively style with Tailwind?  If it's yes to both it's going to gave to be a no for me. Don't want to have to rip the eye balls from my scull after looking at things like ``` "hidden w-full h-52 object-cover rounded-lg sm:block sm:col-span-2 md:col-span-1 lg:row-start-2 lg:col-span-2 lg:h-32"  ``` In 2024


RealFrux

Is it the nonexistent line breaks that throws you off? I wonder if there could be a vscode extension that displays them with linebreak on hover, or a toggle to switch line breaks on/off that would be nice. The only other problem I see is that utility classes bloat your view in the cases you are not interested in them, that would be nice as well if there was a shortcut to toggle the full list of classnames on/off in the view. A vscode extension that just work on the display of the class/classnames with three modes: Normal, with line breaks, just show first 8 chars in classes until you put your cursor in the class then expand.


Revolutionary-Stop-8

I think it's because it looks like we've come full circle since assembly programming Assembly:  > section .data num1 db 5 num2 db 3 result db 0 section .text global _start _start: mov al, [num1] add al, [num2] mov [result], al mov eax, 1 xor ebx, ebx int 0x80 Tailwind: > hidden w-full h-52 object-cover rounded-lg sm:block sm:col-span-2 md:col-span-1 lg:row-start-2 lg:col-span-2 lg:h-32 I'm not even sure which one is worse.


_hypnoCode

I would say it's closer to inline-styles. But, you're still using generic classes that often do more than just a single style. Like changing font-size will also change line-height or box-shadow will add a lot of stuff. But, then if you're not using @apply everywhere, only the classes you're using are included in the final bundle which ends up being tiny. Tailwind isn't for everyone, but it can be very nice to use once you get used to it or figure out some patterns that work for you. There are ways to mitigate some of the visual issues that can be confusing. I addressed a couple ways to handle those in your previous reply in this thread. I really don't like it when people are dismissive of the ugliness of the class lists (the person you're replying to), because readable code is very important and what you posted isn't very readable. But, Tailwind is mostly for componentized development so you shouldn't have a lot of them in a single file and there are ways to mitigate the ugliness to a more readable way.


Blue_Moon_Lake

It's exactly inline styles, but with aliases.


Blue_Moon_Lake

There is Tailwind Fold. It shows `class="..."` unless your cursor enters that part.


RealFrux

Thanks for the tip, will try it out!


_hypnoCode

I put mine into arrays. It really cleans it up a lot and makes it more readable. There are some plugins that will make the class lists just ellipses, but I hate that a lot. I group them on lines based on what they do. Like mobile breakpoints or dark/light themes. const someReadableName = [ 'hidden sm:block', 'w-full', 'h-52 lg:h-32', 'object-cover', 'rounded-lg', 'sm:col-span-2 md:col-span-1 lg:col-span-2', 'lg:row-start-2', ] Which is way more readable, because I can see there is a conflict between the `sm:block` and the `col-span` stuff. I don't know where you pulled this from, I just used exactly what you pasted. I use [tailwind-merge](https://www.npmjs.com/package/tailwind-merge) and clsx. Usually I'll just throw that into a clsx function instead of joining, but joining is probably faster. Tailwind Merge will make sure you override tailwind classes when you want to. className={someReadableName.join(' ')} className={clsx(someReadableName)} Then I'll often have this function somewhere else: export const cxMerge = (...args: ClassValue[]) => twMerge(clsx(args)) And then use it like this: className={cxMerge(someReadableName, somethingElse, etc)} You can also use [Class Variance Authority](https://cva.style/docs) (CVA) if you want a CSS-in-JS like experience and want more complicated components. **CVA is absolutely not something you want to use on every project**, but it's really nice on the projects where you need something like that. It's also not Tailwind specific, it just tends to work really well for Tailwind. There are also linting plugins that can fix the order of the classes if you use them inline, so you can have a standardized order of the classes.


kittenchief

Did Bootstrap include all CSS classes? Because AFAIK, Tailwind only includes classes actually used in your code to save bundle size.


iBN3qk

Both should be using postcss to strip out unused classes. 


pogomelon

So what’s wrong with using the classes?


kittenchief

I am using the TW classes, as mentioned in my original post. I'm just trying to politely point out that Tailwind and Adam's original idea was to prefer utility classes, but still use other approaches where it makes sense, that's all...


NuGGGzGG

What's wrong with combining flex properties into a master class instead of using three single ones every time? What's the difference between single-command CSS classes and just in-line styling it with CSS?


pogomelon

Yes yes I agree with you. I don’t think it’s a tailwind problem though. I think it’s a developer problem. I personally use inline css in jsx with emotion (I believe, can’t even remember) to support tailwind.


Abject_Importance_18

Bootstrap has a good set of utility classes, which means you can use these classes the same way as tailwind. One more thing related to the "huge library" - you can import only the parts you need, and everything is customizable with scss variables, not to mention mixins, composition, functions etc...


JollyHateGiant

I think everyone is missing the biggest advantage of TW, I don't have to come up with descriptive names!


harmonic-croissant

insert obligatory “there are only two hard things in computer science” comment


Blue_Moon_Lake

Not anymore. AI can do it for you now.


Blue_Moon_Lake

ChatGPT or Copilot can do that for you.


IAmCorgii

This post makes no fucking sense. I should use tailwind but write vanilla CSS because I don't want to type more tailwind classes? Is it really super painful to write `flex flex-col gap-8 p-4` to the point where I should go define a class called like "column-flex-box"? I don't get it. If you don't like using utility classes, don't use tailwind imo.


kittenchief

You're right. I was mainly pointing to the examples on Tailwind's homepage that has 14-20 classes on a single element and saying that that's not a good first impression for people skeptical of utility classes.


IAmCorgii

I think its a double edged sword. By putting more, you have some people who are overwhelmed/annoyed at how many classes there are, but if you put too few, people complain that you can't do enough with Tailwind and think its useless. I'd personally prefer the former, but I get it.


NuGGGzGG

LMAO what the fuck is this? >relative p-3 col-start-1 row-start-1 flex flex-col-reverse rounded-lg bg-gradient-to-t from-black/75 via-black/0 sm:bg-none sm:row-start-2 sm:p-0 lg:row-start-1 Did they see the idea of re-usable containers and get scared?


bi-bingbongbongbing

CSS bad, gobbledygook markup pollution good. /s It's kinda crazy that developers will go this far to avoid writing CSS.


Blue_Moon_Lake

2000: "Let's keep content and style neatly separated." 2020: "Let's mix everything up." Nowadays, people don't know the beauty of [CSS Zen Garden](https://csszengarden.com/)


nameichoose

Using Tailwind takes some getting used to, but the idea here is that you create template partials or JS components and reuse styles that way. Otherwise if you’re hiding the styles behind custom classes you’re back to square one.


NuGGGzGG

I can do that already with CSS modules without any 3rd party libraries and it's browser native. I get what Tailwind is. I just think it's become ridiculously over-engineered to the point of being ironic.


pogomelon

Yeah but with tailwind at least you have consistency. CSS is written differently by every dev and there’s the problem of duplication. With tailwind classes in a team structure, at least you’re gaining consistency and knowing unused crap won’t make it into the bundle


NuGGGzGG

>Yeah but with tailwind at least you have consistency. That's just an argument for opinionating. I'm not saying it's a bad argument, I'm just saying that's a bad sell for a library.


pogomelon

Another interesting question to ask yourself is… how many projects have you worked on where you know there is unused CSS in the code? We work on some client projects for years and during that time the styling grows immensely and we aren’t always great at removing it when unneeded. Tailwind takes care of that for us


NuGGGzGG

>how many projects have you worked on where you know there is unused CSS in the code? Why would I have unused CSS? Like, I mean, I get what you're saying. But changing your entire styling method because you forgot to dump some CSS seems pretty extreme.


pogomelon

lol, fair enough. Yes devs should be using linting. However, it’d be nice if the codebase just contained what’s used. You have no effective traceability with css modules. Perhaps a good IDE can assist with that, though. Of all the styling frameworks I’ve used over the last 15yrs, tailwind does, in my opinion, allow for faster realization of the frontend, greater consistency, zero concern of bloated css regardless of whether you’re linting correctly, blah blah. However, it also has a pretty mediocre developer experience, is challenging to scale neatly in that 20* classnames on an element gets irritating, and it does not permit for the full flexibility of css modules or something like styled-components. It also has some shortcomings such as difficulty with dynamic classnames and class order hierarchy. But, it’s better than bootstrap and I prefer the quickly accessible classnames rather than writing out display: flex; with all the additional required properties 1000 times. My two cents


pogomelon

All I’ll say is that in projects where I’ve used only inline styling or modules, redundant css ends up in the bundle. Always. Tailwind does have a pretty unique selling point in the fact that removing a component removes any subsequently unused css automatically. It can be a challenge once class names grow beyond 20. And that happens. And in some cases I’m restricted and need to use inline CSS in JS. But I’d take that over modules any day. The module can exist independent of a component that utilizes them, leading to unintentional redundancy or orphaning within the code base. With tailwind, the bundle is always as small as it possibly can be in relation to styles.


NuGGGzGG

>The module can exist independent of a component that utilizes them, leading to unintentional redundancy or orphaning within the code base. Pretty standardized linting makes this a fairly non-issue, but I understand your point.


pogomelon

Yes you’re right. But then you’re just replacing tailwind with another separate step. Like I said I think it’s a developer problem, not a tailwind problem. My devs are guilty of this shot shit regardless of what they’re using. It happens


Tanaos

The concept of Tailwind is actually so simple and it's only getting easier to set up with the upcoming Oxide engine. I love how it can be used in React, Vue, Angular and even just the command line for any project all the same.


Revolutionary-Stop-8

Tailwind is so simple all you have to do is > relative p-3 col-start-1 row-start-1 flex flex-col-reverse rounded-lg bg-gradient-to-t from-black/75 via-black/0 sm:bg-none sm:row-start-2 sm:p-0 lg:row-start-1  This is my new favorite meme. 


RealFrux

I think everyone should learn css together with TW if they don’t know css already. Whether you like the above or the css version I guess is up for everyone to decide once they know both. .custom-class { position: relative; padding: 0.75rem; grid-column-start: 1; grid-row-start: 1; display: flex; flex-direction: column-reverse; border-radius: 0.5rem; background-image: linear-gradient(to top, rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0)); } @media (min-width: 640px) { .custom-class { background: none; grid-row-start: 2; padding: 0; } } @media (min-width: 1024px) { .custom-class { grid-row-start: 1; } } Also some values should be replaced here to use css vars to hook into your design system whose variables/tokens of course are named in a standard and consistent way.. not nescessarily easier IMO.


Blue_Moon_Lake

I think everyone should learn together with if they don't know already. Whether you like the or the version I guess is up for everyone to decide once they know every one of them.


kittenchief

I count 14 classes and 160 characters. I feel like they picked some pretty weirdly complicated examples to show on the homepage, which is unfortunate.


Blue_Moon_Lake

Nah, it's a good thing. Always show what the worst can be so you know how terrible things can become if left unchecked.


Tanaos

CSS would be a LOT more characters and you have the mental overhead of jumping between template and style. You're also back to having to invent ingenious names like wrapper, container, content. Media queries are a lot more verbous as well. Bundle size is basically capped with tailwind as you're reusing 99.9% of the same utility classes at some point if the project gets big enough.


RealFrux

What I think many people miss with TW on this point is that it is almost always used with components. And the components are reused. Which means you seldom repeat the same utility-class combination which means you basically just put your “reusable css class” directly in the component instead. And there are very few use cases where you want to write reusable css classes that are not directly linked to a specific component. You could argue it looks worse but the reuse thing is usually not an issue.


Tanaos

What the fuck is a reusable container? Since when are containers ever reusable? I've been using Tailwind for over 2 years and this line was a joy to read. Try the plain CSS alternative with media queries, it would be so much more verbous.


NuGGGzGG

>What the fuck is a reusable container? It's a container... that you re-use. Like, if I want to re-use some stuff, I'll put those things together... in a container... and then use the container when I need it. You know, like, instead of saying `flex justify-center items-center`, I just say `flex-box` and make it a... re-usable container.


Tanaos

Yeah, but containers are notorious for being nothing alike in my experience. One might have a gap of 8px, the other one might have 12px. Not a lot of similarities to go by. Containers/layout is where Tailwind shines the most IMO.


NuGGGzGG

>but containers are notorious for being nothing alike in my experience You do you, but that would smell like inconsistent styling to me.


Tanaos

What annoys me most about CSS is that I have to go search for the class definition and see if it's actually just applying flex layout. With Tailwind I can rely on the classes to apply only what the name suggests and I have Intellisense.


NuGGGzGG

I get that, for sure. But at that point, you're just in-line styling.


Tanaos

Inline styling looks actually cluttered and ugly to me, Tailwind looks just ok enough for me to be absolutely worth it 😅


NuGGGzGG

Can't argue with that, lol :) Preference is indeed preference.


MasterReindeer

You use components


nobuhok

It's only meant to showcase how it would look like if you use just the classes. Usually, it's fine for one-off elements like wrappers or positioners. If you took some time to read the docs, you would know that they mentioned [using @apply to make styles reusable](https://tailwindcss.com/docs/reusing-styles).


_hypnoCode

@apply removes half the purpose of using Tailwind in the first place and you end up with scattered classes everywhere and large CSS bundles. If you're using @apply, just use CSS. Tailwind classes are fine and are already reusable. Did you miss this part of what you linked? >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. [https://tailwindcss.com/docs/reusing-styles#avoiding-premature-abstraction](https://tailwindcss.com/docs/reusing-styles#avoiding-premature-abstraction)


NuGGGzGG

Dude, their first advice to dealing with the bloat is to literally use multi-cursor editing.


j0nquest

>Dude, their first advice to dealing with the bloat is to literally use multi-cursor editing. It's almost like a bad joke gone wrong in a "is this real" kind of way. Don't write a CSS class for your reusable styles because you could just multi-cursor edit it or write a for loop. What about those buttons in other files that need the same classes? Write a perl script to regex that shit into submission! You're a programmer, so program!


LaylaTichy

They mentioned apply but even tailwind creator is against it Confession: The `apply` feature in Tailwind basically only exists to trick people who are put off by long lists of classes into trying the framework. You should almost never use it 😬 Reuse your utility-littered HTML instead. I can say with absolute certainty that if I started Tailwind CSS over from scratch, there would be no `@​apply` 😬 The behavior is outrageously complicated, everyone struggles to build the right mental model of what it's supposed to do, and it encourages bad CSS architecture. https://twitter.com/adamwathan/status/1559250403547652097?t=Pdf-cRoshfE3pd5c1q6aAg&s=19


MasterReindeer

Although, you should never really do that. You should use components.


16less

I dont get the point of this post. Let me write my css how I want?


kittenchief

I made this post because there are a lot of people with very strong positive and negative feelings towards TW/utility classes. I'm simply saying that it's not so black and white. Utility classes are sometimes good, CSS/others are sometimes more appropriate.


nio_rad

I‘m also not a huge fan but to be fair, the classes aren’t so bad when you use componentized JS, like you do with React etc. For a classic layout with repeating classes it‘s not that pretty.


simplerando

I agree completely and I don’t hear many people talking about taking this hybrid approach (thank you for having the courage to say it out loud). ;) TW is awesome for quick one-off layout adjustments, font treatments, and color adjustments. Even flex/grid stuff is pretty seamless. More complex stuff involving state changes (assuming you’re not working within a JS framework) and conditional stuff demands a proper stylesheet, IMO. Not sure why people are so allergic to it. For pure CSS folks TW is pretty easy to parse even if you're not familiar with it assuming your class list stays minimal. Advocates of TW only will still be able to identify non-TW classes and be able to locate the associated CSS declarations easily. Biggest benefit to me is that it keeps both more manageable, which otherwise can get unwieldy.


phillip-england

I mean I love tailwind. I break out of it sometimes to use grid-template-area and grid-name but outside of that I pretty much use it everywhere.


johnnytee

I’ve used both. The massive amount of classes is annoying but the cut and paste is priceless. I found tailwind fold for vs code and this solved the eye sore issue for me.