Tailwind UI
tailwindui.com
tailwindui.com
On the other side of things, sites without a framework generally opt for a convention like "BEM" (block-element-modifier). BEM seems to be the worst of both worlds, both abandoning the "cascading" part of "Cascading Style Sheets" and still requiring verbose class names!
I've been working on a Tailwind project for the last six months with a team of around 8 people. We did a bunch of initial work getting the Tailwind config just right and some base styling in place, but since then we've barely written a line of CSS. Yes, the templates are verbose, but they are also incredibly readable and easy to reason about what classes are doing what. On-ramping new people has been easy as well, since they don't have to learn some custom system, instead they can just read the docs on the Tailwind site.
> BEM seems to be the worst of both worlds, both abandoning the "cascading" part of "Cascading Style Sheets" and still requiring verbose class names!
BEM doesn't abandon the cascade (or really care about it). What BEM is actually pushing back on is rule specificity. For example:
#navbar a { color: blue }
/* Can't do this, it doesn't change my navbar-submenu colors */
.navbar-submenu { color: inherit }
/* Have to do this as a workaround */
#navbar .navbar-submenu { color: inherit }
And now I'm in an arms race with myself over rule specificity.If someone writes '.nav a' they're saying "select all links inside of nav", but what they really wanted to say was "select all nav menu links, and nothing else", a class like '.nav__link' will never select other links that happen to be in the nav (CTA buttons, logo links, etc) and will survive markup restructuring, something like ".nav > ul > li > a' will not survive minor markup changes as it doesn't express what someone wanted to select in the first place. I think this way of thinking brings a lot of benefits that most CSS frameworks don't give.
Hmm, that's not really my main concern. My main initial feeling is that it feels like just as much work as writing plain CSS?
For comparison, I've been using Bulma for a lot of my projects so far, and given that many websites/web apps really don't have any special unique layout, it's covered my use cases very well so far, to the extent that I really don't recognise the anecdote of needing lots of little `margin-left: 3px` rules. (Though a magic number like that would be a red flag anyway...)
The primary benefit that Bulma gives me there is that it's just much less work! I really don't need to throw together some shadows, rounded corners, borders, etc. to make something look like a card, but I can just use Bulma's `card` class, and set some global settings w.r.t. colours and dimensions.
Is there a reason I might be interested in Tailwind still?
Bulma or Bootstrap are ok if you stick to the defaults, but it get's tricky if you work with different fonts, icons and graphics in general, where you often have to make small adjustments to align things.
Everything sits in their own little bounding box and might look off next to another element. Tailwind and other utility based systems with generous enough sizing scales make it easier to make those small adjustments.
Sure you could re-center icons from your icon libraries manually within a design tool and adapt their bounding boxes to fonts this way, but it's a time consuming task.
As far as concrete UI components go, I'm not sure this technique is any better, especially since you often need pretty ad-hoc styling with pseudos etc.
I think if CSS had built-in mixin support you could have the best of both worlds pretty easily, still crossing my fingers we get that some day, would be nice to drop all these build systems.
To me, the biggest benefit of Tailwind and utility classes in general is that it removes the cognitive overheard of having to think of class names while designing a new page.
For example, if I'm working on a card and I want some text below the main text to have a smaller, gray font size. What do I name that class? "card-sub-text", "card-sub-title"? No - don't even worry about it - "text-sm text-gray-700" and move on.
Later on, if I end up repeating that combination in a number of places, I have more context of what that class name really should be, and I can extract the utility classes to a specific class name.
Really powerful stuff that has helped to increase my velocity quite a bit.
> For example, if I'm working on a card and I want some text below the main text to have a smaller, gray font size. What do I name that class? "card-sub-text", "card-sub-title"? No - don't even worry about it - "text-sm text-gray-700" and move on.
What's the difference with "color: gray; font-weight: 700"? In this case I really don't have to care about the property order, whereas in your case I would guess you still have the cognitive overhead requiring you to know that "gray" comes before "700" (unless it's expected to be preprocessed away? what if I use text-700-gray?).
The biggest benefit of this over inline styles is that if I decide to change the color of "gray-700", since those colors come from a configuration, I only need to change it in my configuration.
It takes some getting used to of the rules, but after a day or two I don't even need to think about what the class names are.
But gray-700 says it's a 70 % gray. Changing it to something else is akin to changing "color: #666" to "color: #444" through redefinition (JS?).
i.e. "text-gray-dark", or "text-gray-700", would have a class with a single css property:
color: #4A5568;
By default Tailwind comes with a default color palette with hand picked colors. They were hand picked by a designer, not determined through an algorithm.
https://tailwindcss.com/docs/customizing-colors#default-colo...
#FFFFFF is white
They are 3 sets of 2 hex numbers.
#FF0000 is red
#00FF00 is green
#0000FF is blue
(you hear of RGB, Red Green Blue, in that order)
Now if you want a darker color (closer to black) you lower FF to a lower value. A darker blue would for example be #0000AA
if you want a lighter color you increase the other 2 color values. A lighter blue would be #2222FF
If you don't like hex there is rgb(0,0,255) which does exactly the same.
There is also rgba(0,0,255,0-1) with an alpha channel.
You can also put any part of that in a css variable and use it where you like.
body{--foo: 0,0,255,0.5; bar:0,0,100 }
p {background: rgba(var(--foo)) }
div {background: rgba(var(--bar), 0.8) }
I've actually come across C code that had "#define ONE_THOUSAND_TWENTY_FOUR 4096" because that was the audio buffer size and later had to be increased to 4096 but the macro name was never changed. AUDIO_BUFFER_SIZE would probably have been a better name in the first place.
Most code is not that bad though, haha. But that is still my first reaction. What if instead of slightly changing the gray color, you now want them to be blue and underlined? Or take HN for example, the username, vote buttons, and timestamp are all #828282, but have different class names. Is keeping this in sync ever a problem in Tailwind? This is only my first time looking at Tailwind, but it seems it's not really meant for "complex" apps where you'd run into these problems often?
I think for your specific example, I would use the `@apply` directive to apply certain utilities to all links.
I've used Tailwind on large, complex apps with around 50 screens (so far), and using extracted components or partials hasn't been a problem at all with keeping things in sync.
``` a { @apply text-gray-700; }
// now becomes a { @apply text-blue-500 underline; } ```
The documentation goes over this pretty well, I think.
https://tailwindcss.com/docs/extracting-components#extractin...
This sounds like a boldRedText pattern to me [1]. I get the idea of adding utility classes that inherit the base classes, but altering the definition of the "gray" class to be some other color feels wrong.
In reality I'm pretty sure that you wouldn't alter it directly either and that if you do, you would try to keep the 10 versions of it somewhat linear, or at least consistent with the use that you do of it. Theses colors are there for prototyping quickly yet still offering good looking result. Sure "color: gray" works, but look at the colors choices [1], it's much better than the default gray and offer more choice than lightgray, gray and darkgray without having to do math over #808080.
[1] https://tailwindcss.com/docs/customizing-colors/#default-col...
1) Sizes are standardized in a predetermined set of discrete size classes. So you start to think about sizes, padding, margins, etc in terms of steps instead of values. You can change the steps in one place and they apply globally. It's a little easier to standardize a rough style guide compared to starting from scratch.
2) Colors are standardized in a similar way. You just need to configure your app's core colors and then you can just think in terms of steps instead of color values.
3) You have a smaller set of "best practice" means to achieve most outcomes compared to all that's available with css. You don't need to know the best way to do what you want, you can just browse the documentation to find what you want.
Outside of that, you still have to use @apply to collapse utility classes into more semantic classes if you want style changes to cascade (tailwind recommends using components or view partials to achieve this instead of via css classes, though this would work equally well with inline styles)
The styles are very verbose, just like with inline styles. They are only slightly shorter than inline styles since they are basically abbreviated forms of inline styles.
You can still do everything tailwind does for you by using your own style guide and building out css classes, but tailwind gives you a head start.
It feels like it makes you more productive in the beginning because you get a toolset with a lot of decisions already made for you, but I suspect it will make things a bit slower as the app gets more complicated.
text-gray-700 is not a font-weight, it's a color predetermined by the framework. They aren't generated, they are hand picked by a designer. Each addition of 100 is a bit darker.
https://tailwindcss.com/docs/customizing-colors/#default-col...
So essentially, what's the difference between style="color: gray;" and class="text-gray-500" is mostly that you get a more beautiful gray (they add a bit of blue in it).
I guess "text-sm" is also similar, with an hand picked size which appear nice on every device and can be considered "small text".
.custom-bg-color {
background-color: theme('colors.gray.500');
}I love though that as an engineer you would be hesitant to use Tailwind, but you are not aware of how new variables are.
I think Tailwind seems to make sense for any prototypes works and probably even an MVP for a company that still doesn't have a shared CSS that represent the style of the company.
> I love though that as an engineer you would be hesitant to use Tailwind, but you are not aware of how new variables are.
Why would you think I'm unaware? Please see: https://caniuse.com/#feat=css-variables
I'm not writing software for IE 11 (released in 2013), Opera Mini, QQ, or Baidu, so CSS variables are widely supported for my target demographic.
`text-sm lg:text-lg` is something you simply can't do in style attributes.
`text-gray-700` or `color: var(--mycolor-gray);` is indeed not _that_ much different. (I'm using CSS variables here to achieve the same as Tailwind variables.)
Seems like a step backwards at worst and identical to Bootstrap/Foundation at best. Everyone provides class primitives like that
What you're describing offends separation-of-concerns
If it turns out that later down the line I realize that "every card should have that size and color for the card title", then I'll pull it out to a separate class or part of a partial or something like that.
The idea being at that point then I have more context around when and how that particular section of a component should be displayed, so I have more context about what I should name the class (i.e. "card-subtitle").
I feel like the documentation explains it fairly well if you're interested in reading more about it:
https://tailwindcss.com/docs/extracting-components#extractin...
This removes the need to name at all. It can just be .card > h2 or whatever and there you would do your font-weight and color.
I don't even need to move over to my css file at all - I stay within my template and stay within my flow.
It seems crazy and counter-intuitive at first, but I find that it makes me a lot more productive.
I have been paralyzed by trying to do things the semantic way before too though. And now no one cares according the markup I venture to look at now and then.
Some editors like Brackets allows you to edit other files online and handles css specially so you can edit it just by hovering over class names, etc.
In fact, I think this scheme is a whole lot closer to what most developers actually want, which is to have composable classes that actually represent something semantic. "text-sm" is your small text. That should be consistent around your application. If you change what some of that looks like, you probably ought to be changing all of it. If you want a few elements to use a different text size, then go change the classes on those.
I really encourage you to try this out. I was somewhat skeptical, but it truly feels like a huge step forward. Going back to something like Bootstrap/Foundation or- God forbid- BEM feels incredibly painful to me now.
I also don't think separation-of-concerns is a reasonable goal. I read this article [1] after using tailwind for a while, and I agree with almost the entirety of it.
[1] https://adamwathan.me/css-utility-classes-and-separation-of-...
But you could also define a color called text-primary, if you are concerned that something like this would happen.
One of the biggest benefits in my opinion is, to communicate the different utility classes to your UI/UX person. By restricting him/her to discrete values for margin, padding, colors, etc. they will not go overboard with there designs and also make the handoff way easier. If you use zeplin for example you can for example define color names in the sketch file and zeplin will show them in their UI. You just click on a text and see "ahh she used text-gray-500".
Much less friction in the workflow.
As for the concerns about messy markup mentioned in some other reply. True that can happen sometimes, but if you use React or Vue, you can encapsulate a lot in components. The markup in the components high up in the tree will look basically the same. And the leaf components should be quite small anyways.
Another really nice benefit to the old way is that you don't have to worry about breaking stuff. When you change bg-gray-200 to bg-gray-300 you can be sure that it only affects the element you have in front of you.
But in the end I think people have to try it out to be able to judge Tailwind.
Regarding style attribute. You can’t do responsive-ness, hover- or focus-states in style attributes.
It’s hard to compare to bootstrap and the like because they give you components, while Tailwind is just a different way of writing CSS. You can of course extract components, btw, and define stuff like text-primary (that you can change in a central variable).
Using Tailwind (or other atomic css frameworks) makes it easy to reason about styling while staying completely inside HTML during editing. Within a few days, you quickly memorize all the names and can build complex visuals while also benefiting from the well-designed default sizes and options.
I don't think Tailwind is perfect, but find the benefits of consistent naming, easy modifications, and the "instant" design system, more than outweighs the negatives of utility classes. The framework also feels very light since there's no need to preprocess potentially hundreds of Sass files and I can just modify the view template or component directly. PurgeCSS also works amazingly well with Tailwind.
Adam, Jonathan, and Steve are also generous contributors to the opensource community!
My approach is to use class names, and in a custom stylesheet use tailwind's @apply function, so
.page-section { @apply bg-white rounded shadow overflow-hidden max-w-lg; }
You update it in the one place (template/render function/component/helper/view/partial) that you wrote it.
> What you're describing offends separation-of-concerns
The entire HTML/HTTP/CSS/Javascript web schmozzle offends separation of concerns and is shot through with layering violations and dependence on the specific rather than on abstractions.
Tailwind responds to that particular shitshow by refactoring style at the point of HTML generation, which (particularly in a template-driven world) makes a crapload more sense than trying to build higher-order style abstractions in a language that was explicitly intended to not be Turing complete.
If the HTML ERB had chosen DSSSL instead of CSS, we wouldn't need this.
When it comes to developer productivity and happiness, composition beats inheritance, even in declarative paradigms.
There are also live demos of the app and marketing pages:
1. https://tailwindui.com/page-examples/landing-page-01
2. https://tailwindui.com/page-examples/detail-view-01#
Plus a screencast on how to use it to build these pages: https://vimeo.com/393580241/82c6d7c5f6
plus javascripts
See how dumb that sounds?
Caveat: not a UI developer, I’ve mostly done backend work And DevOps for quite some time.
It's an interesting concept.
It’s way too much effort for me to want to mess with, and then you have to repeat the same things for every site you make.
Yes, you can check off on your list that you no longer have any .S files. But did you actually gain anything?
> Most C libraries do too much.
> They come with all sorts of predesigned components like functions and structs that might help you move quickly at first, but cause more pain than they cure when it comes time to make your program stand out with custom behavior.
> Tailwind C is different.
> Instead of opinionated predesigned components, Tailwind provides low-level utility macros that let you build completely custom functionality:
void main() {
BEGIN_TAILWINDC
MOV(RAX, 4);
MOV(RDI, 1);
MOV(RSI, "Hello world!\n");
MOV(RDX, 13);
INTERRUPT(128);
END_TAILWINDC
}
And then every Hacker News discussion of Tailwind C would inevitably include a link to their "Why using Tailwind C is definitely not just as bad as writing inline assembler" documentation page.Ooh, and then the creator of Tailwind C would start selling the Tailwind C Library, with like an implementation of memcpy that you just cut-and-paste into your program every time you need to copy memory.
The leap between vanilla css and tailwind is not large at all.
Assembly: raw html and css C: A framework like Tailwind Python: Components, like TaildwindUI or any of the React components I’ve seen
I think that’s not a bad analogy.
CSS frameworks are great because there is a flavor that should fit just about anyone.
The use case is for creating Template Components with something like React, Vue, Hugo, Razor or another component template framework. Tailwind offers a large list of customizable variables to use to help keep your CSS consistent. You're still pretty much writing CSS though, just with shortcuts. I consider it Emmet CSS + Variables. I also highly suggest using a plugin for your editor that offers hinting on all the crazy names no matter what CSS framework you use.
If you want a higher abstraction, Bootstrap or Foundation provide that. There is now also this Tailwind UI that you can purchase that would also provide that to some degree.
Whether building a regular website or a web-app I generally just use component names (like .card) the same way. I'm more of a fan of defined components with limited variations though than people being able to change anything with a lot of utility classes. Sort of like having a succinct API with a constrained depth. I see css as an api to the original designs and Tailwind introduces too much freedom for my comfort! I will endeavour to give it an honest trial though and maybe I will meet you somewhere in the middle.
"PHP is an awful language, superior developers write in Perl."
"Rails is bloated and slow, making it unfit for any real work."
"True developers don't rely on frameworks, writing all your own code is the only way to be performant."
If you wanna handicap yourself, be my guest.
I've written three or so projects in TailwindCSS, and it lets me create responsive designs quickly. It gives me a very sane set of defaults to build off of. And most importantly, it helps me get a product to production faster than writing raw CSS.
personally having written css since I was a teenager, my gut reaction is "eww", but if the team or stakeholders deem it to add value to a project and not affect productivity, sure why not?
I can not force myself to use something like this but I’ve been writing CSS for a long time.
I use BEM and predefined sets of colors and space values to ensure consistency and that’s efficient enough for me.
Why would you have shared in-house css and components? Just write vanilla css right?
Tailwind is that shared in-house css and components for people/team that don't have shared in-house css and components. If you can afford to build one, sure use that!
This is made for prototyping too, this is to get to the MVP quicker. Again, if you have a shared in-house css and components library that does the same, sure use that instead, it makes much more sense!
> Those were fine when I was a jr developer - not anymore
That's a scary sentence. Why do you believe it matter whether you are junior or not to use that library? A library is made to avoid doing twice the works. If you already did that work, you don't need that library, that's for sure, but it's totally unrelated to your level as a developer.
1. https://angry-hypatia-f1529a.netlify.com/
2. https://github.com/philippbosch/tailwind-ui-purge-css-exampl...
If even the creator of Tailwind doesn't use Tailwind properly, does anyone?
I'm not particularly against JavaScript, but I'm not willing to install and use npm and several hundred dependencies.
All documentation for purgecss always includes postcss and a gazillion other packages I have never heard of.
Maybe something in Go, as a single executable?
Good luck being a employable lol
still in js, but very fast, ~10KB (min), 0 dependencies, and does not require npm [1]:
however, it expects properly formed html and css; the parsers are quite unforgiving.
(i'm the author)
But I think a lot of people wouldn't just replace the CSS framework, they'll rethink the whole UI and everything that goes with it with a big operation like that.
</sarcasm>
I might reconsider it again once I am more comfortable with what frontend has become, but that is still quite a bit away.
A big part of Tailwind's value is that it provides a curated, well-documented subset of the most important CSS attributes. The utility classes are consistently and concisely named (unlike many native CSS properties, which grew organically).
You're totally right that it is yet another abstraction, and that can be tiring. Personally I found it to be well-designed and transparent enough to make it worthwhile.
I'm guessing most of the naysayers here work in the web applications world with component-based architectures, where the HTML/CSS is a small portion of the total time they spend coding, so they can't understand why someone would sacrifice readability, maintainability, and organization for speed on something that isn't a bottleneck for them. The thing is, it absolutely might be a bottleneck for agencies and other companies that need to build lots of custom sites.
And the argument is that this comes at the expense of maintainability.
It seems like if your project is not suited to a "website bashing" or prototyping approach long term, and you need semantic classes to allow for easy theming type use cases, it could be more trouble than it's worth?
I literally manage something like 10 different products/websites. And the only way to stay sane and have some pace with features is to use bootstrap for all of them (we currently use bootstrap for maybe 5 of them, and the rest were inherited sites that we're migrating).
I love the look of this but don't have the time or the will to migrate all our sites to learn yet another CSS meta-language with its own sets of concepts and classes.
I've always liked the Bootstrap 4 CodeBase theme ($28): https://demo.pixelcave.com/codebase/be_pages_dashboard.php
It's not the same exact look of course, but it has dozens of pages, widgets and components that look clean. It's all well formed code too with ES6 JS, Webpack, etc..
I don't think the license is worded very well. If you read it as "end user" being a visitor of your site then pretty much every theme on themeforest would cost $999 but that's not the case.
I think what the license means is if you're bundling the theme in with a product you plan to sell and distribute then you need an extended license, unless it happens to be for freelance work in which case a regular ($28) license is fine (the "note to freelancers" clause handles that). If you have a free or paid SAAS app or something like then you can use a regular license too because you're not distributing the theme as a paid product.
I've talked to the author of the theme directly and mentioned using it for a course platform I'm building (end users of the site would be paying for individual courses). He didn't mention needing an extended license for that. He even went as far as giving me permission to release the course platform as open source with his theme included[0].
[0]: What I wrote isn't official for saying you can do the same. I recommend contacting the author directly if you have intent to do that.
abler is free and open-source HTML Dashboard UI Kit built on Bootstrap
Normally with themes it would be time prohibitive to do so, but the nature of utility-css is that it's relatively straightforward to implement each component, even without looking at the CSS that's obviously easy to inspect.
I think what they should do is build a tool that let's you build your entire site using these components and charge for that. Otherwise, I guarantee within a year of today, 2/26/20 there will be a free version of this on GitHub created by the community.
---
On a side note, if some bored person out there wants to make a huge splash in the CSS community, figuring out a way to target a specific DOM element, create the equivalent of an AST and specify a "dictionary", which would be a utility-css framework (tailwind, tachyons, basecss, etc) and finally reimplement the targeted DOM element in the chosen framework would be amazing.
Assuming you buy into utility-css, that would remove all existing friction in adopting it. Then that would mean you could grab an existing theme [1] and convert it to tailwind components as desired.
Tachyons is licenced under MIT too.
There are tons that look visually appealing, but very few I've found that take a component-based approach (where they document each component individually - or think about how they interplay with each other). I've found the CSS is usually muddled, they often have legacy build pipelines that has to be rewritten to fit with Webpack, and a distinct lack of flexibility.
If Adam solves that side, Tailwind UI will be worth the money.
If it causes other theme providers to up their game, even better.
No because I believe that for every enterprising person wanting to circumvent paying for software, there are that many people who want to support the entrepreneurial spirit Adam and company show, and pay for good work. That's what capitalism is suppose to be about at least, anyways.
This is quite doable for us at Protoship (we've built both a design-to-Tailwind CSS+HTML converter as well as a webpage-to-Sketch Chrome extension). It is a very appealing idea - to be able to recast any webpage into a Utility CSS framework, but I'm curious to hear about situations where it would've been useful in commercial work.
Tailwind-UI looks very interesting and I would have no problem paying for it, rather than getting a "free" version, if only for the long-term sustainability. Community projects often go through endless rewrites, and suffer from feature creep and lack of direction.
In a business setting (I run a self-funded SaaS business) I am much more interested in a framework that fixes bugs and is stable.
The only thing that worries me is that the pricing is one-time rather than subscription. How can the authors expect long-term sustainability with a one-time payment? Maintaining a CSS library is a continuous effort, not a one-time thing.
I think if utility-css frameworks get popular someone will abstract the components from the frameworks and things like tailwind ui will become unnecessary (rather it will just be utility-css-ui and will work with any css-framework that implements the "interface").
Semantic UI is the perfect example of why you shouldn't go with something that's generic. Unfortunately the project just became too bloated for one person to handle. Your concern about sustainability is a good one and that's exactly why many of the frameworks' authors sell themes. However, themes usually require a lot of work and are difficult to implement using the actual css framework. tailwind ui is different because if you had the theme it's really easy to recreate it because it's utility first.
It is described in the Tailwind docs here - https://tailwindcss.com/docs/utility-first/
a) how hard it is to make a library like this that's any good
b) people will want to support them anyway
$249 (or $599 for a team license) one time is really very little if it does what it promises.
When your job is delivering high quality UX and there are always more apps to build in the pipeline, having someone give you a library of useful components works.
I have licenses for probably 4-5 of these, and they've all saved many hours of time, and resulted in avoiding the cost of a dedicated designer.
<div class="lg:flex lg:items-center lg:justify-between"> <div class="flex-1 min-w-0"> <h2 class="text-2xl font-bold leading-7 text-gray-900 sm:text-3xl sm:leading-9 sm:truncate"> Back End Developer </h2> <div class="mt-1 flex flex-col sm:mt-0 sm:flex-row sm:flex-wrap"> <div class="mt-2 flex items-center text-sm leading-5 text-gray-500 sm:mr-6">
Personally I would prefer Bootstrap over this approach.
It also makes responsive styling a lot easier in my experience.
I think this masks a lot of complexity that you have to manage when taking on this approach. And it's not because the approach is good or bad, more what it is or isn't suited for.
The example on the homepage is very slickly presented, but the end result markup is extremely verbose. If I have a Card component, I would like to update them all at once when needed which is what css classes are generally good for. I find BEM naming conventions much more friendly to come back to than markup full of miniature class names.
I will stick to BEM + colors and sizes maps because this feels almost like using the style tag on each element.
For non-css expert engineers writing spa components, tailwind can be useful.
I can also see that it’s not trivial to mix tailwindcss and scss processors so it’s a no for me.
It has the benefit to limit spacing and color sets to presets but I already do this in my BEM codebase.
Though, you can still use BEM with TailwindCSS through the @apply directive. Adam calls the directive a kind of "trick" to get more devs on board with utility-first but it does help a lot of you're used to reasoning about CSS with BEM.
Then you update the styles of the card again but the new styles clash with the ones in those tailwind classes and you end with broken styles in some elements.
Mixing components and utility classes is a recipe for future chaos.
edit: thinking more, you can override classes. So yeah, maybe utility/atomic classes are not as effective here.
Or, if it is a minor change, then conditionally include / exclude a small subset of tailwind classes.
The point is to not write your own CSS, you only use tailwind classes. In this way you can look at the template for each of your components and reason about / edit their style and layout easily.
Yes, you may have more than one card in your system, but in all likelihood you aren't repeating the HTML for that card more than once, rather you have it in a template of some kind which is called. So while you may have more than one card on your site, you probably don't have the template for it defined more than once. (at least ideally you don't)
For those cases where you do want to extract that code, Tailwind makes that easy to do.
Tailwind is a weird thing and like I said I really thought it was insane at first. But after rewriting a site in it in a few days I have to say it is better than the standard semantic CSS by a mile.
So you can move really fast and experiment when you need to, and then extract to something shared when you're ready to DRY it up.
button { @apply border bg-white; // ... }
So now it's the worst of both worlds: an abstraction layer and dirty code.
When you use inline styles for everything, you're making the initial development a little faster by making future maintenance and changes a lot harder. (Like, if you decide headings should be italic instead of bold, that's a one-liner fix if you're using CSS properly, but if you're using inline styles you have to individually fix every heading on every page.) So most people have internalized "don't use inline styles for everything" as a general rule.
But if you don't actually care about that sort of future maintenance (or you're charging hourly for it), then using inline styles for everything looks really attractive to you! But you can't literally use inline styles for everything because even non-experts know that using inline styles for everything is bad for future maintenance. So instead you pull in Tailwind so you can say you're using a CSS framework.
Once the components get too bloated, you start forking them, and you are back to each page looking subtly different.
You should have utilized a template engine in the first place. So you'd only have to change the layout/partial/component that is responsible for rendering the heading. Moreover, you could also have extracted the component with css by creating a .title class and using @apply.
Tailwind recommends PurgeCSS, but i'll plug my own lib here:
https://github.com/leeoniya/dropcss
i have a specific section on how to handle tailwind's unorthodox classnames:
https://github.com/leeoniya/dropcss#special--escaped-sequenc...
<div class="lg:flex lg:items-center lg:justify-between">`
Isn't this why we have CSS preprocessors? So we can do:
<div class="description-of-what-this-is">
.description-of-what-this-is { .lg_flex() .lg_items-center() .lg_justify_between(); }
Assuming there's enough complexity beneath the mixins to justify their use -- some of these might just be CSS properties.
What you find to be clean code might go the opposite way for someone (i.e. why would I use scss if utils are all I need?).
You might work with large scale apps where BEM may make more sense. You might work on a site builder where utils might be better. You might be creating splash pages for marketing purposes where going for element selectors may be enough.
// in JS, then build .btn-blue { @apply bg-blue-500 text-white font-bold py-2 px-4 rounded; }
With Tailwind you'd have `bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative`. Then I'd have to change my HTML everywhere to update the appearance of alerts & its not always obvious that I'm looking at an alert in code.
Nope. Once you see same (sub)set of classes repeated, you would instead define .alert and .alert-danger using Tailwind's @apply directive, and you now have a single place to change how your `alert alert-danger` looks :)
<Alert type="danger"> Are you sure? </Alert>
Of course this solution would work in other templating engines as well.
The alternative would be extracting css components:
.alert { @apply px-4 py-3 ... }
.alert-danger { @apply bg-red-100 .. }
So for a button, you might have a class='rounded shadow p-4', which becomes rounded corners, drop shadow and a padding of 1rem.
On the one hand, you have to do a lot more to code. Instead of just adding class .btn in Bootstrap you would need to add all those classes.
On the other hand, the styles are not all the same as everyone eles's, and you can have different styles for one element if needed. You can have a button that only shares some styles, or a theme that has a lot of complimentary styles.
A downside of utility classes, is that you don't have a base to work off, you have to know what classes would go on a button in order to quickly get something nice.
The solution to that is a numerous collection of Tailwind Components. Copy the styles as ou need, and modify as you need.
Until now, there was no official collection. Some of my favorite collections are at https://tailwindcss.com/components https://www.tailwindtoolbox.com https://tailwindcomponents.com https://www.creative-tim.com/learning-lab/tailwind-starter-k... Forms: https://tailwindcss-custom-forms.netlify.com
But now we have an official collection from the framework creators themselves. Use them as a base, but - by changing a class or two, easily modify them for your project.
Of course, in Bootstrap, you could always have written your own classes to overwrite Bootstraps. That can be much more complex, and usually you wind with side effects. In my experience, the more you deviate from the prebuilt styles in semantic libs such as BS, the more hair you lose.
Utility CSS allows you to change or customize far more flexible in a fast pace environment than Bootstrap.
If you prefer lighter CSS, Tachyons is another option which I found more easier to read even if I have a long classes.
I'm a frontend guy (among other things) and for past 2 years I've been using Nuxt (app server, node.js) and Vuetify (material UI framework for Vue.js). Given what kind of results that stack can (and does) achieve, I wonder if people in the same boat as me (using the same stack) would even attempt to use Tailwind CSS/UI.
Whatever the case is, I'm glad there's a project that's useful and that helps authors finance their effort. Thumbs up!
(Again, I realise the failure is probably on me. But I don't get it.)
- The classes cover many common use-cases and, in some cases, present a simpler "API" than hand-rolled CSS would
- You can eyeball a HTML fragment and get a good idea of how the pieces fit together, compared to the normal approach of needing to work out what each individual class does, and then how they fit together. It's easy to remember what the Tailwind classes are doing.
- It's dumb, but the ability copy-and-paste entire HTML fragments from one place to another and have the styling "just work" is slightly mind-blowing
- Some CSS attributes work oddly depending on the order in which they are applied, or the order of the composition of classes that both attempt to apply the same attribute, and that problem goes away with Tailwind
There are other advantages, but these were all quite surprising to me, because my expectations of CSS have always been quite low.
Not really. styled-components makes this simple if you're using react.
Tailwind is essentially unusable without a build step. You can configure it to make composite classes for common styles (button, card, etc.), but if you buy into their philosophy you'll probably want a component-based design (web components, React, Vue, etc).
It's better than working with CSS manually because you work at a slightly higher level. If it was transformed into a css-like language I would prefer that. As a non-UI expert, I also enjoy having an enumerable limited set of sane choices for most properties.
With tailwindcss or tachyons you get some of the benefits of component frameworks without having to use component frameworks, because you can colocate html & "styles" in regular template based systems and scope sections on a page this way. Great DX if you need to render sections conditionally, e.g. for ab testing.
If you think in sections rather than individual components anyway, which tailwind kind of promotes by design, you don't gain that much with a component framework.
The actual CSS functions like an inverted triangle (see ITCSS) the utility classes access from the html, so you won't have any specificity issues because it's already sorted out by having the CSS in a fixed order.
Another advantage is portability of sections between modern frontend JS frameworks and template based systems, you can just copy and paste things around, which is harder if the information about the styles is separated from the html, and without a fixed inverted triangle like CSS structure.
Isn't a section just a case of a component?
Yeah, a section is a component, but in my book it also involves the visible page background where the element is located (you could override the page background with a section color), like a slice of the page.
https://tailwindcss.com/docs/utility-first
The core principle is that you wrap up all UI elements into components. Most frontend and backend/template frameworks allow you to do this. You then verbosely apply the Tailwind classnames to perform styling, staying out of custom .css files all together.
I was skeptical of Tailwind too until I actually tried it. It’s one of those things like JSX that defies received wisdom but in real use is very nice.
Do people really struggle with this?
<div class="hero">
<h1 class="hero-title">Heading</h1>
<p class="hero-tagline">Tagline</p>
</div>
It far more straight forward just to call something what it is and you can actually read the CSS afterwards.> You need to go digging around in all your stylesheets to figure it out and in most cases actually load up the page and inspect it.
When are you changing CSS and not inspecting the page at the same time? You are going to have to check your work. This doesn't happen if you keep things tidy as you go along. Working in a large team and/or scrum is no excuse for checking-in poor code.
Generally what the code is doing should be fairly obvious and should not need comments. Comments should be reserved where things aren't obvious.
I don't think it is a good idea to create code where it isnt obvious what it does. CSS is relatively simple tbh things really shouldn't be complicated.
I've been building sites the way you suggest for 20 years. I also had a negative knee jerk reaction to tailwind. But I had enough of an open mind to try it and now I have no interesting in going back.
People say that. If you build stuff in components like you are supposed to you almost always have a server side component or component logic that you will have to name. So you are going to have to start naming things properly somewhere.
You are simply kicking the can down the road.
> I've been building sites the way you suggest for 20 years. I also had a negative knee jerk reaction to tailwind.
It isn't a negative kneejerk reaction. I've worked with sites where they have done similar things to tailwind and it is a nightmare to understand what is going on with the page.
> But I had enough of an open mind to try it and now I have no interesting in going back.
The markup is almost unreadable, it completely defeats the point of what CSS is supposed to do and it creates considerable mental overhead for someone who isn't familiar with it.
But I suppose I shouldn't really expect anything else from other web developers that over the last 20 odd years somehow manage to not understand the tech they are given.
And despite your crude last jibe at web developers attracted to Tailwind's model, most competent web developers will be able to quite easily pickup this very sane CSS utility framework :)
No my jibe was at web developers in general. CSS and HTML are quite simple really. If you actually keep things semantic and build your document properly with appropriate markup ... lo and behold things just work properly.
I can understand the divistush of the past when CSS 1 and 2 were quite limited. However today there is simply no excuse.
> most competent web developers will be able to quite easily pickup this very sane CSS utility framework :)
Sure I can read it. The problem is with things like this is that you are learning how to work with their model that basically doesn't work like CSS is supposed to work.
So you it essentially nullifies your existing skillset and forces you into using their framework. I bothered to actually learn CSS properly and understand the technology and then I have to work with something which basically throws that all out the window and forces me to work how they want me to build stuff. No thanks.
If you think that is a "sane" way of working, I really don't know what to say.
Sure, so you can do it once and use functional css to define the styles that go with that component right alongside the markup instead of having to maintain another css class name for that component in a separate file, mostly likely with arbitrary and inconsistent padding and margin and font-size values.
I am now a convert and although it's hard for me to articulate exactly where the magic lies, these are contributing factors:
- You can do the entire thing in HTML quickly, including media queries and pseudo-classes.
- The predefined sizes and other values are granular enough that you can do just about everything with them, but coarse enough that you often get it right in the first shot. In a sense, it's a little like going from drawing a chart on blank paper to grid paper.
- Tailwind intellisense in VSCode shows you the colors you likely need.
Each of these points are tiny and could easily be achieved in another way, but combined they have increased my personal joy in frontend development quite significantly.
Tachyons has truly taken a lot of the pain of writing web applications away for me. It looks kind of ugly in the beginning, but I can't imagine going back to writing oodles of CSS again. Haven't used Tailwind though.
I don't necessarily want to remember 30 different context-specific class names when adding a new link or button on a simple page if I know a bit of syntax I can get exactly what I want, when I want it.
Again, it's very much a project specific choice, but when you're playing and tweaking and having fun with a design (or simply, iterating on one element multiple times), it's a nice library.
That being said, I can imagine a point where once you're happy with a design, there'd be a push to refactor.
After watching a few of those I started thinking about how much faster it could be to use these utility classes instead of writing it by hand. Everywhere he adds a few quick classes I was thinking "here I'd be going back to the CSS, hunting for that class name, maybe duplicating it to create a unique variation... and it took him 7 seconds with a utility class. Hm."
Haven't gotten to try it on a project yet but it's on my list.
My take is that it's not. It's just a convenient shortcut for those who aren't well versed in CSS.
I see what kind of problem they're trying to solve, but I think it collapses under its own weight the same as complete, closed components do - just later into the project.
I'm considering open sourcing a software product I'm working on, but it could mean that I'll be bending over backwards to monetize it, as people can just run straight from source.
I used to sell GPL licensed Joomla extensions and themes.
Short answer: you can't. Long answer: You just can't.
People who're going to pirate your work aren't your customers and weren't going to pay anyway.
I rather use a free option like https://semantic-ui.com/ than pay that much. Maybe if you are company but it doesn't really work if you are a solo dev or using it for a side project.
this isn't an issue with something like bootstrap where a single class makes a button look pretty.
And you can store and access components as code snippets within your code editor (e.g. VSCode), that's how I'd store the bigger Tailwind UI components. When I need a component then I just use a shortcut and pick from a component menu.
extracting "component" as code snippets does nothing if one day your boss tells you to change all the size and colors of all the buttons. you still have to go through your entire site and make the changes manually at every instance... or have the foresight to have a class on every button that you can reference through pure css to make the change without breaking tailwind... but at that point, why would have use tailwind to begin with.
https://tailwindcss.com/course/composing-utilities-with-appl...
Does this mean, Tailwind UI is Tailwinds "answer" to that problem? Like, it's are direct Bootstrap competitor?
Why should I pay for a Tailwind hero when, if I apply myself, I can get a Bootstrap hero for free?
https://tailwindui.com/components/marketing/sections/heroes https://getbootstrap.com/docs/4.4/components/jumbotron/
You also get all the other components they add in the future, whereas Bootstrap only has its core components.
https://tailwindui.com/components/application-ui/forms/input...
the currency sign not matching the selected symbol is confusing
Like you, I was put off by how crowded the HTML looked but got used to it and found it way quicker to update and kept the css file clean.
What I'm really missing (and I don't understand it doesn't exist) is a way to compose classes into a single class, to refactor collections of small utility classes into a meaningful class with semantic sense. Why can't I do something like:
.my-class {
use .text-sm
use .text-gray
use .bold
}
Kind of like calling several functions from a single function to compose their effects.The only things that come to mind are SCSS mixins (but would have to declare the `text-gray` mixin AND the `text-gray` class, plus it doesn't with a lib like tailwind that provides classes), or CSS-in-JS trickery. Styled-component allows this sort of things, but it still doesn't feel very nice to use.
If I've missed something and this is actually possible, please somebody tell me!
https://tailwindcss.com/docs/extracting-components#extractin...
.btn {
@apply bg-blue-500 text-white py-2 px-4 rounded;
} .my-class {
@apply text-sm;
@apply text-gray;
@apply font-bold;
}But ideally, instead of extracting that specific collection of classes out to a class, extract out the HTML fragment into it's own template (or into it's own React Component or insert framework component abstraction here).
The cleaner separation now is:
1. classes represent some atomic unit that enforces (for that unit) some design system specification
2. html fragments represent a specific implementation composed of those atomic units
I currently use https://materializecss.com/ over several products. It's been great, but I'm stuck on the 0.100.x line because the upgrade path was too difficult. It's also hasn't been updated since the first 1.0 release some time ago. Not complaining since I got what I paid for (it was free) but it's left me pretty anxious to find a replacement.
Salesforce's Lightning components are good but challenging to understand how to work with outside the walled garden. Zurb's Foundation UI is interesting but seems to want me to use whole page templates rather than components.
This looks like exactly what I've been dreaming of. I've put my money where my mouth is as I can't wait to have more components built out to a stage where I can start using it for real.
1. Components are sort of antithetical to the Tailwind CSS ethos of atomic styling. Of course, examples of markup and class arrangements are certainly helpful, but at the end of the day you are still always going to have a unique markup in the end. And according to their license, those customized components are now under their Tailwind UI license.
2. What counts as a component? What if Tailwind UI produces a licensed component that is a single div with a single border class? Could it be that someone with no prior knowledge or access to this component have accidentally already created the same markup elsewhere? Would that be an infringement?
Frankly, I really enjoy using Tailwind CSS, but I'm a little nervous now to even use the original project in my work.
[2] Sample App: https://github.com/SAP-samples/openui5-sample-app
[3] Slider in the component library: https://openui5.hana.ondemand.com/entity/sap.m.Slider/sample...
2. is huge (libs)
3. was made by SAP for custom HANA apps with "normalized" widgets and skins, originally known as SAP UI5
4. MVC, Single-App, two-way data-binding, tutorials are hard to grasp, conventions that may not lend itself to front-end devs mindset.
5. naming convention is a mixed of Java and C++ (hungarian notation) instead of JavaScript
Source: used SAP UI5 in the past. Nobody likes it.
Comparing it to Bootstrap or Foundation adding the class `alert alert-danger` to a div tells my coworkers that it's an "alert" & it will look like an alert everywhere. If I want to change how alerts look, I change the CSS
With Tailwind you'd have `bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative`. Then I'd have to change my HTML everywhere to update the appearance of alerts & its not always obvious that I'm looking at an "alert" in code. I'd end up with different looking alerts, cards, buttons, etc all over my app
But for buttons & heros not so much. I've worked with apps that have a "button" template. I find it overkill.
For one project we have some components rendered both server-side & with Vue.
Other cases I've had are sharing styles across multiple apps and pulling in markup from a 3rd party, like Stripe or a WYSIWYG.
But you're right. Ideally this wouldn't be an issue w/ view templates.
Reasons:
- Its constrains and whitespaces are well made, if kept untouched, the result may be good, even if build by dev with no design skills.
- Elements are containing what's necessary, but no more. No unnecessary tooltips etc.
- All elements have clear basic states (see https://tailwindui.com/components/application-ui/forms/input...)
My biggest request would be, making the naming conventions match more closely to CSS property names and Bootstrap 4 names. Once a developer learned the system, if they knew CSS property names they could automatically guess the Tailwind class without looking at the docs. Matching Boostrap 4 whenever its convention, would make it that much easier to convert BS4 sites to Tailwind (and easier to adopt for BS devs). My 2 cents.
Excited for UI. Keep it comin!
I like how they didn't limit too much what can you do with components in license, which is really good.
I generally am OK with this and want to see if I want to get just appUI or both sets. I think Adam should've joined them together and maybe given us some deal on pricing as early adopters. But, he is great guy, and this is excellent way to support him and project.
For example - http://landrick.react.themesbrand.com/ is 17$.
https://g-axon.com/wieldy-ant-design-react-redux-admin-templ... is 24$ (which uses ant design)
I bought this the moment I got the email about it this morning because this is going to help my productivity in building web applications. When you use Tailwind, you aren't using a pre-made theme as you would with a bootstrap theme you buy, you are designing it from scratch.
With this UI kit you'll get some nice building blocks to become even more productive, but you'll still end up modifying stuff to make it yours.
I honestly think this is priced too high.
Not only that, but I think the pricing model is wrong; lifetime access for a one-time fee is a big mistake (and one I previously made with a startup).
As a developer, I understand that you need a predictable, repeatable income stream to keep going - and if I'm going to invest in something like this, I want it to keep going. I'd far prefer to pay something like $49/y instead of a one-time $249 fee.
Really doesn't work with react.
react + styled components is god mode. This is a step down (aside from the design).
At the end of the day, CSS isn't that hard anymore.
Design it in figma. Put it into zeplin. Copy paste the styles into a styled-component. You're done.
tailwind is only a step up if you're a russian php developer who has been using bootstrap for the last 10 years.
Right now it's not possible to tell what would happen when any of these components were resized since it's just a static image as a preview but responsiveness is one of the most important things to see.
It seems they've only done it for the ones they are ok with making freely available.
But that still leaves a vast majority of the components (almost all of them) as static images at 1 specific screen size.
They should consider adding screenshots of each size, or a few second gif / video showing how it looks at various breakpoints. Otherwise potential buyers (like myself) have no idea what things look like at each size. I don't mind a premium price but I'm not going to blindly buy it without knowing what the components look like beforehand. What it looks like is the most important thing for a CSS theme.
I do think they have a fourteen day free trial, though.
Tailwind related playlists on Adam Wathan's YouTube: https://www.youtube.com/channel/UCy1H38XrN7hi7wHSClfXPqQ/pla...
And this publication (by same authors as Tailwind UI, that is Adam and Steve) https://refactoringui.com/book/
Enjoy!
I would like to see a React component version of this, ready to use with a CMS like https://webiny.com
By adding a simple utility, your css gets very short very quickly.
(Disclaimer: I'm a backend dev and I don't know CSS well)
The HTML-CSS "separation" question will never have a "right" answer...
Is there anything similar to Tailwind that doesn't require any build process?
Your question is intriguing to me because I come from web development long before the Bootstrap was available. Teams I worked on would frequently take custom designs and turn them into clickable HTML templates with all UI components before spending a lot of time with the site itself. Bootstrap took this a lot further, but also enables the early parts of design to be skipped. You then have your issue with the site looking like a Bootstrap site.
My personal opinion is that Tailwind along with this new offering enables a better way out of that situation. Bootstrap is still known to more people and has less of a learning curve which are important points for some.
UIKIT is super light weight and modular. I've developed extremely high converting landing pages with almost no JS at all using only components I needed. Can the same be done with Tailwind? And if yes, then what exactly is the appeal? Simply the difference in number of components?
I love the look and feel of Tailwind, but it just looks like another UI framework to me and I don't understand all the raving reviews here. If it's something obvious I'm missing, very happy to learn it and pick it up.
Thank you.
How about compatibility with React?
Or is this the land of "bare metal" HTML+JS+CSS?
But you can't use it directly with Webflow. I don't know about Weebly.
Best to set it in stone (by bringing it onto your own website) before you start selling.
It comes down to a css library being a utility that defines clean patterns for extension.
[1] https://tailwindui.com/components/application-ui/tables/wide