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

thing is this is way too easy for developers only focused on frontend development.

for us backend developers also doing database, caching, networking, storage, etc. being able to write "m-2 p-2 border border-red-600" is way easier to remember and doesnt take that much brain cpu cycles that we reserve for more important stuff.



They’re quite literally the same. The difference is that you’re now learning tailwind instead of general CSS.

If you’re already doing all that, CSS is peanuts.


They are not the same. Margins and paddings can be configured to use a different base size (5px instead of 0.25rem). Colors can be configured freely, and with a centralized config. Kinda like inline Strings vs constants.

But there‘s more important benefits (IMO):

- Media queries are done inline and become ridiculously easy to read

- Light/dark mode colors and selectors are done inline

- Gradients are easy as pie and actually readable

- Built in grid system

- Your code is somewhat future proof - if the idiomatic code for a gradient changes, you only need update your Tailwind version

- Plugin system for custom code generation


You should do what works for you, but even so.

When you declare `py-4 px-2 bg-blue text-white rounded-lg` on five buttons in a row, doesn't this work almost exactly like inline strings when you compare to the semantic classname `button-secondary` that is maintained in one single place much like a constant? And wouldn't you just rely on constants to maintain consistency between components, in other words use CSS variables?

.button-secondary { background-color: var(--color-action-secondary); }

Inline media queries are not easy to read. What does this button do?

<button class="inline-block px-large py-medium rounded-large border-solid border-thin font-regular bg-core-yellow-100 border-core-yellow-300 bg-text-core-yellow-800 bp-medium:font-medium bp-medium:bg-core-green-100 bp-medium:border-core-green-300 bp-medium:text-core-green-800 bp-large:font-bold bp-large:bg-core-blue-100 bp-large:border-core-blue-300 bp-large:text-core-blue-800 bp-x-large:font-black bp-x-large:bg-core-red-100 bp-x-large:border-core-red-300 bp-x-large:text-core-red-800">Sign in</button>button>

It changes font size, background color, border color and text color when you resize. That's easy to tell if you don't inline it

.button { @apply inline-block px-large py-medium rounded-large border-solid border-thin; @apply font-regular bg-core-yellow-100 border-core-yellow-300 text-core-yellow-800; @media (--bp-medium) { @apply font-medium bg-core-green-100 border-core-green-300 text-core-green-800; } @media (--bp-large) { @apply font-bold bg-core-blue-100 border-core-blue-300 text-core-blue-800; } @media (--bp-x-large) { @apply font-black bg-core-red-100 border-core-red-300 text-core-red-800; } }

Edit: Hacker News did of course inline it, but that only proves the point.

The same goes for light and dark mode. These are by the way Custom Media Queries [1], but Tailwind has a `@screen` directive much to the same effect.

Gradients aren't much different in CSS nowadays, really, and the "built in grid system" is really just a super inflexible subset of CSS Grid that will run out of luck if you need something other than equal sized columns. If you use it for the core page layout, chances are low that you will want your sidemenu, main content and sidebar always appear in equal width columns. In Tailwind you don't, of course, but it is a wonderful feature of CSS.

Tailwind actually is future proof, but that's only because you remove Tailwind from the list of dependencies and check the generated CSS into your souce code repository. At some point all these websites will need an overhaul of the visual identity and people will realize all over again why presentational attributes were removed in HTML4 along with the introduction of CSS. You can update your Tailwind version, then, but nothing will happen. Fortunately, this "plugin system for custom code generation" can be replaced with a stylesheet.

Tailwind has certain qualities, but the things you mention are not some of them. I like that you can't simply copy the CSS from some textarea in Figma and paste it into the CSS, because that will soon make your website even more unmaintable even if it is vanilla CSS. You are in other words forced to think about the layout, the spacing system, the color variables and the breakpoint behaviors, ironically what the typical proponent of Tailwind would like to avoid. If all of these things are declared in a highly customized Tailwind preset, and if you elect to maintain complex components (eg. with synchronized breakpoint changes) in CSS files via `@apply`, it becomes an effective tool to enforce a "design system". Some might say that Tailwind's own creator advises against this strategy, but that should only encourage you, in my opinion.

Essentially, what he is saying [2] is that you should not use SQL to transform you date from one format to the other because the SQL will break when someone changes the database structure. Instead, you should just hardcode the result of this transformation directly into the database and now you won't need SQL at all. You could argue that this would be retarded since the abstraction layer enables different, future presentations of the data in question and that is exactly what I am trying to say.

My best advise is to go light on presentational attributes, which is what utility classes is, and move your Tailwind into proper CSS as soon as the implementation indicates moderate complexity [3]. Here you can make use of the `@layer components` stuff that bears an uncanny resemblance to semantic classnames, but more importantanly, now your Tailwind can easily break out into real CSS, for example to author your core page design with a Grid of uneven column sizing. Make sure to Use CSS variables for everything including your Tailwind preset so that `12px` are never mentioned in the JSON, but instead refers to `var(--base-unit-or-something)` which can be referenced equally in vanilla CSS. Keep the best of both worlds and Tailwind can add more value than it destroys.

[1] https://preset-env.cssdb.org/features/#custom-media-queries

[2] https://adamwathan.me/css-utility-classes-and-separation-of-...

[3] https://frameable.com/company/tech/how-we-found-sanity-in-a-...


I think you are disregarding Tailwind‘s composability almost completely and still thinking in terms of the document based HTML/CSS model.

With TW, it’s preferable to reuse whole components (JS+HTML+CSS). So in your example, you‘d have a button React/Vue/LiveView/etc component that is reused across the app. Only if _that_ is not feasible, you should fall back on @apply.

If you’re developing in an environment where HTML+JS+CSS code reuse is not possible, then I agree that OOTB TailWind is not that much better. But for a component-based architecture where you want to minimize outside dependencies, TW is IMO ideal. Meaning: React, Vue, Svelte, Elixir Phoenix (incl LiveViews) and many others.


If Tailwind relies on classnames used in the HTML and defined in CSS, then that is the document based HTML/CSS model. The composability you are talking about is a feature of CSS, not the component framework. By stopping short at "utility classes" instead of "semantic" classes that define a complex appearance, you in fact destroy composability in favor of either inheritance (assuming that your component framework allows) or simple copy-pasting. Ironically, Tailwind does feature the concept of classnames that aggregate utility classes to produce a complex appearance, it is called "@layer components", and it is infinitely more composable because you can @apply these things as well.

.my-tab { @apply my-button bg-transparent; }

There is actually a very powerful CSS framework hidden in there somewhere, but they remain intent on appealing to developers who believe that real layout is coded with JavaScript, perhaps it is because Tailwind is a multi million dollar business that relies on selling components to teams that give up on making their own.

Your components don't minimize outside dependencies when they share the same global stylesheet, by the way, they would for example not work in my website even though I am using Tailwind (if highly customized). This shared dependency, or "global variables leaking into my scope" as programmers would phrase it, is the problem that CSS frameworks have been fighting for years, and now it's become a brilliant feature of Tailwind that components can share styles. Welcome to CSS! Now you only need to define your complex layouts via @apply and you can share them as well, that is what composability is all about.


> you in fact destroy composability in favor of either inheritance

I favour composition over inheritance, so I'm ok with that.

> Your components don't minimize outside dependencies when they share the same global stylesheet, by the way, they would for example not work in my website even though I am using Tailwind (if highly customized).

I think you just made the case for using vanilla Tailwind and restraining from customizations to cater to design extravaganza. The days of pixel perfectness are over, and designers can and should IMO get used to making compromises. Form follows function, and using vanilla TW can get you more "form" in the same amount of dev time.

Having said that, wouldn't you just have to merge the two Tailwind configs and generate a new CSS file? Apart from color naming clashes (which can't be avoided in any system) I don't see any issues there.


You seem to imply learning Tailwind and CSS take the same effort, but I don't have that impression. Tailwind makes CSS tolerable for people who don't use it a lot. Its classes and defaults let me be productive very quickly. It's not perfect and I don't like that it's yet another config file and more npm madness, but at least it's not CSS.


i know lol, the tailwind docs actually show the css equivalent side by side.

thing is, i despise writing the long ass version especially when im working with flexbox, grids, borders and everything else lengthy that i cant cram up in one liners




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

Search: