This is so true. All the classes in HTML source look so ugly and verbose when you first see it. At first I dismissed the framework and wondered how someone could think this was a good idea.
I kept seeing it pop up, and the comments were always positive, so I put in a little more effort into understanding how it works. Eventually I decided to try it, and within 5 minutes I was making stuff that actually looked nice. I used it to create a really minimal company website, that looks totally custom, and is really lightweight.
Thanks for sharing it, I really enjoy using it!
With Tailwind, we don't try to pretend that you will never need to write any CSS, and instead embrace that fact and give you as much tooling and guidance as possible on how to extend the framework the way it was intended to be extended.
In the situation you're talking about, you would extract a "component class" using Tailwind's `@apply` directive to enforce that the component followed your design system:
https://tailwindcss.com/docs/extracting-components
Then you could update all your buttons at once by making changes to that component class.
The key with Tailwind is that it encourages a "utility-FIRST" workflow, not a "utility-ONLY" workflow. Build your UI with small primitive utility classes, and extract components only when you start to experience painful duplication problems.
Then you could update all your buttons
at once by making changes to that component class
Oh my god, that's genius!I'm looking forward using this right away.
First of all for the wonderful experience to add a class to my buttons. I think I will call the class "button". But I'm open for other suggestions at well.
Second for learning your DSL. Curious what other clever tricks you invented.
And most of all I am sure I will love implementing a compilation step into my workflow to turn your DSL into actual html and css. It always felt a bit too lean to just change a style and reload the page.
.btn {
@apply .bg-grey .rounded-sm;
}Then I also have to write our own classes for modals, cards, toasts, lists, media objects, drop down menus, side menus, breadcrumbs, buttons, forms, their labels, images and their captions, and get the right mix of responsive utility classes as well so they all play nice together.
I'd rather just pick a framework that lets me customize the corner radii, padding, margins, and be done with it.
.align-left {
text-align: left;
}
This is a very reusable class, of course, because it is literally just css but with a different name. But that's what always ends up happening. The lowest common denominator for reusability in css is so low, that you often end up with ridiculously simple classes like this, or close, basically re-inventing css with a different syntax. The new challenge becomes learning this new language and how to compose it.The core issue with CSS is that it has divergent architectural characteristics simultaneously. On the one hand there are usually a set of extremely re-usable primitives: btn, normal-text, overlay, card, etc. Then very quickly, we get higher-level components/styles that are extremely not re-usable: order-form, contact-page, etc. And other stuff in between. Applying the same structural models to all of it will cause sub-optimality at some level.
To address this, I've found that applying different models to different aspects of the css most beneficial. Basically having a mix of both utility css, and semantic css. Low-level, highly re-usable components are defined in a utility fashion so that font-sizes, colors and other things are consistent throughout the site. And complex, non-reusable high-level components that compose primitives, and other custom non-reusable css, to define the top-level components. When the need for sharing common css arises, those can be abstracted out into utility stuff, but part of the goal is to keep the utility part small so that people don't have to learn an entirely new language.
[1] https://adamwathan.me/css-utility-classes-and-separation-of-...
Also, from a previous comment of mine:
“Problem is, defining quantity in the class name doesn’t work. .m10 may be fine for desktop but not for mobile. Then you’ll have media queries which define .m10 as margin: 5px or something, which is nuts. You could go for unspecified .mSmall etc, but in real life, things tend to be more specific and messier, in my experience.”
You can easily do something like 'w-10 sm:w-5', and it'll add a media-query based class.
The solution is pointed above, even more classes for responsiveness.
I'm experimenting with using 'em' and % everywhere, base font size with 'vmin' and scaling font size with %. Works pretty well for scroll-less apps.
Don't go overboard, but a little offset can go a long way
For anyone building React apps with Tailwind or Tachyons, I just open-sourced a library that makes it easier to reuse CSS classes in standalone, customizable components:
https://www.npmjs.com/package/nanostyled
(I think this is a React implementation of what the Tailwinds docs call "Extracting Components".)
I was curious what your thoughts are on a JS-based functional CSS library? I noticed that you mentioned emotion on the docs, and that was also what I thought would be the perfect tool for the job
Imagine a set of functions like `textColor()` or `margin()` that return composeable objects that you'd stick onto css props, and just like tailwinds would throw errors or lint warnings if you didn't pass in values it was configured to allow? (E.g., colors.red, okay, colors.maroon, error? Or maybe colors('red') okay)
I figured it'd more elegantly solve the problem of generating stylesheets that are too large and then needs to be pruned off
One trade-off I see is that the utilities would need to be imported to each file that needs it (as opposed to strings you can put anywhere), but the the good thing about that is you could more easily click into the definitions that way, and you could namespace utilities under a variable so you'd only need to import one thing
I would guess you'd put more thought on this topic than I have, very curious to hear what you think
Not really :) It might have been my reaction some 10 years ago, but right now I think it's quite good. I've done BEM, the atomic crap, OOCSS and what have you but to be honest nothing beats composition when it comes to rapid development. I used Bootstrap in the past, it was heavily customised for the project, and I ended up making it look very similar to your approach. It makes sense when you have 20 Devs working on a website and you don't want to end up having separate stylesheet for every page. Because business hates consistent design and always wants this and and that to stand out just on this one page. It should be easy, right? I look at your framework as an embodiment of understanding business driven development in a big team.
You really do have to try it to shake that impression.
If you need a bit more convincing before you're willing to try it, I wrote an in-depth article a while ago that documents my journey from a "semantic classes"-loving HTML/CSS purist to a utility-loving heathen:
https://adamwathan.me/css-utility-classes-and-separation-of-...
If you want to watch it in action, here's a screencast where I rebuild the Netlify UI in an hour and a half without writing any custom CSS:
https://www.youtube.com/watch?v=_JhTaENzfZQ
...and if you want "social proof", here's an interview I did with Diana Mounter who leads the design systems team at GitHub about how moving to a utility-based approach has made things infinitely more maintainable for them, and given their developers a lot more confidence:
http://www.fullstackradio.com/75
If you have any questions I'll be checking the comments, thanks!