I'm trying to experiment with Tailwind. It seems so... Scattered and difficult to keep track of. Should I push through and keep practicing with this method of styling or is normal CSS still going to be around for the foreseeable future?
I like structured and grouped stuff I guess.
Top comments (51)
There's a reason why inline styling went out of fashion.
There are some useful tools to keep Tailwind styles under control, such as
Stuff's still quite messy tho. But I'm sure standard CSS will stay.
And I still don't understand how or why it came back
I believe due to the way components are defined. Take a simple Vue SFC. There still is a separation of concerns between
script
,template
andstyle
. + they're meant to be reusable, almost like CSS classes are. So much for the theory.It gets interesting when you try and reuse spacing, colors or even shadows over several components. The moment Tailwind's promise breaks is when I need the same color for, say a navbar AND a button component. Even worse, you probably have those util classes scattered over your whole codebase.
What if the client changes their mind? I want red instead of purple. You'll refactor the all components that use this coloring. Now you might say 'this can be done with a regex replace-statement'. At this very point, the circle closes if you directly applied Tailwind to the component instead of using dedicated classes.
Oh my God, I hadn't even thought of refactoring or redesigns with Tailwind.
That actually caused a legit stress response in me. 😖
It didn't - this is an extremely common misconception.
That article still only makes it sound like inline styles but a bit more convenient this time.
That still leaves the main problem though: You're inlining your styles in your document. It is inline styles.
No, it isn't, any more than an approach like BEM is. You're still using classes for styling, but the scope of those classes is generally reduced a little. It's definitely not a one-to-one relationship between Tailwind classes and single CSS rules in every case. And, by using the
@apply
directive you can easily extract the styles used to a stylesheet.Fundamentally Tailwind is an abstraction over CSS that provides the following benefits:
It's a particularly good fit for component-based JS libraries like React or Vue where you're actively encouraged to extract common UI sections to their own component. In that context it tends to be extremely quick to style it using Tailwind once you get up to speed, making it extremely useful for prototyping. Further into your project, once you have some styles established, then if you want to reuse them in ways that template partials or separate UI components don't facilitate, then it's easy to use the
@apply
directive to extract common styles and create your own more conventional classes, without losing the advantages of consistency mentioned above.Honestly, I thought the same at first and it took a while for it to click, but I'd never go back. I maintain a big legacy project with a huge pile of messy CSS that I inherited and is very difficult to strip out. That would be virtually impossible for that to happen with Tailwind.
That's not the important part though. Whether you're using classes or inline styles, even if one lets you do more things with less typing, the fundamental difference is that you are inlining the actual styling into your HTML.
There may be a CSS document somewhere that defines some more powerful tools in the form of classes, but those aren't styling "rules" in the same sense as with normal CSS; they end up being more similar to CSS properties, in that they just toggle atomic design elements like a colour or the text alignment.
The actual styling is still in your HTML though, so no, it is just plainly wrong to claim utility classes are somehow fundamentally different than inlining CSS using the
style
attribute. They may be more powerful and convenient, and that might for many be the deciding factor as to why this approach is okay to use while inline CSS is evil; but some sort of defense has to be made. One cannot simply claim that "they're different things" and dismiss all criticism of inlining styles into HTML.There's a separate discussion to be had about whether enough of the problems with inline CSS aren't present, or whether the most relevant ones still remain, and that discussion can be a lot more nuanced and ultimately up to personal preference and picking the right tool for the job.
The
@apply
directive renders much of that moot, though, since once you've settled on a style that works you can easily use that to extract common patterns into reusable classes. It depends on the context you're using it in, and for using component libraries like React it often makes less sense, but certainly if you're using Tailwind in something like Blade or Twig templates then using@apply
is more commonplace.At that point, haven't you just gone full circle and basically achieved nothing other than introducing two new dependencies?
No, because Tailwind still works as an abstraction layer. And you can combine the two approaches however you see fit - it doesn't have to be either everything using the utility classes direct or everything using the apply directive.
It's like JSX in that it sounds arse-backwards when you first hear about it, but if you try it then once you get over the hump it starts to make a lot more sense.
It isn't. But it does feel like it for a lot of classes:
...
Yes. Utility-First uses classes so the property:values does one thing and can be easily combined and reused.
When you define selector on your own, you are mostly going to duplicate the css property:value in it. Which causes CSS size to grow, you have to use modifiers to change the css on certain places like
button button--red
. This is less likely to happen with utility first.More info => dev.to/machy8/comment/1p2jj
What you call
button button--red
I just call<button class="danger">
, which will need one selector for thebutton
element and one for the.red
class, which will work for any element, not just buttons.When done right, this gives you a complete
n * m
elements you can style, with every colour applying to every element type (although, of course, in reality some of them will not be implemented because YAGNI).My bad, the
button--red
example was not showing the problem enough.I am talking about reusing a button in an efficient way. What I mean by that is, when for example a button is used on multiple places and needs various indentation, colors, paddings and alignment.
You can't solve that by just one class. How would you solve that?
The way you phrase that question doesn't even make sense when we're talking about proper rule-based CSS; what's the context for these different indentations, colours, paddings, etc.? Does it depend on the surrounding elements? are certain buttons special? Is there just no clear design idea and every button just gets positioned by hand?
Stylify or Tailwind is NOT inline styling.
Stylify uses selectors like
class="color:blue"
that are reused, optimized, combined and etc. The same goes for Tailwind and other utility-first frameworks.Inline styles are
style="color: blue;"
.More info => dev.to/machy8/comment/1p2jj
I really mean no harm or offense, but this project seems like the worst of both worlds.
bundle sizemental load for no visible value addedPerhaps somebody can elighten me - why would I do this?
You're very kind to say you mean no harm or offense, I'd be a bit more harsh and say that this is just a terrible idea.
I think it's abundantly normal to struggle with a new paradigm. Tailwind is a pretty simple mental model once you get it, but it's a pretty big departure from how you do CSS right now.
I guarantee it will click soon enough.
Woa, and how is this supposed to be maintainable? Hard-coded values all over the place, that doesn't really sound like a great idea to me ... you could just as well put a
style
attribute on your HTML elements and stuff all your CSS styling in there, that's just as horrible but even simpler.TL:DR
[...] "separating CSS" is relevant [...] - because it keeps your project maintainable by a team of devs, designers and other team members.
[...] why you think the bundle size will be affected negatively - in fact, judging just by size, I don't think it will. But the value of using this style of applying styles, in my eyes, does not outweigh its costs
I get your points. I'm biased on a few as well, so lots of words would probably not convince. Let me try and elaborate with a few:
About bundle size:
Perhaps phrasing on my first point was poor. With additional bundle size, I meant: It's another package I have to take care of during my dev workflow. I understand your point with atomic component design - it's a pattern where utility CSS frameworks such as Tailwind+PurgeCSS really shine. Because when you develop, you must make compromises between technical cost ( and debt ) vs. value added.
In a nutshell: The value I see at first and second glance does not outweigh the cost of using this package. It's just my opinion. It might as well be wrong and I'm sure there are projects where this will save a lot of time. I just cannot envision them clearly.
About SOC
As per your advice, I did Google "separation of concerns css in js". The first entry that came up led me to the book 'Programming JavaScript Applications by Eric Elliott', where the first sentence reads:
As per my understanding:
So if you say
I say:
Let's create a single language that does HTML, CSS + JS at once. Even better: Let's all use
.jsp
for everything again. That'll be fun.In all honesty: There's a reason why there are whole CSS design systems, such as BEM or SMACCS around. If properly applied, they empower you to scale your product without compromise. Or shift it over to other teams without a lot of struggle.
Or refactor / rewrite a big chunk of your HTML templates. If you scrap your Tailwind-powered views, all the styling is gone for good. If you use a design system, all CSS classes will persist and you can quickly prototype new pages.
Now you might argue: "But this works with Tailwind too!". Sure it does, but building the templates AND the styles at once from scratch doubles the mental payload you might have to carry. If you already have a guiding star, it'll be much easier.
You can use the Tailwind CSS Intellisense. If you have idea about bootstrap then tailwind is easy to understand. You can create any kind of websites without writing single extra CSS. I created 2 landing pages like that only. Final word Tailwind is super dooper
2 landing pages is, no offense, small enough that I could memorize it.
Where I'm struggling is when you have a lot of pages and all the HTML is heavily... "Cluttered."
It's depends how you are reusing the variables from Tailwind Config. You should have the plan when you are starting the project. Like colors, button sizes, border radius and everything. Only you are going to reuse that. Then whenever new designs you are adding you have to add that in config. Another biggest advantage for tailwind is arbitrary values. You can add particular styles in class itself. But you can't reuse those values again. So if you are creating big application or small application it does not matter. If you are reusing the styles properly, Then outcome will be really nice. Thanks
Wow, this is some hell of a fight of arguments here 😆.
I am the author of Stylify and I will try to clarify some points in the thread above and bellow:
Why would anybody use such syntax
auto-cols-auto
is a class from Tailwind. The class is not self explanatory and a dev not using Tailwind daily have to go into the docs or into the dev tools to see what it does. In Stylify you write thisgrid-auto-columns:auto
. Everyone with a bit of knowledge CSS knows what that does.shrink
=>flex-shrink: 1;
(class from Tailwind). The browsers come with, for example a newshrink: auto
. Then they will have to figure out a new name for the new selectory so it makes sense. Which can be confusing.<div class="page-section__container page-section__container--full-size page-section__container--without-background"></div>
. I can't see howproperty:value
selectors are more bad then this.Shure, Stylify syntax might not be for anyone. You can however define custom macros for having classes like
ml-2
orpy-3
if you like it more. It's just a Native Preset that you can ignore and define custom set.There is plenty of hardcoded values
Why not to put the style directly into the style="" attribute
color:red
is generated as.color\:red{color:red}
. This selector can be reused..button
that needs red text, it is generated like this.color\:red,.button{color:red}
. The selector is simply attached, reused and theproperty:value
not generated again => This means smaller bundles._zs,_zx{color:red}
. This is done even by Medium.com and Facebook.const myValue
toconst zx
and nobody cares.Advantages over pure CSS
.color\:red,.button{color:red}
text-align:left
to short_zx
property:value
. There is some article about CSS size from FacebookBloated templates & maintainability
Separation of CSS from HTML
Although I'm developing Stylify and I like the Utility-First + Components approach and dynamically generated CSS, I understand it doesn't fits everyone. Therefore, it's good that there are more tools that do a good job like Tailwind, Bootstrap, Bulma and various approaches so everyone can use whatever suits them. Different tools and approaches for different needs 🤟.
Thanks @lukeshiru for the persistent and extensive comments in a favor of Stylify.dev ❤️.
Normal CSS is going to stay around.
If you have to use something like Tailwind I'd suggest avoiding using any of its utility classes in your HTML. Build your own classes, and include the utilities in them instead, so the HTML doesn't become littered with non-semantic attributes.
This will make it easier to see what's going on, and mean your project can be maintained in the future without resorting to search-and-replace choring.
The way most people use it, and the way most examples show, yes, it's "scattered", but you don't have to do that.
Thanks a lot for this extensive answer, I wasn't familiar with Atomic CSS (but I was with Tailwind, and it's more or less the same concept) ...
I see what you mean, same as Tailwind this is to be used in the context of a framework like React or Vue that allows you to create components, hence solving the problems of "repetition" and "consistency" ... you wouldn't want to create a large site with heaps of HTML where you duplicate
class=background-color:#023
a hundred times across your codebase.You can define components, variables and custom macros (like
my-2
) in Stylify if you need to. Therefore you don't have to have such repetative code.More => dev.to/machy8/comment/1p2jj
Thanks for explaining that, so with these variables you avoid sprinkling hardcoded RGB values or hardcoded font/padding/margin sizes all over your codebase ... I do understand the advantages of this approach, traditional CSS stylesheets also have their problems.
TailwindCss essentially improves inline styling.
If you learn Tailwind you'l find yourself with ease when it comes to writing normal CSS, as many class names are similar in CSS.
Take this example:
It can easily be converted to:
It's also all about practice, eventually you'll get it.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.