Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Building React and Vue Support for Tailwind UI (tailwindcss.com)
286 points by shayac2 on April 12, 2021 | hide | past | favorite | 117 comments


> We crawl this document as an AST, and actually transform it into four formats...The key to getting sensible output is really just having total control of the input format. It's still hard work, but when you can encode the intent of each example into a custom input format, converting that to another format turns out so much better than trying to write something that can convert arbitrary jQuery to React or something.

One tends to think of parsing/compiling as a fairly esoteric skillset that a relatively small number of programmers ever actually need at their jobs, but it always makes me glad to see examples like this where a little DSL was a genuine boon to productivity in a real product. Once you know how to do it, you start to notice more and more little opportunities where it could be useful.


So true. The thing that put me on the path of discovering parsers was a tweet that said something to the effect of “if you want any relatively complex regex, what you actually need is a recursive descent parser”.

Now as a self thought dev I haven’t really been shown in school what those were and always thought of them as some wizardly magic that only compiler writers dabble in.

But after that tweet I looked around and discovered https://github.com/dmaevsky/rd-parse which is a 100-ish line library, and using it you can do https://github.com/dmaevsky/rd-parse-jsexpr/blob/master/src/... which is a 200-ish lib that parses all of freakin JS expression syntax.

Now whenever we have various custom unwieldy regexes to parse some input, I can refactor that into a clean and easily understandable parser.

I guess thats why you need at least a little bit of formal education in CS.


I once worked on a product where the idea was the end user would write a lot of custom regexes to parse the output of commands on network devices. The system was written in such a way that the regexes were nested and looped depending on the depth of the output. The overall result is you could read and update config on a device based on what output of these regexes.

It seemed bizarre to me that it was considered an appropriate solution. The end users were network engineers so they were _able_ to write the regexes but it seemed obvious to me that providing the user with a higher level parsing library would be much easier. It was something I wanted to POC but never found time in the end.


I have a CS degree but we just never really covered parsing or compiling at all, for whatever reason (well... technically we talked about the formal theory behind grammars a little bit but we never did anything with it, and it hasn't really been useful at all)

But I always dreamed of making a programming language so one of my pandemic projects was to read Crafting Interpreters, and ever since then I've been a little bit obsessed

That's a great point about regexes! I'll have to keep that one in mind


That's a great comment. I might use it in the field.


You always have to check yourself and make sure it'll genuinely be helpful, because it's so tempting to do :)

But that said, I had a good usecase of my own a couple months ago where a little s-expression-based DSL was just the ticket to open up some data analysis functionality to internal users without having to prematurely build out a super complex, much more rigid GUI. DSLs are really just small, hyper-flexible user interfaces. Once you frame it that way, there are many applications. (The drawback of course is discoverability/feedback, which GUIs excel at, so you have to balance the two for your usecase)


One tends to think of parsing/compiling as a fairly esoteric skillset that a relatively small number of programmers

Parsing is the easy/not so interesting part of a compiler.


Someone on here made the comment a little while ago that while that is true for compiler makers, parsing is the much more useful skill for the average programmer. It allows you to approach a new realm of problems that are otherwise off limits.

So while looking back it may seem like a gentle incline, to a lot of us looking forward it is a steep cliff.


Tailwind and Tailwind UI are really great. Tailwind UI as a series of blueprints is exactly what I'm looking for and I love how often they're updating and adding new blueprints to their list of components.

This part from the blog post kind of confused me a bit, though.

"The promise of Tailwind UI is that it's just a code snippet"

Am I the only one who never looks at the code snippets/tab for Tailwind UI, and instead jumps straight into inspect element? As blueprints the components are great, but I almost always want to make some small tweaks or changes to fit my application. Are there other people out there actually copying/pasting the snippets as they are?


I almost always copy + paste them, but then start tweaking them in my app. It's easier to just start fresh then change after in my app than trying to do things in the console.


I’m not sure I get the difference between looking at the source vs inspecting it? In any case, they’re not expecting you to outright copy them (though you can if you want), they’re saying that the code snippet has everything you need just by copying it.


I guess for me I have trouble visualizing all of the elements and classes just by looking at the code snippets. Looking at them in the DOM allows me to see them in context, and I find to be easier to use than looking at the underlying code snippet.


Agreed. One reason I find is that I generally use the componentized examples and when put together they lack consistency. Maybe if you lean toward the full page examples it could be used "as is".


I’m the same way, but that’s because I don’t use Tailwind (the CSS library) and have no plans to use it. I just like the clean design work and some useful CSS techniques and tricks in Tailwind UI!


This is so ugly and error prone:

<Button className="bg-gray-100 rounded-full flex" ...

How do you remember the names of all your classes? Should your IDE know about these classes? Can you autocomplete class names? Where's the import statement for these classes so you know where they're defined and what they do. There's a better way:

Use site-wide themes (Objects with keys like colors.heading.primary having value '#000') and withStyles[1] and React.PureComponent[2]. Having your React component render the same result given the same props and state makes things so much easier to work with. Also, the compiler knows about your theme so your IDE helps auto-complete and makes sure the style you're using is actually defined.

[1] https://github.com/airbnb/react-with-styles

[2] https://reactjs.org/docs/react-api.html#reactpurecomponent


> Should your IDE know about these classes? > Can you autocomplete class names?

Yes! (https://marketplace.visualstudio.com/items?itemName=bradlc.v...)

Although I wouldn't mind an array instead so I can use the typescript typechecker.


You get type checking automatically using withStyles, no plugin needed. That plugin is kinda cool with the css preview feature, but I bet using the built-in IDE autocomplete is more reliable. I also find withStyles more readable in general, for ex:

theme: {

  button: {

    primary: {

      color: 'blue',

      padding: '2px',

    },

  },
}

<Button {...css(theme.button.primary)}>

vs. tailwind classes:

<Button className="text-blue p-2">


You don't need to remember all the classes. Instead, you can go to https://tailwindcss.com/docs and search for whatever you're looking for.

Having IDE autocompletion (or even TypeScript integration) would be really nice. I'm sure there's plugins for many IDEs or editors that can do that, though.


As a tailwind user, looking them up every time, especially when you a already know the CSS, isn’t that great an experience either.


> Having IDE autocompletion would be really nice. I'm sure there's plugins that can do that.

Use withStyles [1] and vscode autocompletes without needing a plugin.

[1] https://github.com/airbnb/react-with-styles


VS Code and IntelliJ plugins provide just that, and the VS Code plugin goes further by showing the CSS it will expand to and show a color preview next to the class name.


So does the IntelliJ one, with a hover I think


Love this. And anything else that uses design systems rather than styling individual elements.

I currently have a tailwind project that's around twelve months old. I'd like to add a dark theme.

Normally - in a CSS, SCSS, PostCSS project - this would consist of adding a media query overriding a handful of color variables.

Using tailwind (which has 'inbuilt dark mode support') I have a few thousand colors spread around the project and I have to modify them all. Additionally by having a giant palette of named colors, we have, for example, multiple occurrences of our active color as `blue-400` and `blue-500` and `blue-600` rather than a single `var(--active-color)`.


Tailwind out of the box is a simple, canned design system. The Tailwind authors have already decided your color palette, spacings, animations, etc. This is perfectly fine for prototypes or anything that isn't that important. But if you want to have more ownership over the design system, it's better to use Tailwind's config and set it up as it makes sense for your site. Colors are the most obvious candidates, with Tailwind you can setup your own colors and from there do `bg-active` or whatever else makes sense for your site. You can define whatever is important for your site, and fall back to the inbuilt system for the things that aren't.


That’s definitely true. I just wish tailwind encouraged consistent styling (by having a design guide and variables) rather than styling individual elements in their documentation, which means someone has to clean up the mess later.


In practice I find UI built with Tailwind to be a lot more consistent because all the dimensions are built from standard values instead of custom dimensions for every css class. The bigger problem in my experience is that most designers are too lazy to set up a type and color scheme up front and just drag whatever looks good to them in their sketch/figma files.


You mention the issue being solved is having standard dimensions.

We’ve been doing this in CSS for quite some time using variables. This didn’t require adding a fairly leaky and thin abstraction on top of CSS and adding thousands of copy pasted singleton styles to our projects.


I have a few hundred tailwind classes left in my projects after a purge css pass. If you have thousands you probably should start looking into extracting some components. If you literally have "a few thousand" colors in your UI you need to find a new designer.

And CSS variables are great but way more verbose and still require you to come up with "semantic" names for everything.


> If you have thousands you probably should start looking into extracting some components.

This is confusing component reuse with design system reuse.

Two components may have completely different purposes, but they both have a certain rounding, palette, and other styles.


@apply is your friend here.


100% agreed that sharing styles with @apply is exactly how to solve this.

However Tailwind tells users they shouldn't be doing this, encouraging them to paste the same mixins on every element they want them.


They specifically recommended using it in the documentation to solve exactly the problem you describe.



You’re missing the point. I’ve already enabled dark mode in the config file. But tailwind’s approach of styling elements individually means I have to clean up a few thousand lines of styling first.


Yep, design systems (your own component library) are the way to go with React. Auto-complete, type checking support, functional, etc. You do style the component once, but after that it's self-contained, reusable, and functional.

Everyone stopped using unstructured cryptic class="bg-gray-100" for good reason. Tailwind is backwards progress.


https://wptavern.com/state-of-css-2020-survey-results-tailwi...

Clearly, not "everyone" stopped doing that.


Not the OP but I suspect 'everyone' was hyperbole, and they actually meant 'professional frontend designers and engineers'.

Tailwind being popular doesn't really contradict their point.


see https://www.youtube.com/watch?v=MAtaT8BZEAo where they discuss how to do what you want. There probably could be better standard advice on how to make your setup a bit more future proof out of the box.


That video specifies to undo all the manual styling which tailwind encourages and that’s exactly what I’m doing.

The point is undoing single element styling would never would have been necessary if tailwind didn’t encourage styling single elements (saying that “best practices aren’t”) in the first place.

The author literally even mentions we should use “symantic descriptive names”. You know, like those best practices that tailwind says don’t work.


he is one of the tailwind guys, I don't think there advice is one size fits all, there are different scenarios where you want different things. The point they basically make is to make a design system using generated a utility first approach. Nearly everywhere in the their tutorials etc they encourage customization to your specific needs.


I know he’s one of the tailwind guys. That’s why I’m pointing out the inconsistency of a video stating semantic class names are needed for consistency, while having a website that strongly suggests otherwise.


Not really sure what you are referring to, they always seemed to be open ended, and their docs https://tailwindcss.com/docs/customizing-colors#naming-your-... seem to represent this. The main point is you need to customize your design system and tailwind provides a toolbox for doing that.


I'm with you here.

Tailwind is easy to start but hard to maintain and extend.

Its good for a prototype or small landing page.

I would never use it for long term project where you need to maintain and extend your features a lot.


> How do you remember the names of all your classes?

You don't.

https://tailwindcss.com/docs/extracting-components


So, the dev never reads/modifies the extracted component that still uses hard-to-read hard-to-typecheck classes? Doesn't seem like a good solution.


It’s a great solution. Every class only maps to one css property setting, and they are very well named.

Thus not much more difficult to read and remember than css key value pairs.

Why would you typecheck component class names? If so, its all strings, seems pretty easy less error prone than inline styles.


Actually each class does NOT always map to a single property. In what I consider to be its greatest strength each class is actually designed to do some very specific thing that can actually require multiple CSS properties and settings. For eg the breakpoint classes are fairly complex but allow you incredible flexibility in building responsive UIs


This is great work, congrats on shipping a great product. I use TailwindCSS on my personal website.

I often wonder whether we need yet another UI framework implementation? I touched on this in my post a couple days ago: https://williamhoyle.ca/blog/2021/vue-has-too-many-ui-framew...

To summarize:

We have 20+ UI frameworks written in Vue. Surely there's enough common ground/code to combine the implementation details for all these common components. For example, OP mentioned the complexities of implementing a modal with some corner cases for 'ESC' behaviour. This is a universal concept whether you're using WidgetUI or TailwindUI. How many times are we going to re-implement a modal/button/dialog/menu?

We have to learn another set of APIs, props, component names, etc... Of course, no one is forcing us to use this. But it seems like we're going in circles re-implementing the same UI patterns over and over again.

I wish we could standardize on a library. Imagine just pulling in GenericUI and sprinkling in your CSS of choice (e.g. tailwindCSS, Bulma, Material, etc...).

I'm a Vue guy, but I think my argument still stands for the React ecosystem.


> I often wonder whether we need yet another UI framework implementation?

Because the web wasn’t designed for applications UI interfaces (hence the CSS grid which landed only in 2017), so it lacks basic primitives and behaviors that are then re-implemented slightly differently by different people. On the contrary, a UI framework designed for this such as the Windows Forms on Windows desktop is still very usable (and used) to make applications, 20 years after its release; and is only concurrenced by a single newer framework (WPF) which actually brings a lot of improvements on the table.

Actually the web does it half-way: there are a set of common elements (input text, button, etc.) but some useful components are missing, and some of the existing one are hard to style. This support should be added in browsers, then custom code wouldn’t be needed anymore.


There is an ongoing effort at https://open-ui.org/ to add these basic primatives. I'm throwing my effort behind the <select> replacement and we welcome input from everyone.

If I can avoid writing another autocomplete and solving the Esc corner cases, the effort will have been worthwhile...


Thanks for bringing this up. I didn't know about open-ui. I think something like this is becoming more and more necessary.


I think a big part of the problem is that probably 12x of those have to re-implement because they want to change something unrelated like styling, or want to add more components, but can't extend existing libs without using the same styling, so they end up re-doing everything.

So we end up with 20x libs all doing roughly the same thing, sometimes badly.

This one doesn't seem like the typical Munroe +1, because it's not trying to rule them all, just put a visually unopinionated base in place with the tricky, boring stuff handled. It kinda feels like other libs are doing too much in any case.


> Imagine just pulling in GenericUI and sprinkling in your CSS of choice

That's exactly what the tailwind people built in Headless UI: "a library of JS components that abstract away all of the keyboard navigation and accessibility logic without including any design opinions"


I guess what I'm arguing is that we already have so many Headless UIs out there. Another comment pointed out PrimeVue, which does exactly what Headless UI does. This feels like another library reinventing the wheel.

I'm always reminded of https://xkcd.com/927/ when another UI framework pops up. Do all libraries do things just differently enough to warrant a completely new library or can the implementation details be abstracted to some core lib (maybe even a web spec).

On the other hand, maybe I'm wrong and HeadlessUI ends up being that GenericUI lib.


Agreed! I believe the path of popper.js should be of inspiration to a lot of people! Clean separation of concern, high focus, resulting in high quality and high reusability!


I just learned about it for the first time in this post, but it sounds like that's what they're trying to do with Headless UI?


It would be great to see AlpineJS as a first class option here, especially since it's already there in the source for the examples.


What an effing great article. Not only for the clarity and care behind the writing, but also for useful links like [0].

Adam's (author) podcast Full Stack Radio is useful like this too [1].

[0] https://www.w3.org/TR/wai-aria-practices/examples/menu-butto...

[1] https://fullstackradio.com/


Indexing your references from zero. Cool, haven't seen that before :D


Or just use something like Chakra UI, which is like Tailwind CSS but based on styled system and built with Typescript for React from the beginning and has a nice set of basic components.

I even built something like Tailwind UI but for Chakra (link is in my bio if you want to check it out)


And then you have JSS, no restrictions to the available design tokens, no postcss plugin support and your "css bundle" increases since you don't reuse tokens but styles are generated.

Those things alone are reason for never using Chakra for anything serious as these are actual reasons your product/saas/whatever is at a higher risk of failing.

And that's just apart from the fact that the components are not allowing easy overriding, theming is a mess (especially if you want Typescript support again for your custom variants) and it's sometimes buggy with the way DOM events are handled (the checkbox being the biggest offender). At some point the frontend also randomly crashed for me because of the Popover component and it's usage of Popper.js


Chakra-ui uses Styled-system and Emotion. All your points are against those 2 projects, not Chakra directly. Chakra turns Tailwind into a Styled-system theme that can be adapted and changed.

>> Those things alone are reason for never using Chakra for anything serious as these are actual reasons your product/saas/whatever is at a higher risk of failing.

Emotion and other CSS-in-JS libraries are used extensively and don't raise a risk of the project failing.

>> And that's just apart from the fact that the components are not allowing easy overriding

You can use Styled-system to create and extend the existing theme. This is actually a knock against using Tailwind CSS directly since you will need to write custom CSS to override the theme. I've even seen projects where Tailwind is used with Emotion to extend the existing theme.

>> At some point the frontend also randomly crashed for me because of the Popover component and it's usage of Popper.js

I use Chakra (and the Menu component that uses Popper) on my landing page and SaaS and have never had any issues. If your code is open, I can help you debug this.


Check out SnackUI, which solves most of this with typed components.


“If we catered to React developers, we'd be making it harder to use for the 70% of people not using React.”

Third paragraph of the article


Chakra UI is available for Vue as well: https://vue.chakra-ui.com


As someone living in ClojureScript land, I’m really happy that someone is giving me a decomposed/decomplected option for these things.

Headless UI is some of the nicest React components I’ve worked with via interop, and to me it’s really valuable that they don’t come with an opinionated way of styling them.


I think you missed the point as an opportunity to pitch your project.


Not really. I like TailwindCSS, I used it in several smaller projects before. But then I found about Styled System and later ChakraUI and never looked back. I really think ChakraUI is TailwindCSS on steroids for React and recommend everybody who is working with React to at least check it out.


That would negate some of the reasons for using Tailwind in the first place, like the flexibility to make a design be specific to your use case despite the guard rails of the basic constraints (Styled System provides this on its own) combined with very simple tooling with no runtime overhead.


Super interesting to read this. Especially how you eventually bridged HTML to React/Vue. Thanks for sharing!

One year ago I had to do something similar and used Web Components (https://www.robinwieruch.de/react-web-components). Did you consider using Web Components or a Web Components library such as lit-html in the first place?


Well this completely deprecates my personal react/tailwindui library starting on tax day. I guess that’s good!


Same here :)


I'm currently using Tailwind CSS to style a fairly simple static website that's being generated using Hugo. I've been considering using some Tailwind UI components, e.g. modals (in particular, lightboxes to show zoomed-in versions of images).

I assumed that I would use Tailwind UI's HTML for these and write vanilla JS for interactivity, but now I am rethinking, especially having read this quote in the article: "If we tried to write it in custom vanilla JS, well we'd be making it harder for literally everyone".

So given this announcement, in my situation would you recommend against vanilla JS, and instead to adopt one of React or Vue?


Look in to alpine.js - pairs very nicely with Tailwind


Thanks - Alpine.js looks like an appropriate choice in general, but unfortunately it’s not supported by these particular components. However, the announcement does say “we're looking forward to exploring other frameworks in the future (Alpine.js is next on our list)”.

I’d be interested to know whether Alpine.js support is “coming soon” or “maybe eventually”.


They're already generating hacky alpine to power their interactive examples, so I'd guess soonish.


Ah I'm not a huge fan of this:

    <Menu.Items className="absolute mt-1 right-0">
I'd prefer it to be like this:

    <Menu.Items absolute mt-1 right-0>
I did some experimenting (I'm the owner of `react-tailwind`, please reach out if you want it!) and it's definitely possible to do that; but it does imply components are purely visual, which I'm not sure it's the way they want to go. It's also not possible to use the colon like `md:...`, but you can do `md="..."` instead, which is a good approximation IMHO


Blurring the line between attributes/react props and CSS classes seems abhorrent to me, but just my two cents


I've found a lot of success abusing a styled-system Box (+ Flex/Grid) component. It's like a more mature, flexible tailwind that allows complex integrations and much more dynamic styling, not to mention extremely simple media query adjustments.

I know it's not the right system for everyone, but it's the best styling/layout framework I've ever used. You can have it span as much functionality or as little as you want. In my experience sticking to largely layout based styles is the right move, while occasionally mixing in some slight design-based styling as needed.

    <Box
      px={4} // padding left & right
      width={['95%', '80%', 320]} // correlates to my media query grid
    >
      <Card ... />
    </Box>
or

    <Flex gap={4} flexDirection="column">
      <Card ... />
      <Card ... />
    </Flex>
or

    <Grid
      gridTemplateColumns="1fr 1fr 320px"
      gridGap={4}
    >
      <Card ... />
      <Card ... />
      <Sidebar ... />
    </Flex>
I can put together nearly any layout I want without ever touching styled-components, raw css/sass, or augmented classNames (ew?). If I need to do something complex, falling back to a normal styled-component is trivial enough. Plus every layout is in your face and immediately visible; no paging and scrolling around files to figure out what this class or custom styled-component does.

The only downside is that if you don't organize your layouts effectively and break up your react components, you can end up with Box overloads or abuse, but ultimately its up to the developer or team member to figure out that balance. It hasn't been too much a problem for me.


I also like styled-system a lot. It's too sad that it was essentially abandoned. Theme-UI seems like a replacement that most people are moving to, but I doubt that it will be maintained for years to come either.


Sure in this "extreme" I'll agree, it was just an experiment after all (I do think both the short-hand classes and attributes look wrong). Do you think the same about either of these?

    <Button color="red">Hello</Button>
    <Button red>Hello</Button>


What does red apply to? The button color? The text color? Both (sounds useless)?

If you told me a button were red, I would assume the button is red and any decoration on it (e.g. text) isn't. Not sure if that's what happens here.


I dislike both of these :). Just leave the styling layer to itself.


With props you get auto complete which is fantastic for this type of styling work. I’m constantly going to the tailwind website to remember their “DSL” of class names. Autocomplete would dramatically help here.


I know it's not actually a great solution but personally I've had no problems with remebering their DSL because I use the official Tailwind extension for VSCode which also uses your config file to give you autocompletion


I feel the exact same way


A big issue I see with this is that having custom classes (the whole extensibility point), at least in TypeScript (without re-declaring them).


I investigated figuring this part out. Theoretically you could build a postcss plugin that generates the proper typescript types. It would be difficult.


If typescript is an issue don't use it ;)


Giving up the myriad benefits of type-safe code over this relatively minor and entirely subjective coding style preference will be a poor engineering decision.


i’d prefer `<Menu.Items absolute mt={1} right={0}>`


Could someone clarify why / when would it make sense to use Tailwind UI with upcoming Vue support versus just using one of also very popular Vue component libraries, such as PrimeVue or Quasar?


I thought I’d be getting a couple of examples of nicely designed components, but this an excellent example of getting my money’s worth and more.


Tailwind is the weirdest thing I've ever ran across. It's basically inline CSS.

Personally, I write CSS this way:

1. Select based on cascaded semantic HTML elements; 2. Don't repeat yourself; 3. No unnecessary classnames; 4. No style-descriptions in classnames.

Only when you have troubles selecting an element based on its position in your DOM you should choose a classname. It should not be ".text-gray-500" (like Tailwind does) but it should be "p.author-role".

In my case the classname is semantically descriptive whereas Tailwind is not. In my case you just need to update the CSS and in the case of Tailwind you need to change your HTML and then probably also create a new CSS class.

But still, ideally, you'd simply select it like this:

The author name:

    figure.author figcaption h5 { ... }
The author role:

    figure.author figcaption h6 { ... }
And even the .author selector would be optional, depending on whether that figure elements needs custom styling that is exclusive to the author or not.


This comes up almost every time, but it's not "basically inline CSS". The best thing about Tailwind (and utility classes in general) is that it forces you to use consistent measurements across your app.

"Shoot, was this 13px padding or 14px padding on the other page?" Don't worry about it, just use "p-4, p-6, etc.". Thinking in these terms becomes really powerful.

Another great thing as that you just simply don't have to think about what to name things! I find that so liberating, to be honest, and I don't have to keep switching back and forth between my markup and my css. I don't have to worry about coming up with semantically descriptive names. I just use "text-gray-500". Was this .authorrole? Or was it .authoremail? Hmm, now I want to display an author nickname. Do I just repeat "authorname" class? I find it so freeing to basically not have to worry about this stuff at all.


Who uses 13px for anything? I literally don't get this. Just remember to use a multiple of 4px? Or 0.25rem? Or whatever your designer is desinging to? This is solved with a 5 second conversation at the start of a project. Why the fuck do you need a library?

Legitimate question. How do you remember not to use "p-4.25" without npm installing tailwind-default-constraints or whatever the fuck?


> How do you remember not to use "p-4.25" without npm installing tailwind-default-constraints or whatever the fuck

Because "p-4.25" isn't an available class.

The whole point is that you have a fixed list of sensible options. You can extend it and customise it, but out of the box your design system is sensible and predictable. "p-8" is double "p-4"; "p-6" is half way between. It's like an enum case vs just using a raw integer.

Sure you can replicate it by creating some Sass variables and sticking to them but then you're on your way to re-implementing a utility-first framework.


"Shoot, was this p-4 or p-6 on the other page?"


Checkmate!


so thinking of names like ‘author-nickname’ is difficult but learning an entire new syntax for css is easy?


Yes, "learning" the tailwind syntax was really quite easy.

In addition, most editors and IDE's now have plugins for autocompletion

And as an incentive to learning – once you're familiar with Tailwind's syntax, you get to use that learning on all your future Tailwind projects.


As a tailwind user I find it a hassle. There's quote of lot of CSS values, and having to remember small things like...

- 'grid-auto-flow: row' is 'grid-flow-row'

- 'grid-auto-flow: column' is not 'grid-flow-column' but rather 'grid-flow-col'

...is annoying.


There's a better way to get consistent measurements without having to remember class names:

Use withStyles[1] and have a spacings namespace in your theme. Use the spacing in your component like spacing.button, which applies an Object containing the correct CSS padding, or spacing.padding.medium for the raw number.

[1] https://github.com/airbnb/react-with-styles


If you see it as just inline CSS, then tailwind can be avoided for all the same reasons that we avoid writing inline CSS. It’s considerably more than inline CSS imo but that’s a different story.

That said, I’m surprised by this:

“Only when you have troubles selecting an element based on its position in your DOM you should choose a classname”

Certainly if you have knowledge of the exact DOM structure in advance, and high confidence that it will never be substantially changed, this is workable. But in many cases, having the CSS care about the DOM structure produces way more pain than the ergonomics of tailwind do. At least in the kind of code I’ve worked on where components are reused all over the place and sometimes rearranged by authors directly in a CMS. Or just having DOM reorganized because something is added that requires an extra wrapper & then all the CSS selectors are nested wrong. Or whatever.

Anyhoo. I don’t love tailwind, but I think it’s fine. Far worse things have happened to web dev. It seems like you have a problem with utility CSS, which tailwind takes to the extreme for sure.

Also, side note - having headings in a figcaption like that seems semantically incorrect.


> having headings in a figcaption like that seems semantically incorrect.

I genuinely wonder what the payoff is for semantic correctness.

Web browsers don't care, screen readers aren't nearly as particular as they used to be, and the web certainly isn't returning to some XML/XSLT universal document ideal.


A screenreader user cares if they are navigating between headings and the headings are not actually headings - and it’s always _better_ if the nature and structure of the content is expressed in the HTML so that the screened can announce things correctly. Keyboard users also care a lot about semantic HTML because they are so so many interfaces out there that are not keyboard navigable as divs are used for everything including buttons. So they just can’t reach parts of the interface, or even perceive them.

It’s not about a pristine ideal. Though I’d argue semantic HTML is not only the foundation of good accessibility, it also makes for more readable code because the intention behind the elements is exposed to the next person reading it. It nudges you to do better work because you actually have to understand the nature of what you are building, which means you might see how it reflects an existing pattern that can be copied, not duct tape together a half working tab interface with JS event listeners on divs and spans.


Tailwind is not "basically" inline styles.

Tailwind and other functional frameworks use classes for abstraction, which unlocks media queries, pseudo selectors, and many other CSS features.

Plus Tailwind's build system generates styles according to your config, which is sort of what distinguishes it from other functional frameworks.

"Semantically" descriptive could mean any number of things. In this case, it seems to mean: name your class according to what it's supposed to do, which is nice in theory, except that it hides the relationship between the markup and CSS. A well-prepared stylesheet is nice, except when the markup doesn't match what it expects.

In Tailwind, the class names themselves are "semantically" descriptive because they do exactly what they are supposed to do. There are no hidden abstractions.


> It's basically inline CSS.

It's not, because there's a system to it. With Tailwind you pick specific values. Inline styles let you specify any value.

> It should not be ".text-gray-500" (like Tailwind does)

This is fair. I'd never considered that specifying the actual color in the class name would be problematic, but another thread pointed out that it makes theming (such as dark mode) difficult.

> 1. Select based on cascaded semantic HTML elements; 2. Don't repeat yourself; 3. No unnecessary classnames; 4. No style-descriptions in classnames.

I'm sure this works great when there are a small number of people working on styles. When there are many, however, I've found that the cascade often results in styles overriding one another, and needing to introduce more specificity to fight it, in an endless cycle.

Obviously people should write better CSS to avoid that. Which is actually what Tailwind is, I think.


> It's not, because there's a system to it.

I think what bothers people isn't _what_ it is but _where_ it is. I for one, don't want long sausages in my HTML elements, regardless of whether they are classes or CSS styles.


Pretty much every CSS framework under the sun relies on a pile of classnames for each element? Even the most mimimal frameworks from 10 years ago worked this way...


Bootstrap and the like don’t have one property per class name as Tailwind does.


The bootstrap comparison is awful as they both do COMPLETELY different things


I agree Bootstrap and Tailwind are very different, that’s what I was pointing out. Your problem is with tomc1985, not me.


The semantically descriptive unit for most Tailwind users is the React/Vue/Angular component. For vanilla web development it definitely makes less sense, especially since it has a "compile" step.


Honestly, the only two things missing in Tailwind for me are:

1. @apply as a JS function that I can use in CSS in JS.

2. Some way to override existing Tailwind classes with new ones (ex: Generic Button => Specialized Button => Unique Button).


Not sure if this would work for you for 1, but I love using Tailwind with https://github.com/ben-rogerson/twin.macro


I'm using Tailwind right now on a Phoenix Live View project and I am happy to report the two work quite well together.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: