Join the discussion

Write your take first — we'll ask for email only when you're ready to publish.

  • Hacker News
  • Tailwind crazy adoption is something that makes me happy to nowadays be doing mainly boring stuff in distributed cloud systems and agents, instead of WebUIs.
  • Great writeup!

    Lately I've been enjoying Open Props[0]. It's a library of CSS props/ variables that helps structure a design system. I like it because it's CSS-first, so like OP experienced moving off TW, I've learned more CSS, and it works with the browser not against it. It also provides some sane defaults for anyone less interested in fiddling with precise cosmetics.

    [0]: https://open-props.style/

  • For me Svelte and LLM completely removed my need for Tailwind. Turns out I was using it primarily to avoid CSS collision, and (to me) more logical syntax, rather than the self-imposed constraints.
  • Why did Svelte affect your stance towards Tailwind?
  • It bothers me that SMACSS is from 2011 and was completely ignored. That was the sane way to write CSS. Been doing that for more than 10 years and never had issues redesigning large applications.

    https://smacss.com/

  • That site is a portal back to 2011, wow. Thanks for sharing.
  • One approach I've been really starting to enjoy is to use use Tailwind alongside scoped styles (in Svelte and Vue). This keeps template pollution minimal while still allowing for the conveniences Tailwind brings:

      <div class="counter-component">
          <button @click="count++">+</button>
          <span class="count" :data-is-even="count % 2 === 0">{{ count }}</span>
      </div>
      
      <style scoped>
      @reference "tailwindcss"
      
      .counter-component {
          @apply flex items-center gap-2;
      
          button {
              @apply bg-gray-800 text-white;
          }
      
          .count {
              @apply italic text-teal-500;
      
              &[data-is-even="true"] {
                  @apply text-rose-500;
              }
          }
      }
      </style>
  • yeah, likewise, I locked in on this very early on even though it goes against what the tailwind creators recommend. But I've never regretted this approach and it works well.
  • Nice article!

    I'm a fan of removing any dependencies on external libraries and writing my own solution from scratch, but there's a good reason why I decided not to do so with Tailwind: They offer an optimization for production that ensures that you never ship more than the bare minimum of CSS needed. This means you can keep your palette of color, spacing, and other options fully enumerated in `globals.css` and elsewhere, without worrying whether you're using all those variants in production. Moreover, if you're working within a framework, such as Next.js, this minimization step automatically happens when you build, without even having to worry about whether it's happening. This alone is a compelling reason, at least for me, not to migrate from Tailwind.

    Also, I've never found any restrictions in Tailwind in using inline CSS that weren't readily navigable, or in implementing really nice responsive grids that handle different screen widths for instance using Tailwind's grid tooling. I definitely have solved each of the scenarios described in this article using Tailwind or a Tailwind-CSS combination, but it's true that they don't have grid-column-areas natively. Still, I haven't yet found that to be a significant restriction in getting responsive grid layouts.

    I think the biggest issue with Tailwind is simply that it takes a long time to get used to reading it. We all learn that inline CSS is bad, globally scoped CSS is best, etc., and we get used to seeing clean simple HTML. Then we look at real-world code featuring Tailwind and it just looks so hard to read at first, especially because the lines are so long. I guess I just have been using it long enough that I've gotten completely used to the way it looks, but I do remember it took me a very long time to get comfortable with reading Tailwind. After a long while, I concluded that, for me, Tailwind really is more efficient and maintainable and even more readable, but it definitely took quite a bit.

  • > This means you can keep your palette of color, spacing, and other options fully enumerated in `globals.css` and elsewhere,

    Why not use native css variables?

    > Moreover, if you're working within a framework, such as Next.js, this minimization step automatically happens when you build, without even having to worry about whether it's happening

    Again, if you are using plain css I don't think this is an issue. With any modern build system it will spit out css file for that build, right?

    > After a long while, I concluded that, for me, Tailwind really is more efficient and maintainable and even more readable, but it definitely took quite a bit.

    I think this sentence says it all: Any framework will be "more efficient and maintainable" once learned, even if "took quite a bit".

    For tailwind I think it's an abstraction too far, but that's a decision we all do ourselves.

  • When an agent writes a component, the styles come along with the JSX. "flex items-center gap-4 bg-purple-600 rounded-lg" doesn’t require any mental context switch to a separate stylesheet file. Custom classes force you into a separate file for each component; utility classes keep the style information close at hand.

    The other thing Tailwind stops from happening: class name bloat. In its absence, agents invent classes such as "card-header-inner", "feature-block-content", "sidebar-item-wrapper" – all separate naming choices. After a few months of development, you accumulate hundreds of classes that are not owned by anyone. The limit placed by Tailwind is in its vocabulary; there are no names to invent. This trade-off described by Julia exists. It's just articulated a bit differently.

  • I have been writing a "clean" web development guide focusing on writing HTML and CSS that scales well: https://webdev.bryanhogan.com/

    Maybe it's useful for people here. I don't use Tailwind or similar for styling, just CSS with modern frameworks like Astro or Svelte.

    For every project I have the following CSS files:

    - reset.css

    - var.css

    - global.css

    - util.css

    Other styling is scoped to that specific component or layout.

  • Sounds like a home made Tailwind of your own
  • Using a JavaScript framework kind of defeats the whole purpose doesn’t it?
    by aejm
  • CSS Modules are a simpler solution to cascading problems. They create unique class names, so your classes don't clash [1]. And they don't have the two main downsides of TW, which are readability [2] and tooling. Tooling for debugging and experimenting interactively with Chrome and FireFox DevTools.

    [1] https://x.com/efortis/status/1888304658080256099

    [2] https://github.com/ericfortis/tailwind-eye

  • We've for a while determined that unique class names are a dark pattern. Having to match unique and unreadable names with the actual src is a productivity killer.
  • Don't most modern CSS tools create unique class names? I know styled-components did.

    Recently I've been using linaria which is a drop-in replacement for styled-components (exact same API) but its zero runtime. All the CSS is compiled during build (similar to vanilla extract, panda CSS, etc).

    I really prefer things like styled-components or Linaria or CSS Modules where you can just write straight up CSS. If you ever decide to switch your tool you should always be able to just copy-paste your CSS away. You don't get that with Tailwind or "styles-as-objects" stuff (StyleX)

    by culi
  • One thing that has always struck me about Tailwind is that practically every argument its proponents use more or less boils down to “I never learnt CSS beyond a junior level”. It’s super common to hear Tailwind advocates say things like “Without Tailwind, we would just have one big disorganised CSS file that always grows uncontrollably and ends up with loads of obsolete stuff in it and !important everywhere! Tailwind is so much better!”.

    CSS is a skill just like any other technical skill. If all you do is learn the bare minimum so you can bodge things until you get something that looks right, then your ambitions are going to outpace your ability to keep things organised very quickly.

  • That’s the value of tailwind. You can just skip learning CSS and still get a good result. The benefit to learning it is marginal.
  • Do you have an actual list of arguments with the steps you take to boil them down to ignorance? CSS is a design system, as like any system it can be poorly designed. Poorly designed systems require more effort to operate, and you can even call that "skills", but that just ignores the core issue of comparing design of those systems
  • Isn't the same true of those who use a library that wraps SQL?
  • I'm a big hater of Tailwind but also know that most CSS out there is an absolutely clusterf of outdated rules and !important wars. There's no winning when some dude jumps into the codebase and fixes a bug by adding margin-right to "p"

    CSS linters never really picked up steam and even with them, what's lintable is quite limited.

  • Isn't Tailwind easy to understand when you look at the codebase, rather than putting in more effort to learn a pure CSS codebase? Isn't that part of the argument of Tailwind being easier to scale?
  • You aren't wrong, but the _overwhelming_ majority of "full stack" devs I've worked with only know CSS at the most basic level and have little interest in learning it in depth. I myself have been programming for more than 20 years, doing web dev for almost 15, and I can't find the motivation to learn it well. There are too many technical skills to keep up with and CSS is pretty low down on my priority list. I would prefer to rely on specialists who are experts but companies aren't willing to hire dedicated front end devs.
  • The more experienced Tailwind proponents probably have better things to do than get dragged into yet another online flamewar :) I've done tons of CSS since the 90s before looking into Tailwind. After it clicked, I've mostly tried to avoid raw CSS. In a sense, you exchange one mess for another. Personally, I'd rather deal with a localized class soup than trying to make sense of overlapping, often contradictory, cascades of styles across multiple files. Both can be implemented cleanly, but I'd much rather clean up a Tailwind mess than a CSS one. And I find the development process much more enjoyable overall.
  • It's worse than that; the common arguments for Tailwind literally derive from total ignorance of how CSS is made to work, and a disposal of guidelines that developers would worship in any other context (i.e. Don't Repeat Yourself).

    It's really frustrating to be talking with someone about Tailwind and CSS, and realize that not only do they not know what "cascading" means, they never even considered the concept might be useful in the context of a stylesheet.

    by timr
  • I really, really love Julia Evans writing.

    She writes from a place of vulnerability and honesty. Most people write to sound smart and she writes to say "I don't know it all but there are some things I discovered I want to share." I almost feel like she writes to share things with people she loves, even though she doesn't know them directly.

    She spoke alongside Randall Munroe at the last Strange Loop (RIP). Some people waited to talk to him afterwards, but I waited to talk to her. I don't think she got my joke that she should rewrite her bash scripts into perl and for that I'm truly sorry.

    by xrd
  • > I almost feel like she writes to share things with people she loves, even though she doesn't know them directly.

    Thank you for articulating this!

    I'm not Julia, but I'd just like to put down here that this is pretty much my philosophy for public speaking/giving presentations, and I have been trying to instill it in some coworkers who struggle with presentations. It's a great privilege to be able to convey to one's peers and loved ones things that you're (likely) a bit more familiar with than they are and which may help them with some matter.

  • > I got curious about what writing more semantic HTML would feel like.

    I've been teaching semantic HTML / accessible markup for a long time, and have worked extensively on sites and apps designed for screen readers.

    The biggest problem with Tailwind is that it inverts the order that you should be thinking about HTML and CSS.

    HTML is marking up the meaning of the document. You should start there. Then style with CSS. If you need extra elements for styling at that point, you might use a div or span (but you should ask yourself if there's something better first).

    Tailwind instead pushes the dev into a CSS-first approach. You think about the Tailwind classes you want, and then throw yet-another-div into the DOM just to have an element to hang your classes on.

    Tailwind makes you worse as a web developer from a skill standpoint, since part of your skill should be to produce future-proof readable HTML and CSS that it usable by all users and generally matches the HTML and CSS specs. But devs haven't cared about that for years, so it makes sense that Tailwind got so popular. It solved the "I'm building React components" approach to HTML and CSS authoring and codified div soup as a desirable outcome.

    Tailwind clearly never cared about any of this. The opening example on Tailwind's website is nothing but divs and spans. It's proven to be a terrible education for new developers, and has contributed to the div soup that LLMs will output unless nudged and begged to do otherwise.

  • What's a good source to learn how to develop like this - to create HTML / CSS structure that's accessible?

    EDIT: ignore. I can see you have some links in your profile. Will check it out.