I use Bulma (discussed at the end) for all my projects. It's very easy and quick to get started with, but I found myself diverging from this style when I was starting to add new CSS of my own, to get the pages to look exactly how I wanted them.
And due to the lack of tooling, it's hard to refactor CSS (removing duplicate code, etc.) so I'm not sure how scalable it is to adhere to what the OP says for a long time.
I never tried Tailwind, I landed to Bulma after using Bootstrap, and then Tachyons, for many years, and I really enjoy it. I find myself maintaining an helper.scss file with basic classes that bulma does not support out of the box, but other than that, it definitely saves me time and, overall, improves the outcomes.
I used Bulma as a way of getting up to speed after a hiatus since circa 2001 when it comes to web stuff. I needed to quickly throw together a company site.
I searched around and Bulma seemed ... "not insane" which was good enough for me. And it is good, and good enough. But I can easily see how you could start fighting against Bulma if you wanted to do much customizing.
If I ever get caught between a rock and a hard place and need to do stuff not easily wrought in Bulma, I will check back on Tailwind.
Tailwind would come out ahead because there are fewer classes that contain the same declarations, so the total number of style declarations would be less.
It only seems large because there's lots of repetition based on the various screen sizes, colors, and states (hover, focus, etc). In production it's just a few kilobytes in size.
It puzzles me why these Atomic CSS based systems use various mnemonic systems instead of plain English which is much more understandable. I'm not a fan of human-powered text compression.
Because you'll have 29 different margins, 67 different left paddings, etc all over the place. Tailwind allows you to create a consistent design system. CSS was supposed to be "write one class, use it everywhere instead of inlining". Usually it ends up with nobody reusing that class and everyone creating their on in the same codebase. There's an article I don't have a link handy, which explained how ridiculously many classes were used by GitHub/Lab, Airbnb, etc. Now even GitHub have their own utility based CSS system and others are following along, including Bootstrap with their CSS utility classes.
> Because you'll have 29 different margins, 67 different left paddings, etc all over the place.
That's not really the case since SCSS became a thing. If SCSS doesn't help you, Tailwind won't, you can ignore their classes just as you could ignore preset constants.
Honestly, to me it seems like people are just starting "fresh" with a benefit of some experience, and ascribing the benefits of experience to the tool.
I've used SASS for years, and yet switching to tailwind felt reaaally nice. have you tried it for yourself, or are you just assuming that you understand the practical differences?
Can you elaborate? I can't agree with you. Tailwind is meant to provide a consistent design system, of which CSS size should never get out of hand (which is the case then using regular CSS). Whenever I use Tailwind, I end up adding maybe 20-30 lines of CSS and I never have to open a CSS (or other sass/less/whatever) ever again. Have you tried Tailwind or you're just assuming what you're saying?
It's based on how often you use a helper. For instance, changing letter spacing is verbose (https://tailwindcss.com/docs/letter-spacing) as it's not something you use that often. Tweaking spacing is very common and "padding-horizontal-2" uses an awful amount of characters.
In what context is this "an awful amount of characters" an issue? GZip compression is fairly standard these days, and languages based on plain english (or similar languages) has a better level of compression than random text because of repetitive nature of sequences of characters.
I can't believe that mnemonic based languages are easier and more readable than something closer to a natural language. And with the assumption that code is written for humans first, computers second, what is the point of inventing a language that's less readable than the one it's trying to replace? CSS compresses particularly well, as every Atomic CSS based framework tends to point out on it's landing page!
I agree with your sentiment. I think this is because half the programmers like mnemonics and the other half prefers English, so no matter what you do people criticize your choice. People call Java verbose and perl write-only.
After spending more than, say, two hours with Tailwind you'll probably read the first line much faster than second one (since there's less to read and you don't need to scroll). Humans are very good at pattern recognition, and you'll quickly read "mb" as a symbol in itself and not as "m[argin] b[ottom]".
> I can't believe that mnemonic based languages are easier and more readable than something closer to a natural language.
Well, it's worked out pretty well in mathematics. This is not about file size at all. It's about defining an "alphabet" of common concepts.
Ah, I see your issue: you do know you can have whitespace inside attributes? You don't have to clump all the class names on one line. Scanning vertically is quicker than through the horizontal line-noise of both your examples.
This also has the benefit too, that if you use version control line-based diffs to see what's changed, it will highlight the specific css class name that changed. Handy if you need to ensure that whenever you change the bottom margin, you can see at a glance whether the small prefixed one has been updated too.
On the other hand if you regularly need that many classes to style an element, perhaps it's a good place to refactor commonly occurring class names into a set, and label that set with a meaningful identifier.
As for mathematical notation, it's about as understandable to me as my understanding of Hanzi.
I have trouble with the following statement. Complete flexibility is a bad thing? If I accept that how is limiting options to 30 not providing too much flexibility?
"Limits & standards. With normal CSS, I can make any element any width I want. For me, this is not a good thing! With tailwind, there are only 30ish options for width"
In some situations, choice reduction can come from abstracting them away. Then, by definition it's a good thing. Assembler v C. Of course, if the abstraction is inadequate (leaky), then you haven't really abstracted anything away.
As an example, it means you’ll never be off by a pixel here and two pixels there. You’ll be off by, say, five pixels or ten pixels instead. Your mistakes will be obvious and easy to fix.
It’s the difference between working with Lego and working with ordinary hunks of smooth plastic.
That's the nature of any higher-level language: you reduce flexibility and gain ease of use for particular use cases.
E.g., With Ruby and Python and Java you lose a lot of the flexibility that pure C gives you. You can't directly manage memory directly any more, for example. Is that a bad thing? Not for most people.
Note also that one of the major goals of an operating system is to limit flexibility. The first thing an OS does on starting is to lock a bunch of functionality away from any other code. Similarly, virtualization and containerization are mainly about removing capability.
Actually it is, especially when you're working with a team of developers.
Imagine that your designer puts together a design system built on a soft grid. The rules in the design system are what ensure consistency across the site.
If you have a team of developers, sooner or later you'll manage a junior dev who interprets the design as a pixel perfect layout, and starts defining widths on elements per their own personal interpretation. Maybe they eyeball it, maybe they measure it, maybe they measure it but don't include the border.
You can catch such things through training and code review, but it puts the burden of managing design consistency on a senior engineer. Starting out with a constrained system is one easy way to ensure consistency of design across large projects.
Say you want a div to be a specific width: 135px, how do you make it without writing any CSS? Or you want a specific shade of a colour? Or you want to style things that are not in your html (third party widgets).
You treat your stylesheet as your style guide, design system, or single source of truth. That's where you define your fonts, colors scales etc.
So you actually don't have to think about specific widths while you're building, you reference a width that is already set up in your stylesheet!
I find that it improves the design to dev workflow. You experiment with design in a design tool like Sketch, and then translate your final idea or rules into a stylesheet, which is the basis for your live prototyping in editor & browser (wrapping HTML elements and referencing styles in your stylesheet).
Be sure to check out the Wizard Zines site they are talk about. It had old school hand drawn zines about topics such as git, debugging, and more. Here is one on tcpdump
Absolutely. She's really good at making a complex topic approachable and bringing a lot of excitement as she shows you around. It reminds me how incredibly cool I thought these tools were when I first learned them.
When I make something, I want all and just the relevant pieces of what I am doing in my face, and then I want them gone when I do the next task.
So if I were to every try to design a page, I want all the relevant design items there when I am figuring it out, and then when I am done, I don't want to see them again.
So if you spend a lot of time designing the html/css then this approach makes sense. I don't want to jump into the css file and then back in the html file.
However, if I want a particular look and feel for a site, and then knock out the css, then I want the css in a different file and then I want to focus on the layout and the logic.
So my guess is that the original author builds lots of new sites and moves on. My guess is that the original author does not build one large site for a large company that has a consistent look and feel for years (till the rebrand).
I really don't see the benefit. Sure, you don't write "CSS", but you write a lot of classes that look like CSS. If you write class="bg-white no-underline" you could easily write style="background: white; text-decoration: none;" and every frontend guy will understand it. I don't get the point.
If this article didn't make it click for you, that's understandable. It took me a long time of hearing about this & thinking it was stupid before it made sense. When that happens to me, it's usually a sign of something good.
But I only want the element to be the color it IS, not a range of colors it could be. Whats to stop a dev using $concrete when they should be using $cloud? or $linkGray instead of $headerLinkGray?
these inconsistencies compound, especially across teams.
Nothing would stop them from choosing to use cloud vs. link gray but it's far easier to identify and fix those cases than it is to have #CCC, lighten(#CCC, 10%), etc. around the codebase. This doesn't fix human error, just reduces it.
I admit, after the middle of that article anything would look good.
It's a good realisation that there is no real separation of semantics and styling between HTML and CSS. XSL would have been one solution, but it was just too XML-ly. Personally I found it a joy; I could design my pages with pure semantics alongside a turing-complete stylesheet.
However now we have web components - your HTML and CSS are tightly coupled, but scoped. And the semantic / styling separation is provided by the shadow DOM. So no need to create inner platforms like Tailwind.
Sounds to me like the author should simply use SASS + a good autocomplete feature in their IDE.
When I write CSS, I use a lot of shortcuts. I simply write "mt5" and then press tab, it then auto completes to "margin-top: 5px;". If I write "tdu"+tab and then it goes "text-decoration: underline;". The IDE also shows me in a drop down all the options that can be used after writing "text-decoration".
Changing standards because you do not want to learn or remember something is the perfect example of programmer "laziness". Why remember this super common language when instead I can develop and remember a new obscure abstraction instead?
Oh no, laziness! Someone is doing something in an easy and convenient way that somehow doesn't match up with other people's ideals of conceptual purity! :'(
Bloating your markup with classes is simply a bad habit. It bites you hard in the long run.
Even the framework that they are using proposes better alternatives.
“Tailwind encourages a "utility-first" workflow, where new designs are initially implemented using only utility classes to avoid premature abstraction.
While we strongly believe you can get a lot further with just utilities than you might initially expect, we don't believe that a dogmatic utility-only approach is the best way to write CSS.”
A class based rapid prototyping framework is a powerful tool, don't get me wrong. However, like all tools you should only use them when they truly are needed.
How so? If what I need is (as the author describes) to occasionally make a quick relatively-usable site, and I want to do some styling on it, and then forget about frontend UX until I need to do another small site 4 months from now, how will this pattern bite me?
How can you achieve reuse (DRY) with this? Every time I have a button, if I want my buttons to be consistent and have a single place to change them, I have to like invoke a button partial that just outputs my <a> with 20 classes on it? It's a lot easier to reuse a CSS class (an abstraction) than a template of a chunk of HTML (an indirection) -- especially across divides of languages/runtimes/client-vs-server if you have any of those.
I think the article provided good insight on this: "I wonder if the reason this approach makes more sense now is that we’re doing more generation of HTML than we were in 2003. In my tiny example, this approach to CSS actually doesn’t introduce that much duplication into my site, because all of the HTML is generated by Hugo templates, so most styles only end up being specified once anyway."
So you write your button one time in a reusable button component, then reference the component and avoid writing the same 20 styles again. I think this has benefits as it keeps all the information for a single component in the same location, making it easy to understand and edit the component from a single location.
I agree with the point you're making, but it doesn't seem to address my question. The author describes the usage pattern that I find myself in, and I suspect is relatively common among non-frontend devs: we aren't particularly skilled in CSS or other frontend web dev work, but every now and then we find ourselves wanting to make a quick, simple, but usable site as a landing page for some other project we're releasing.
For people in that niche, frequent tweaks/changes to the styling seem unlikely: I'm going to make the site once and unless it breaks I'm unlikely to come back to the code for it.
The parent comment I replied to makes the direct claim that this class-based pattern will bite me, and I'm curious if somebody can help me figure out how that would happen.
Could you suggest how it's bloating the markup and how it'll bite you in the long run?
I understand that maybe adding a bunch of classes for every element will increase the overall size of the page but if it's served with gzip compression doesn't it actually (maybe only technically) work better to have repetitive classes everywhere instead of unique class names?
The problem with granular classes is that you project won't scale in an efficient way. It also makes refactoring almost impossible.
On a small one page website, do use them. However in something more complex like an e-commerce website theme or a complex web app, you will regret it quickly.
One of the selling points of CSS is the ability to scale and refactor very quickly and easily. Class based frameworks remove all those benefits. Extracting components and building sementically is the solution. As I said in my previous comment, that framework they are using supports it. They say it themselves:
“*While we strongly believe you can get a lot further with just utilities than you might initially expect, we don't believe that a dogmatic utility-only approach is the best way to write CSS.*”
I have worked on many contracts where the client came to us because their current web agency wanted to charge crazy prices to refresh their website's design (e-commerce websites change at least one a year). Almost every time, those projects are a pain for both the team and the client because the previous developer decided to be lazy and use classes or inline styles everywhere.
It’s not reusable. It’s not consistent. It’s not scoped.
It may be hard to see now how it will bite you now, but I promise you, it will. It would take hours to explain why, but I am speaking from years of experience here.
There is a reason large organizations have abandoned this approach, and it isn’t just personal preference.
This talk gives a pretty good explanation, Airbnb.design, Netflix, Facebook, and Instagram have many others
I tend to think laziness is positive when it inspires better architectures. Picture a dev who just sits there drinking his coffee until he finds a way to do something without typing a lot or remembering a lot of small details. Now picture a dev who dives in enthusiastically, writing the same bits of configuration a hundred times with small tweaks. Whose code would you rather maintain?
If an abstraction makes it easier to do what you want to do, it's a useful abstraction.
The project in question uses PostCSS, which is to CSS as Babel is to Javascript.
The point of a broad set of utility classes is to have predefined and discrete classes that map to conventions your application uses. Here's a few examples from an app I use:
Each of these are a "standard" that we use throughout the app. There are NO one-offs. These can then be composed into "component" classes (e.g. .Button, or .TextInput).
The benefit is mostly threefold:
* Maintainability is great. No hunting throughout the templates when you want to change the primary colour. Just update the .u-colorPrimary class, or its underlying variable.
* Our developers can look at a design and mostly do it themselves. No need for a CSS pro to come in.
* We can package these into a node module and share them across our apps.
You're right: this is laziness. I don't like to repeat myself, and I like consistency.
This way is great, it's not the one I use but I have no issue with it.
I prefer to use SASS variables along with a strict build system that refused to build if the developer isn't using variables that are injected via a config YAML file. In the end, we are both working in a similar way.
That being said, ".u-colorPrimary" is great. You can easily refactor it and it should scale well. However, ".bg-orange" and ".text-white" aren't great.
To address the author's “oh, another bootstrap site” line, Bootstrap offers a "css grid only" option. Which, I've found to be great when you don't want the Bootstrap look, but want a grid system in place to build with.
I really like these atomic/functional css libraries with any sort of frontend framework or templating system that leverages components.
Personally, I have been using Tachyons with React for the past couple months, and it's been a blast. Compared to writing html templates with Emmet and css with Sass, I feel as if I am more productive and like I can reuse more components.
I've also found Tachyons & React to be an amazing combination. The only trouble I've had is extracting common CSS class strings into tweakable components, e.g. a <Button> whose background color you can easily override, or a <Header> with tweakable font weight.
I wrote a tiny (1kb) library to make this easier. For anyone working with React and functional CSS, I hope it's helpful:
Seems like an interesting library! I also encountered this issue, but I ended up just passing in colors/borders/spacing as props. I will have to see how that holds up for complicated UIs.
Thanks! I started by just passing props too, and I could see that approach working forever. I just got tired of having to always specify <Button bg="blue" border="ba1" />, when 90% of the buttons in the app were blue with a border.
I fear that many will not prefer attribute bloat in their markup.
And many are moving to React, does this sort of toolset matter anymore? Not being negative, genuinely serious. Does this tool make sense for apps going forward? To me it seems Tailwind is for little html things.
I've been saying for years that, in these days where all HTML is generated, CSS makes no sense and we might as well just style inline. You probably already have a "button" class in your UI framework that contains the HTML for rendering a button; put the styling there too.
CSS sucks because it lets you reuse code to a very small degree, but doesn't go very far. Less or sass seem much betters, if for no other reason than referencing common behavior.
> So if you have a large number of buttons or other elements with the same class you will be repeating yourself over and over.
In the HTML, sure. But so what? It gets compressed in transport so there won't be significant overhead there (similar to how remote desktop protocols that send images with compression turn out to be just as efficient as those that tried to send intelligent drawing commands), and the browser has to compute the final style for each element anyway so there's no overhead in-memory either.
> This would be a nightmare to work on/maintain.
HTML is an output format, you don't edit/maintain HTML any more than you edit/maintain binary machine code. And keeping the styles inline allows better encapsulation: the styling for each component lives in that component, you don't have the spooky action at a distance of child selectors.
What frameworks treat HTML as an output format, and what is the input? When I see samples of React code, all the HTML (in the form of JSX) is still handwritten, just combined dynamically.
Sure - you write the html snippets by hand (and those are still very maintainable if you use inline styles). But you don't maintain the final page that might have e.g. twenty buttons, so that's not a case to optimise for.
Most (all?) of the classes apply exactly 1 line of CSS.
I see this as an anti-pattern, because to me it looks like inline styles with extra steps. The only thing it avoids is accidental strong specificity.
The reason we have CSS is that it's really easy to make HTML unreadable - after all it's essentially a 1D medium(lines of text) trying to describe a 2D space.
Inline styles = open ended, while classesrestrict you.
Also this is switching things around. Now your html depends on your css classes and not your css depending on your html. No more broken css when a dev modified the html structure and didn’t realize that one of the hundreds of lines of css now doesn’t get applied right.
The difference is that inline styles can't use several important CSS features, like media queries or pseudo-classes like `:hover`, `:focus`, etc.
You have to first be convinced that inline styles are not inherently an anti-pattern to understand a framework like Tailwind. After that, the benefit of Tailwind is that it's like inline styles, except with the ability to style elements in different states and at different screen sizes.
I've been using Tailwind lately and I really like it. It lets me prototype and iterate quickly, and then when I've settled on a design I can create component classes for those completed styles. It has made doing frontend work slightly more bearable for me.
Lol here we go again. Why does this get people so riled up?
I suspect people who immediately dislike this maybe are not using some type of component-based UI. CSS classes are all about code-reuse. If you have the concept of say a "button" in your UI, and you are copying your button markup every where you use that "button" then it certainly makes sense to have a class for your button markup that encapsulates the styles for that button in a style sheet somewhere.
If using a button component however, you've already created a place for the concept of your button to exist. At that point if you go on making a class in some style sheet that also represents the concept of your button, now your button concept exists in multiple places, linked together by one or several class names. That seems a lot messier to me than using utility first styles, but I don't think it really makes a huge difference one way or another.
The problem isn’t how the author has used it, but using this approach for something that will grow and change over time. This is one of those things that seems really nice when you start, and gets uglier and uglier as time goes on.
If you see this enough times, and are tasked with cleaning it up/working with it, it can become difficult to appreciate it in the beginning too.
after doing a project with tailwind I have completely abandoned the idea of BEM. while it was nice having clean classes, having the styles directly in the html is way easier to reason about.
Sass makes it a lot nicer to write BEM notation. The long class names used to bother me too, but it is actually much nicer than not knowing where a class came from. Is `.right-button` a global button style, or unique to this component?
I agree that sass enables nice readable BEM, but I don't really think that BEM makes markup any easier to read than something like tailwind.
If you're into knowing where your class came from, it seems tailwind would be even better for you because now you have access directly to your styles right there in your markup. Skip the class step altogether!
If you're interested, I wrote a short blog post recently with some very similar thoughts on the role of classes vs inline CSS in the component paradigm.
Tldr: for me, classes make more sense for reuse in simpler content-heavy scenarios. For anything remotely complex or webapp-like, I think they are the wrong abstraction.
After doing a project with this I think Tailwind is great! There is no need to choose either BEM or Tailwind, they can co-exist in the same project and they both makes a lot of sense (for different use cases). Typically, I’ll start with tailwind classes and extract simple tailwind components when those classes start to repeat. If the component is clearly reusable and has enough complexity, I’d switch to BEM.
It's easy to understand why it gets people "riled up." For 20+ years the entire industry has been pounding the table about why inline styles are so bad. Thousands of articles have been written espousing this idea, and likely hundreds of thousands of hours have been spent devising better alternatives in the form of CSS frameworks.
Whether Tailwind is functionally and pragmatically better than inline styles isn't even important. It looks like inline styles, so the first reaction of almost any experienced designer/developer that looks at it is to make that association and squirm in discomfort at its mere appearance.
CSS has a bit of a learning curve, the probably most difficult to understand is the C (cascading ) part, and where something more specific over-rides something less specific. It's simple. Yet complex. But it's very powerful to be able to change the look of something, without touching the code that makes up the site/app content. And change theme by replacing the CSS-file.
I prefer the hybrid approach, having a mix constantly repeated utility styles for things like padding, margin, floats, and colors, and then having custom SCSS/CSS for the rest.
that's what tailwind does, look into the components docs. essentially utilities vs components are a matter of definition order, such that utilities can always override components.
184 comments
[ 2.4 ms ] story [ 201 ms ] threadAnd due to the lack of tooling, it's hard to refactor CSS (removing duplicate code, etc.) so I'm not sure how scalable it is to adhere to what the OP says for a long time.
Last time I migrated a project from Tachyons to Tailwind, it was quick and painless.
I searched around and Bulma seemed ... "not insane" which was good enough for me. And it is good, and good enough. But I can easily see how you could start fighting against Bulma if you wanted to do much customizing.
If I ever get caught between a rock and a hard place and need to do stuff not easily wrought in Bulma, I will check back on Tailwind.
> By comparison Tailwind seems really heavy (over 1.5x larger than Bootstrap!), but it turns out that this comparison isn't totally fair.
https://tailwindcss.com/docs/controlling-file-size/#app
That's not really the case since SCSS became a thing. If SCSS doesn't help you, Tailwind won't, you can ignore their classes just as you could ignore preset constants.
Honestly, to me it seems like people are just starting "fresh" with a benefit of some experience, and ascribing the benefits of experience to the tool.
I can't believe that mnemonic based languages are easier and more readable than something closer to a natural language. And with the assumption that code is written for humans first, computers second, what is the point of inventing a language that's less readable than the one it's trying to replace? CSS compresses particularly well, as every Atomic CSS based framework tends to point out on it's landing page!
> I can't believe that mnemonic based languages are easier and more readable than something closer to a natural language.
Well, it's worked out pretty well in mathematics. This is not about file size at all. It's about defining an "alphabet" of common concepts.
On the other hand if you regularly need that many classes to style an element, perhaps it's a good place to refactor commonly occurring class names into a set, and label that set with a meaningful identifier.
As for mathematical notation, it's about as understandable to me as my understanding of Hanzi.
Ok then.
I recommend this post by Adam to anyone who is interested in learning more about utility first CSS.
https://adamwathan.me/css-utility-classes-and-separation-of-...
"Limits & standards. With normal CSS, I can make any element any width I want. For me, this is not a good thing! With tailwind, there are only 30ish options for width"
It’s the difference between working with Lego and working with ordinary hunks of smooth plastic.
E.g., With Ruby and Python and Java you lose a lot of the flexibility that pure C gives you. You can't directly manage memory directly any more, for example. Is that a bad thing? Not for most people.
Note also that one of the major goals of an operating system is to limit flexibility. The first thing an OS does on starting is to lock a bunch of functionality away from any other code. Similarly, virtualization and containerization are mainly about removing capability.
Imagine that your designer puts together a design system built on a soft grid. The rules in the design system are what ensure consistency across the site.
If you have a team of developers, sooner or later you'll manage a junior dev who interprets the design as a pixel perfect layout, and starts defining widths on elements per their own personal interpretation. Maybe they eyeball it, maybe they measure it, maybe they measure it but don't include the border.
You can catch such things through training and code review, but it puts the burden of managing design consistency on a senior engineer. Starting out with a constrained system is one easy way to ensure consistency of design across large projects.
Say you want a div to be a specific width: 135px, how do you make it without writing any CSS? Or you want a specific shade of a colour? Or you want to style things that are not in your html (third party widgets).
So you actually don't have to think about specific widths while you're building, you reference a width that is already set up in your stylesheet!
I find that it improves the design to dev workflow. You experiment with design in a design tool like Sketch, and then translate your final idea or rules into a stylesheet, which is the basis for your live prototyping in editor & browser (wrapping HTML elements and referencing styles in your stylesheet).
but if you want something not provided explicitly by Tailwind, you have to write it yourself.
https://wizardzines.com/zines/tcpdump/
Reminds me of many computer publications in the early days
So if I were to every try to design a page, I want all the relevant design items there when I am figuring it out, and then when I am done, I don't want to see them again.
So if you spend a lot of time designing the html/css then this approach makes sense. I don't want to jump into the css file and then back in the html file.
However, if I want a particular look and feel for a site, and then knock out the css, then I want the css in a different file and then I want to focus on the layout and the logic.
So my guess is that the original author builds lots of new sites and moves on. My guess is that the original author does not build one large site for a large company that has a consistent look and feel for years (till the rebrand).
The author of Tailwind suggested I read his best effort at explaining why this makes sense.: https://adamwathan.me/css-utility-classes-and-separation-of-...
Towards the end of the article it started clicking for me.
“With inline styles, there are no constraints on what values you choose... Utilities force you to choose...
You can't just pick any value want; you have to choose from a curated list. Instead of 380 text colors, you end up with 10 or 12.”
these inconsistencies compound, especially across teams.
It's a good realisation that there is no real separation of semantics and styling between HTML and CSS. XSL would have been one solution, but it was just too XML-ly. Personally I found it a joy; I could design my pages with pure semantics alongside a turing-complete stylesheet.
However now we have web components - your HTML and CSS are tightly coupled, but scoped. And the semantic / styling separation is provided by the shadow DOM. So no need to create inner platforms like Tailwind.
When I write CSS, I use a lot of shortcuts. I simply write "mt5" and then press tab, it then auto completes to "margin-top: 5px;". If I write "tdu"+tab and then it goes "text-decoration: underline;". The IDE also shows me in a drop down all the options that can be used after writing "text-decoration".
Changing standards because you do not want to learn or remember something is the perfect example of programmer "laziness". Why remember this super common language when instead I can develop and remember a new obscure abstraction instead?
Even the framework that they are using proposes better alternatives.
“Tailwind encourages a "utility-first" workflow, where new designs are initially implemented using only utility classes to avoid premature abstraction.
While we strongly believe you can get a lot further with just utilities than you might initially expect, we don't believe that a dogmatic utility-only approach is the best way to write CSS.”
Read this page: https://tailwindcss.com/docs/extracting-components/
A class based rapid prototyping framework is a powerful tool, don't get me wrong. However, like all tools you should only use them when they truly are needed.
How so? If what I need is (as the author describes) to occasionally make a quick relatively-usable site, and I want to do some styling on it, and then forget about frontend UX until I need to do another small site 4 months from now, how will this pattern bite me?
So you write your button one time in a reusable button component, then reference the component and avoid writing the same 20 styles again. I think this has benefits as it keeps all the information for a single component in the same location, making it easy to understand and edit the component from a single location.
For people in that niche, frequent tweaks/changes to the styling seem unlikely: I'm going to make the site once and unless it breaks I'm unlikely to come back to the code for it.
The parent comment I replied to makes the direct claim that this class-based pattern will bite me, and I'm curious if somebody can help me figure out how that would happen.
I understand that maybe adding a bunch of classes for every element will increase the overall size of the page but if it's served with gzip compression doesn't it actually (maybe only technically) work better to have repetitive classes everywhere instead of unique class names?
Look at the button from his article:
<a class="text-xl rounded bg-orange pt-1 pb-1 pr-4 pl-4 text-white hover:text-white no-underline leading-loose" href="#">Buy for $10</a>
That's way too granular.
On this page it documents how you can create component classes https://tailwindcss.com/docs/extracting-components/
Then in your styleOn a small one page website, do use them. However in something more complex like an e-commerce website theme or a complex web app, you will regret it quickly.
<a class="text-xl rounded bg-orange pt-1 pb-1 pr-4 pl-4 text-white hover:text-white no-underline leading-loose" href="#">
is no better than
<a style="font-size:16px; border-radius:5px; background:orange; color: white; text-decoration: none;" href="#">
It is simply a fancy way to use inline styles.
One of the selling points of CSS is the ability to scale and refactor very quickly and easily. Class based frameworks remove all those benefits. Extracting components and building sementically is the solution. As I said in my previous comment, that framework they are using supports it. They say it themselves:
I have worked on many contracts where the client came to us because their current web agency wanted to charge crazy prices to refresh their website's design (e-commerce websites change at least one a year). Almost every time, those projects are a pain for both the team and the client because the previous developer decided to be lazy and use classes or inline styles everywhere.It may be hard to see now how it will bite you now, but I promise you, it will. It would take hours to explain why, but I am speaking from years of experience here.
There is a reason large organizations have abandoned this approach, and it isn’t just personal preference.
This talk gives a pretty good explanation, Airbnb.design, Netflix, Facebook, and Instagram have many others
https://youtu.be/TuLY1cYM57g?t=530
If an abstraction makes it easier to do what you want to do, it's a useful abstraction.
The point of a broad set of utility classes is to have predefined and discrete classes that map to conventions your application uses. Here's a few examples from an app I use:
.u-colorPrimary { font-color: var(--utils-css-c-primary) !important;; }
.u-textSmall { font-size: 0.75rem; }
Each of these are a "standard" that we use throughout the app. There are NO one-offs. These can then be composed into "component" classes (e.g. .Button, or .TextInput).
The benefit is mostly threefold:
* Maintainability is great. No hunting throughout the templates when you want to change the primary colour. Just update the .u-colorPrimary class, or its underlying variable. * Our developers can look at a design and mostly do it themselves. No need for a CSS pro to come in. * We can package these into a node module and share them across our apps.
You're right: this is laziness. I don't like to repeat myself, and I like consistency.
I prefer to use SASS variables along with a strict build system that refused to build if the developer isn't using variables that are injected via a config YAML file. In the end, we are both working in a similar way.
That being said, ".u-colorPrimary" is great. You can easily refactor it and it should scale well. However, ".bg-orange" and ".text-white" aren't great.
This button from the article is really bad:
They should at the very least made a component with the styles and then apply via ".button" class.Personally, I have been using Tachyons with React for the past couple months, and it's been a blast. Compared to writing html templates with Emmet and css with Sass, I feel as if I am more productive and like I can reuse more components.
It's worth a try if it interests you!
I wrote a tiny (1kb) library to make this easier. For anyone working with React and functional CSS, I hope it's helpful:
https://www.npmjs.com/package/nanostyled
I fear that many will not prefer attribute bloat in their markup.
And many are moving to React, does this sort of toolset matter anymore? Not being negative, genuinely serious. Does this tool make sense for apps going forward? To me it seems Tailwind is for little html things.
With elements with a large number of style rules, you add a lot of very long lines to your html.
This would be a nightmare to work on/maintain.
In the HTML, sure. But so what? It gets compressed in transport so there won't be significant overhead there (similar to how remote desktop protocols that send images with compression turn out to be just as efficient as those that tried to send intelligent drawing commands), and the browser has to compute the final style for each element anyway so there's no overhead in-memory either.
> This would be a nightmare to work on/maintain.
HTML is an output format, you don't edit/maintain HTML any more than you edit/maintain binary machine code. And keeping the styles inline allows better encapsulation: the styling for each component lives in that component, you don't have the spooky action at a distance of child selectors.
http://reahl.org and http://naga.re
I see this as an anti-pattern, because to me it looks like inline styles with extra steps. The only thing it avoids is accidental strong specificity.
The reason we have CSS is that it's really easy to make HTML unreadable - after all it's essentially a 1D medium(lines of text) trying to describe a 2D space.
Also this is switching things around. Now your html depends on your css classes and not your css depending on your html. No more broken css when a dev modified the html structure and didn’t realize that one of the hundreds of lines of css now doesn’t get applied right.
You can achieve the same, but with much less clutter using BEM. Or even better: BEM + SASS.
The difference is that inline styles can't use several important CSS features, like media queries or pseudo-classes like `:hover`, `:focus`, etc.
You have to first be convinced that inline styles are not inherently an anti-pattern to understand a framework like Tailwind. After that, the benefit of Tailwind is that it's like inline styles, except with the ability to style elements in different states and at different screen sizes.
I wrote a post a while back that is my best effort at arguing for the validity of presentational class names if you're interested: https://adamwathan.me/css-utility-classes-and-separation-of-...
I suspect people who immediately dislike this maybe are not using some type of component-based UI. CSS classes are all about code-reuse. If you have the concept of say a "button" in your UI, and you are copying your button markup every where you use that "button" then it certainly makes sense to have a class for your button markup that encapsulates the styles for that button in a style sheet somewhere.
If using a button component however, you've already created a place for the concept of your button to exist. At that point if you go on making a class in some style sheet that also represents the concept of your button, now your button concept exists in multiple places, linked together by one or several class names. That seems a lot messier to me than using utility first styles, but I don't think it really makes a huge difference one way or another.
If you see this enough times, and are tasked with cleaning it up/working with it, it can become difficult to appreciate it in the beginning too.
.i-dont__find-bem--very-readable.
If you're into knowing where your class came from, it seems tailwind would be even better for you because now you have access directly to your styles right there in your markup. Skip the class step altogether!
I treat my name spacing the way I do in most source code. All the code for a unit is in the same file or in files called out from that file.
If you’re not nesting in Sass you’re missing out on some of the better parts.
https://medium.com/@davnicwil/how-i-learned-to-stop-worrying...
Tldr: for me, classes make more sense for reuse in simpler content-heavy scenarios. For anything remotely complex or webapp-like, I think they are the wrong abstraction.
Whether Tailwind is functionally and pragmatically better than inline styles isn't even important. It looks like inline styles, so the first reaction of almost any experienced designer/developer that looks at it is to make that association and squirm in discomfort at its mere appearance.