Hacker News new | past | comments | ask | show | jobs | submit login

[flagged]



It's more like:

  <div class="flex flex-col items-start p-6 space-y-4 bg-gray-100 rounded-lg shadow-lg max-w-sm">
    {links.map(link => <a href="#" class="text-blue-600 hover:text-blue-800 transition duration-300 ease-in-out">{link}</a>)}
  </div>
Where links are defined elsewhere:

  const links = [
    'Home',
    'About',
    'Services',
    'Portfolio',
    'Contact'
  ];
Otherwise, regular CSS would be repetitive too:

    <div class="link-list">
      <a href="#" class="transition-link">Home</a>
      <a href="#" class="transition-link">About</a>
      <a href="#" class="transition-link">Services</a>
      <a href="#" class="transition-link">Portfolio</a>
      <a href="#" class="transition-link">Contact</a>
    </div>
Not to mention your parent className has a lot going on:

  flex flex-col items-start p-6 space-y-4 bg-gray-100 rounded-lg shadow-lg max-w-sm
That would translate to this CSS:

  .link-list {
    display: flex;
    padding: 1.5rem; 
    margin-top: 1rem; 
    flex-direction: column; 
    align-items: flex-start; 
    border-radius: 0.5rem; 
    background-color: #F3F4F6; 
    box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); 
  }
> thought we had HTML list

We have <ol> and <ul> and in the early days of HTML5 people were wrapping those in <nav> to semantically say a list of navigational links. I guess this didn't because it wasn't clear what the role of your links are.


FWIW you wouldn’t need to add the `transition-link` class to every A tag, you could just do `.link-list > a`.


True for this isolated example, but careful with this practice because that requires `<a />` to be the immediate descendant of `.link-list`, where className is more flexible.

Consider a simple HTML change like wrapping links in a list item, or occasionally using a <button /> to handle click events, it would break the styles if you used child selectors:

  <ul class="link-list>
    <li><a href="#" /></li>
  </ul>
^ even with this tiny change, your styles are gone. Would have to change it to:

  .link-list > li > a {}
And would have to repeat that for anything else you'd want to support later:

  .link-list > li > a,
  .link-list > li > button {}
etc. Where with a normal className it would just work in all those cases without having to touch CSS again:

  <div class="link-list>
    <a class="transition-link" href="#" />
    <span><a class="transition-link" href="#" /></span>
    <button class="transition-link" />
    <ul class="flyout-menu">
      <li>
        <ul class="sub-menu">
          <li><a class="transition-link" href="#" /></li>
        </ul>
      </li>
    </ul>
  </div>
All those would be styled correctly without having to explicitly list descendant structures in CSS. So it's more flexible just using className and I would only use > for specific situations.


Don't do that. You will regret it.


Why?


Yeah, I was being deliberately obtuse.

But to be honest, just a few these lists result in sending way more markup than I would be regular old CSS. And we haven't even applied any responsive classes.

Ultimately I think this is a subjective aesthetic judgement... the kind of UI code the tailwind results is ugly and hard to read (for me), and I much prefer using CSS modules.


I thought Tailwind handling pseudo classes and responsive breakpoints in the className was pretty slick, but I also agree with you that they can get very long.

Part of it is just organization/abstraction. Personally, when a component gets too ugly to look at it's time to abstract that away. I want all my top level components to be simple almost English looking syntax and attributes, or even no attributes, like this:

  import { Header, Page, Footer } from 'library';

  const App = () => <>
    <Header />
    <Page />
    <Footer />
  <>;
   
Ideally I'm looking at clean components like this in my daily work, with those long classNames hidden away in a component library: https://github.com/bennyschmidt/ragdoll-studio/blob/master/r...

I think even with regular CSS, styled components, etc. you're still going to have that base layer where all the complexity is hidden.

To your point, it is purely subjective. ^ this example marketing site uses Tailwind but the product itself is native CSS: https://github.com/bennyschmidt/ragdoll-studio/tree/master/r...

I think a directory structure like:

  Header
    index.js
    styles.css
  
  Footer
     index.js
     styles.css
Is also totally fine. The markup in the components is a lot cleaner and often just uses a single selector instead of long Tailwind-esque classNames. With Tailwind I will end up with many more but smaller components - because those classNames are establishing the design system as we go - where with modules (React components using unnamed CSS imports like `import './styles.css';) you can import just the CSS files you need like a base.css, theme.css etc. then your component is very clean - just uses normal selectors and CSS is fully separated out from markup.


I've been building websites for 25 years, but I'm not very good at building maintainable CSS. From memory, I've used Bootstrap, Zurb, SMACSS, YUI CSS, YAML (the CSS framwework), OOCSS, plus various ThemeForest templates.

Perhaps it's not a problem for you, or perhaps you don't like the solution. But Tailwind is hands down my favourite solution to that problem.

If you think there's something better, you need to start from a place that actually solves my problem better. I'm all ears.


I appreciate that it works for a lot of people... I'm just offering my opinion. A lot of people using something and it being really silly aren't mutually exclusive.


Perhaps it would be silly for you to adopt it because you have a skillset that doesn't need it, but it can still be a sensible solution for others.


The docs address this actually:

> Making changes in a project that has tons of custom CSS is worse.

> You have to think up class names all the time — nothing will slow you down or drain your energy like coming up with a class name for something that doesn’t deserve to be named. You have to jump between multiple files to make changes — which is a way bigger workflow killer than you’d think before co-locating everything together. > Changing styles is scarier — CSS is global, are you sure you can change the min-width value in that class without breaking something in another part of the site? > Your CSS bundle will be bigger — oof

Check it out here: https://tailwindcss.com/docs/reusing-styles

There are surprisingly a number of benefits when you allow this kind of duplication. It's a subtle idea but the idea is not all duplication is bad and not all duplication is alike.


CSS is not a non-problem for me and I've been doing web development since IE6. Tailwind is the first time I've actually felt at peace with it. I even prefer your example over a cascading selector in a different file. I can instantly see how the links are styled and if I want to change one I can easily do so right there without having to create a new selector. I can also just copy-paste them somewhere else and know that they will look exactly the same.


It looks ugly, but that’s neither the source code, nor the downloaded binary. It’s what you get after the React components render. (Or similarly for whatever framework you use.)


Yep, but the killer feature for me is the composability. Take a dozen of components made by different authors, slap them together and it all just works, with no css conflicts and messes.


You could “achieve” this with raw CSS classes easily, sure, but good luck maintaining your hand-authored design system.

Tailwind is successful because it has a very well-thought-out design system powering it. If that sounds like a “non-problem” to you, then it isn’t for you.


Exactly. In terms of design, something like tailwind is a great example of the 'templatization' of design and communication, where ease of authoring and maintainability is valued over producing artefacts that are appropriate.

I don't know if this is even remotely true, but I would guess Tailwind, and things like it, are more popular in agencies (sweatshops) that are pumping out projects where junior staff are the ones writing the majority of frontend code.

For the type of thing I do, "hand-authored" doesn't mean "unmaintainable".


In the real world projects tend to have staff with a range of skill levels, and deadlines. This isn’t just in “sweatshops”. Being a skilled engineer means understanding these constraints and choosing tools that help your team succeed, even if you could flex and do everything yourself, maybe even better.

But if you’re equating TW with something like the bootstraps of yore, you’re misunderstanding it.


I'm curious how you would differentiate TW from Bootstrap.


Why don’t you tell us how they’re the same?


Because I'm not the one who introduced the distinction.


Tailwind is a set of design primitives and tooling that are designed to work together in a manner that is more flexible than something like Bootstrap. You could recreate bootstrap’s look -with- Tailwind. See the many off the shelf UI libraries created this way. Tailwind however isn’t designed to create off the shelf generic Ui libraries. It was created for building bespoke UIs that have their styles tightly coupled to their markup. You know, components…

Bootstrap & co is really more like a set of preset styles and UI logic which you can use to quickly get some UI working.

If these distinctions are too subtle to matter for you, then you aren’t facing the problems that Tailwind or similar tools are meant to solve.


Awesome dude!

Well, when I get into "the real world" I'll make sure to change my mind, especially if I'm making "you know, components..."

I think by then these distinctions won't be "too subtle" for my simple mind.

Thanks bro!


I’m sorry if I offended you by answering your question.


Apology accepted


map or use the `children` variant




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

Search: