Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

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

Search: