Hacker News new | ask | show | jobs
by JLehtinen 857 days ago
Being a designer who does his work inside code, Tailwind is a nightmare. I hand off my design files, the developers do their thing. But then, maybe I want to tweak things after a review, or the design system changes, so I have to do a sweeping change to those buttons. Now I need to touch dozens of jsx/tsx files around the platform and make humongous pull requests, and the result is often dozens of merge conflicts. If I only touched CSS/SASS files, there might not even always be a need to have the files reviewed.

Another problem is readability. When things aren’t getting named, the files are often unreadable at first glance. And that’s what they are to external services like Pendo, which rely on classes to tie their thing into the UI. Which are now susceptible to change on a very regular basis, because when you change Tailwind styles “that only changes that particular instance”, or so the story goes.

3 comments

I second this, as a designer. Maintaining atomic tokens in plain css as custom properties is much more ergonomic than having utility classes.
> ...I have to do a sweeping change to those buttons.

Why aren't those buttons encapsulated in reusable components or templates?

What sorts of changes do you need to make where this is an issue?

They are (encapsulated in reusable components). But when the project grows big, Tailwind's shortcomings become apparent, the biggest ones being the loss of context (cascading) – and of course the lack of separation of concerns, when the concerned parties are also separate (developers and designers).

When building a design system, there are a bunch of default styles, and then there are variations based on context. To put it in a real world example, imagine a newspaper heading style that varies depending on where the heading appears. Front page headings are bigger, sports pages might use a different style, and so on. Same with buttons, cards, tabs, what have you.

This isn't impossible to build with Tailwind by adding, say, react logic, but it becomes a mess quickly. If you have a well-built design system, class naming shouldn't be that hard to figure out and communicate to developers. But deciding on a coding logic to account for these context changes and sticking to it seems not as easy, especially when developers come and go.

I agree and to add this this...

At one time a web designer could write CSS and HTML, pass it off to a web developer who would generate the HTML in some manner and use the same CSS written by the designer, who could then go in and make changes to the CSS without having to involve the developer or much if any of the developer's tooling.

The separation of concerns is not just about code organization. It is also about people organization.

Your average React component is starting to look like late 90s PHP: an intermingling of CSS, HTML, SQL calls, the kitchen sink, the entire cast of Glee, Kit from Knight Rider and your high school nurse.

...the entire cast of Glee! bwaahahaha....
If you're making a wholesale design change, you should expect a wholesale code change. If you're making a small change to a component that's the same every everywhere you should ideally expect to make that change in a single place. If you don't have that, that's a problem, but it's not Tailwind's fault.

Global defaults are a separate matter. As are prose styles / styles for UGC text because you don't know the HTML structure ahead of time - by all means use the cascade here, but for almost but for everything else you have two maintainable options:

1) Some CSS naming system or scoping system, e.g. BEM where you enforce proper naming and selector complexity limits (except in rare circumstances). This is extremely hard to do in the long term on a big project.

2) Leverage the component system / template system of whatever system you're using to make reusable components and use utility styles.

Using the cascade extensively on a long running project is a recipe for maintainability disaster - you will face a wild goose chase for the file you want every time you want to make a change, and then another wild goose chase for unexpected changes because your selectors weren't specific enough.

I'm also pretty strongly of the opinion nowadays that separation of concerns of CSS and HTML is a false separation - the single concern is how a thing looks on the page.

I guess I don't see how you lose the cascade by using Tailwind. It doesn't lock you out of defining your own classes or hierarchy.

.frontpage h1 or .frontpage .main-heading is going to have more specificity than .text-xl.

> Now I need to touch dozens of jsx/tsx files around the platform and make humongous pull requests, and the result is often dozens of merge conflicts

This can be mitigated by enforcing one-classname-per-line, but it's admittedly not the standard