9 ms·
Moving away from Tailwind, and learning to structure my CSS
- villgax 5mo agoRelying on React or Typscript in LLM era seems very stupid, just have the LLM setup whatever dom manipulation you want and have it write decent JS without slop. Far more offline compatible development almost negligible supply chain issues as well. At least ones you can control.
- freedomben 5mo agoThis works great for small sites/apps, but really starts to fall apart if/when it gains complexity where React starts to make sense. I've tried a few times to "just use plain javascript" with the LLM and initial results are often much better, but if the site grows a bit too complex, the LLM starts making a lot of mistakes and it can be hard to reason about as a human and get it on the right track. That hasn't been the case with the React apps IME.
- wakamoleguy 5mo agoWhat a strange take. LLMs produce plausibly correct output, which is exactly where plain JavaScript and DOM manipulation will result in a spaghetti mess. Frameworks like React that add structure to the data flow, component encapsulation, and a huge repertoire of patterns to train on, plus Typescript for immediate compile-time feedback loops… those are what LLMs thrive on.
- thekingshorses 5mo agoI agree, specially for simple apps. it's much easier to upgrade if you are not relying on 3rd party or NPM's. Don't have to worry about code injections. I have these two https://reddit.premii.com https://reddit.premii.com and https://hn.premii.com/ https://hn.premii.com/ both works without any changes. Reddit will stop working once they kill the apis but until then it will work.
- jfengel 5mo agoLayout design issues are orthogonal to choice of language and framework. You can apply the article's approach to plain static pages and to SPAs. I tend to work closer to the latter end and find that both React and Typescript are extremely helpful to make my code extensible and maintainable. YMMV.
- villgax 5mo agoWe strayed away from god after jQuery
- dwb 5mo agoThis makes no sense. LLMs and agents benefit from (good) abstraction as much as humans do.
- villgax 5mo agoSure, just doesn't have to be npm or build dependent IMO
- dwb 5mo agoLLM agents are also very capable of using npm and build systems, and also get the same benefits from them as humans do. For very very simple things (again, just like for humans), it may be viable. But in anything non-trivial I would be horrified with a codebase that was just LLM-spaghetti-DOM-manipulation.
- bel8 5mo agoReact maybe (because there are alternatives). But for mid/large projects, I find that TypeScript brings sanity to JavaScript. I love some quick and dirty JS project. But after a certain project size I begin the see runtime errors like undefined, NaN, 'false/true' concatedted to URLs, and so on. TypeScript eliminates a ton of those.
- cleaning 5mo agoI hope I never have to work with you.
- villgax 5mo agoget back to API calling whip noises
- 48terry 5mo ago> just have the LLM setup whatever dom manipulation you want and have it write decent JS without slop. Hmm, yes, simply have the LLM write good with no mistakes.
- Muromec 5mo agoWhy write in rust if LLM can write assembler for any architecture?
- villgax 5mo agoThat's what another HN post a few days away was saying too lol but about Python
- TonyAlicea10 5mo ago> 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.
- freedomben 5mo agoYou're not wrong, and I mostly agree with you. I die inside when I see the div soup that a lot of sites have become. However, I think there is value in being able to have the important parts of CSS merged into the HTML a bit. Where that line is, is certainly up for debate (and I don't have the answer), but I've found a lot of my tailwind sites are more readable to me than my pre-tailwind sites, often because I don't have to context-switch and open a different file to be able to reason about the styling on an element. For big stuff the second file can be nice, but there's a lot of style tweaking that is great to be able to do right there in the HTML. Tailwind does really lead you to ignore the css file though (or keep it highly minimal), which I agree is becoming an anti-pattern.
- TonyAlicea10 5mo agoThe "open a different file" reasoning piece is a common pro-Tailwind statement and I do see the upsides. I think that upside became more prevalent in the reusable components era, whereas previously CSS was targeting an entire HTML file (and thus the reasoning was more like SQL query than "this one element's styling"). With LLMs I think this upside is much smaller now though.
- KolmogorovComp 5mo agoFor 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.
- esafak 5mo agoWhy did Svelte affect your stance towards Tailwind?
- eximius 5mo agoPresumably because you just put the styles in the component.
- Strom 5mo agoYes and Svelte automatically namespaces them, so there's no collisions.
- mcintyre1994 5mo agoMaybe Svelte does it much better, but there were tonnes of scope-css-to-react-component approaches before Tailwind too.
- brikym 5mo agoSvelte namespaces styles to the component and also has some lint checks for unused selectors.
- stephbook 5mo agoI'm lucky to have learned the web with Angular 2.x It scopes CSS to components by default, and keeps HTML, CSS and JavaScript seperate.
- CharlieDigital 5mo agoVue single-file components (SFC[0]) still works this way. <template> <!-- Largely just HTML --> </template> <script setup lang="ts"> // JS/TS as you would expect </script> <style scoped> /* Component scoped styles here */ </style> Very clean, easy to understand, and (as someone who started hand writing DHTML) it still feels very much like DHTML with more convenience and modern affordances. [0] Vue SFC docs: https://vuejs.org/guide/scaling-up/sfc.html https://vuejs.org/guide/scaling-up/sfc.html
- pjmlp 5mo agoTailwind crazy adoption is something that makes me happy to nowadays be doing mainly boring stuff in distributed cloud systems and agents, instead of WebUIs.
- BoredPositron 5mo agoI am so happy that the only time I have to touch css anymore is for simple internal tools and pico is usually enough for them.
- anydigital 5mo ago+1 for Pico CSS! It’s fantastic. We actually loved it so much that we've taken over maintenance for a fork here: https://github.com/anyblades/pico https://github.com/anyblades/pico
- Serhii-Set 5mo ago[dead]
- neya 5mo agoSo, we're just going a full circle back now. Interesting.
- 4lx87 5mo agoHope so. I’d like to be able to read the HTML templates again.
- eYrKEC2 5mo ago_tailwind_ was the full circle. We had individual controls. We went to semantic controls, then back to individual controls a la tailwind.
- coffeefirst 5mo agoYep. Every 7 years.
- JimDabell 5mo agoOne 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.
- chistev 5mo agoIsn'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?
- JimDabell 5mo ago> Isn't Tailwind easy to understand when you look at the codebase, rather than putting in more effort to learn a pure CSS codebase? No, I don’t think that’s the case at all.
- reaperducer 5mo agoIsn't that part of the argument of Tailwind being easier to scale? I think that was true at the beginning. But Tailwind is quickly approaching the multi-headed hydra it was trying to replace.
- 9dev 5mo agoWhat exactly has changed about Tailwind in, like, years? There are a few more properties for new CSS features, a few convenience features (like size-x instead of w-x h-x for the same values of x), but other than that? If you've grown accustomed to the utility classes eight years ago, then disappeared under a rock until today, you should be able to continue working in an unrelated, Tailwind-using project immediately.
- bryanhogan 5mo agoI have been writing a "clean" web development guide focusing on writing HTML and CSS that scales well: https://webdev.bryanhogan.com/ 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.
- aejm 5mo agoUsing a JavaScript framework kind of defeats the whole purpose doesn’t it?
- hstaab 5mo agocss modules with react are really nice to work with. Plain css scoped to a component. The two arnt always at odds
- bryanhogan 5mo agoWhy do you think so?
- floydnoel 5mo agoSounds like a home made Tailwind of your own
- bryanhogan 5mo agoWell Tailwind CSS is a CSS framework, and I'm writing CSS. What Tailwind does is go fully into inline styles though. But I don't think that's an efficient approach, you also break a few other Clean Code principles along the way. I do have some classes I sometimes apply inline, which are defined in the util.css, but the majority of styling is not done this way.
- hit8run 5mo agoThats why I maintain the successor to tachyons: https://tachyonsneo.com https://tachyonsneo.com No build pipeline. Resort to CSS when utilites make no sense. No lock in.
- keybits 5mo agoCan you clarify how this relates to Tachyons - do all Tachyons features work? Or is it a subset of Tachyons?
- hit8run 5mo agoIt's just a rebuilt drop-in replacement stylesheet compatible to the built version of tachhyons 4.12 but using css variables (so when you need to write custom css you can use its tokens) and it has support for grid plus a few more modern utilities. Building an application you use this as your utility layer that gets you 80% and for the rest you use an application specific custom css to write the parts where css is the best.
- NetOpWibby 5mo agoNature is healing
- zamalek 5mo agoWhat I don't get about tailwind is: why not just use the style attribute at the point?
- 0x3f 5mo agoIt's much more verbose and can't do everything Tailwind can anyway. E.g. how do you style a child on parent hover with the style attribute?
- thiht 5mo agoWith Tailwind: <button class="bg-blue-600 text-white px-4 py-2 rounded"> With style: <button style="background-color: var(--color-blue-600); color: white; padding: 8px 16px; border-radius: 4px; border: none;"> Now more interestingly, Tailwind with hover and focus styles: <button class="bg-blue-600 hover:bg-blue-500 active:bg-blue-700 text-white px-4 py-2 rounded transition-colors focus:outline-none focus:ring-2 focus:ring-blue-400"> That’s not possible with the style attribute. Even more interesting with Tailwind, a div with dark mode and responsive styles: <div class=" bg-white dark:bg-zinc-900 p-4 md:p-8 rounded-xl shadow-sm dark:shadow-none border border-zinc-200 dark:border-zinc-700 "> That’s not possible either with the style attribute. Now your first instinct might be to "that’s unreadable", but keep in mind HOW you actually read and write this code. You’re not actually reading it to understand what it does like you do with iterative code. You see how the browser renders it, and you just adapt the code. Tailwind code is mostly write-only and maintained by viewing what the component looks like. This code doesn’t need to be reusable either, the whole component needs to be. The Tailwind code inside is unique.
- akersten 5mo ago> Now your first instinct might be to "that’s unreadable", but keep in mind HOW you actually read and write this code. You’re not actually reading it to understand what it does like you do with iterative code. You see how the browser renders it, and you just adapt the code. Tailwind code is mostly write-only and maintained by viewing what the component looks like. This code doesn’t need to be reusable either, the whole component needs to be. The Tailwind code inside is unique. I think this helped me finally understand the chasm between tailwind proponents and me. I just don't think I'll ever be part of the "keep painting each room a slightly different shade until it looks right" camp, when there's the "you can buy all the same color paint ahead of time, and even have some left over for the next five rooms you build" option right there. Yeah, tailwind as write-only code definitely tracks. I guess some people like that. Not my bag though.
- Polarity 5mo agooh is this stupid hype of defining design in html with a random framework finally over? thank god!
- thiht 5mo agoCan we stop with this kind of trash opinion? Do you genuinely believe people use Tailwind because they don’t know any better? I understand why many people have a visceral reaction against Tailwind when learning about it for the first time, but when you actually use it, you really can understand why some of the "anti-pattern" stuff you learned about CSS doesn’t really apply with Tailwind.
- grzes 5mo agotailwind is an anti-pattern that breaks separation of concerns rule. i'm amazed how it became so popular.
- thiht 5mo agoBecause it’s a made up rule, not a law of nature. Having the styles inline on a component is very easy to reason about, it was just extremely impractical with CSS and the style attribute. Tailwind makes it easy, practical, and is actually well designed regarding its support for variables (ie. you can have a sane design system easily). What you want to share/cascade is variables, not styles. Styling components makes it easy to make sure the styling of each component is isolated and doesn’t have unintended cascading effects. When working this way, using Tailwind is as much a good pattern than, say, CSS modules (which I like too).
- deleted 5mo ago[deleted]
- agus4nas 5mo ago[flagged]
- Alifatisk 5mo agoOh, have we reached the end of the pendulum swing and are now swinging back to ordinary CSS again.
- EugeneOZ 5mo ago[flagged]
- raincole 5mo agoI think the (misuse of) so-called "separation of concerns" has been the most harmful thing that happened in web front end development. HTML can CSS are the same kind of concerns: the presentation layer. The idea that HTML is purely semantic and has nothing to do with presentation is just burying the head in the sand. Separating HTML and CSS into different files is just like separating a bunch of methods/functions into different files, or splitting one monorepo into git submodules. Yeah, it sometimes makes sense, but if you're doing it for the sake of separating things then just stop. I think the only point of Tailwind is to make front end devs realizing how much separation of concerns is misunderstood and misused as a dogma. Once you realize that you can ditch Tailwind if you like.
- troupo 5mo agoThere are different types of separation of concerns :) https://x.com/simonswiss/status/1664736786671869952 https://x.com/simonswiss/status/1664736786671869952
- xigoi 5mo agoHTML is the content layer. CSS is the presentation layer.
- raincole 5mo agoYes, this is the exact harmful idea that I was talking about. If this were true than there would be no 'reader mode' in browser. Or the reader mode would not modify the html at all. What you see in reader mode is the content layer. HTML is a part of the presentation layer.
- xigoi 5mo agoAre you arguing that things like headers and navbars (which reader mode hides) are part of the presentation layer, not the content layer?
- firatsarlar 5mo agoA life framework, consensus, that how the man face the thing that they crafting.
- simonreiff 5mo agoNice 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.
- SahAssar 5mo ago> 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.
- xrd 5mo agoI 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.
- bthallplz 5mo ago> 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.
- iovrthoughtthis 5mo agohtml encodes a tree of objects css applies attributes to objects via graph queries the queries are tightly coupled to the tree. you must work hard to avoid scatter gun edits now. it doesn't make much sense to have attributes stores in a separate location to their use it would be like assigning all of your instances attributes using decorators
- lawwantsin17 5mo ago[dead]
- huflungdung 5mo ago[dead]
- efortis 5mo agoCSS 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 https://x.com/efortis/status/1888304658080256099 [2] https://github.com/ericfortis/tailwind-eye https://github.com/ericfortis/tailwind-eye
- culi 5mo agoDon'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)
- efortis 5mo agoTrue, I didn't mean to omit other solutions, I thought styled-components were deprecated after React 18.
- madkat 5mo agoYeah it was/is (doesn't work with server components). That's the reason we built next-yak (https://yak.js.org https://yak.js.org) as an alternative.
- culi 5mo agoThanks for your work on Yak. When I was evaluating the alternatives to styled-components, I went with Linaria over next-yak because it is zero runtime. Any plans for Yak to support this as well?
- 5mo ago
- bumbledraven 5mo agoTFA links to https://joshcollinsworth.com/blog/tailwind-is-smart-steering https://joshcollinsworth.com/blog/tailwind-is-smart-steering, which is about Tailwind, but makes multiple distinctions and points that could just as well apply to LLMs, e.g.: > Builders value getting the work done as quickly and efficiently as possible. They are making something—likely something with parts beyond the frontend—and are often eager to see it through to completion. This means Builders may prize that initial execution over other long-term factors. > Crafters are more likely to value long-term factors like ease of maintainability, legibility, and accessibility, and may not consider the project finished until those have also been accounted for. > In my view, the more you optimize for building quickly, the more you optimize for homogeneity.
- taintlord 5mo ago[dead]
- taintlord 5mo ago[dead]
- HungSu 5mo agoI'm observing recurring patterns in Tailwind-only users: they learn a lot of non-transferable and bad habits, especially when the codebase scales up: - Engineers never learn to properly use developer tools to debug CSS - Components get gigantic bloated piles of classes that are not human readable - Those gigantic piles of classes get logic in them, that often would have been easier to write as a CSS selector. Tailwind developers learn to write a JS ternary operator with a string of classes instead of ever learning how CSS selectors work - Those ternary operators get too complicated. The engineers write object maps of Tailwind classes, or export consts of strings of Tailwind classes to use later. Those object keys and const names are what the CSS class names could have been if they just used CSS. They literally re-invent CSS classes, but worse. - Tailwind classes can't be migrated. You can migrate CSS to Sass to CSS modules to Emotion CSS to etc mostly just by copying them over, because all of those are CSS (with some quirks). Tailwind classes are non-transferable The happiest medium I've found was in an organisation of around 200 UI engineers: scoped CSS so that engineers can work with autonomy without colliding with other engineers, plus Tailwind for quick band-aid fixes.
- troupo 5mo ago> You can migrate CSS to Sass to CSS modules to Emotion CSS to etc mostly just by copying them over, because all of those are CSS (with some quirks). Tailwind classes are non-transferable Tailwind classes are literally vanilla CSS classes. You can copy-paste their definitions directly
- locallost 5mo agoI wrote my first CSS 20 years ago, and one thing I can say for sure is that it's impossible to really structure your CSS in this way. The structure will break down over time and it will anyway be buggy and you'll be chasing your tail, as long as everything you do is global. It might work if you're a solo developer, but the reality is most projects involve multiple people trying to get things done. As long as a style is global, changing it will break something else. These days I use scoped styles and that's it. My favorite is when colleague A broke something from colleague B, who fixed it but broke sometimes from me, and I fixed that and broke what colleague A did. The process repeated once more and it landed again on my desk, where I said wait a minute, I've been here already. We were than able to fix all three things at the same time. So it's difficult to keep track of everything.
- outlore 5mo agoIMO the killer feature of tailwind is that it lives alongside your React components so you keep things DRY, and you get a design system with type and spacing scales out of the box. It’s a form of constraint that helps create structure. But I think that makes it a victim of its own success. The tailwind spec becomes ever more complicated the more native CSS features it tries to include. I’ve seen tailwind incantations go way beyond editor wrap line I still like it though. it’s one of those abstractions that actually helped me learn. I would go to the tailwind doc pages and see the underlying css of any class. There were some other frameworks I got excited about: vanilla extract and stitches, both made by some really talented people. I wonder why those never quite got the same traction…
- microflash 5mo ago> I’m a lot better at CSS than I was when I started using Tailwind. > I got curious about what writing more semantic HTML would feel like. This is so relatable. In the beginning of my career, I used to add so many dependencies for things I did not know. But these days, I mostly work on removing dependencies because I'm a lot better at using the web platform. I treat the web platform and browser primitives as materials to build what I want rather than a blank canvas to paint things from scratch.
- klaussilveira 5mo agoIt 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/ https://smacss.com/
- srcreigh 5mo agoThat site is a portal back to 2011, wow. Thanks for sharing.
- dev360 5mo agoTailwind makes sense when you can use React Components to build a reusable design system. It is annoying as heck to use if you don't have that superstructure.
- dev360 5mo agoTo add: I dont want to go back to writing semantic css.. no thanks - I dont go in time-back machines. This is a mess. Just using tailwind and anchoring around a design system like shadcn is just way easier for a team to align around than somebodys made up css language.
- meerita 5mo agoThe only problem with Tailwind is its syntax. It is anti-CSS. It is confusing and takes time to get used to. Heck, people even wrote cheat sheets. That makes adoption wrong, because people install it just because everyone else uses it or because the current thing brings it in. A long time ago, before Tailwind, I was writing true, pure functional CSS https://www.fcss.club/manifesto https://www.fcss.club/manifesto, and I never came back to the old OOCSS or BEM style of structuring all the styles in a project. Components helped a lot with that decision. Today, functional CSS does not make sense only if your website is truly, truly simple. But if your application is more complex, FCSS outshines everything else: speed, rendering, simplicity https://www.fcss.club/syntax https://www.fcss.club/syntax, and weightlessness.
- thiht 5mo ago> It is confusing and takes time to get used to I don’t believe Tailwind is inherently worse than pure CSS. If Tailwind had existed from day 1 on the web and you had learned it first you probably wouldn’t say this. In fact, if Tailwind had existed first somehow, and someone came up with CSS as we know it as a new revolutionary library, I’m not sure it would have succeeded.
- meerita 5mo agoWell, the old-school way was something like this: h1.font.size = 24pt 100%. Tailwind has its own syntax, so you need to learn it first, which adds extra cognitive load. For things like * { color: } in Tailwind, you have multiple options: text-color, stroke-color, etc. With FCSS, you simply have color--[colorname] { color: … }. It’s simpler and avoids unnecessary cognitive load.
- HiPhish 5mo agoI just want to point out that you can use Tailwind inside your CSS with the `@apply` directive (not to be confused with the since abandoned CSS `@apply` rule). You write your CSS and mix in Tailwind instructions where it makes sense. Example: @import 'tailwindcss'; p { @apply text-justify; @apply bg-slate-300 dark:bg-slate-800; /* Second rule just for colors */ display: block; /* regular CSS */ } I used to be a big Tailwind hater because putting all those utility classes as inline styling into my HTML is a crime against nature. But this way I get the best of both worlds. Tailwind is really nice as higher-level building blocks and saves me from writing a bunch of media queries.
- thiht 5mo ago> putting all those utility classes as inline styling into my HTML is a crime against nature. It’s really not when working with components instead of pages, and when working with variables properly
- HiPhish 5mo agoEven with components I prefer what Astro is doing: the component can have a `<style>` tag in which I can add my own CSS. When building the website Astro will know how to transform the CSS so it only applies to that component. This way markup and presentation remain separate even if they are within the same source file. https://docs.astro.build/en/guides/styling/ https://docs.astro.build/en/guides/styling/
- bitbasher 5mo agoI used Tailwind in one web based product and it was alright, but I'll never go back to using it. The HTML bloat was really tough to deal with. I spend far more time in HTML than I'd like, and having more Tailwind classes than I do semantic HTML was really tough to look at. I've settled on using vanilla CSS and applying styles per-page on an as needed basis. For example, include base styles (reset, primary theme, etc) and then include marketing styles (or: blog styles, dashboard styles, syntax highlighting styles, charting styles, etc). It keeps each page light and minimal. Reading the HTML is easy. Styles stay consistent across any pages that share styles, etc.
- anydigital 5mo agoWe also moved away from Tailwind — Pico CSS. It feels like a breath of fresh, modern CSS air. We actually loved it so much that we’ve taken over maintenance of a fork, and just released our Pico successor candidate: https://blades.ninja/ https://blades.ninja/
- d3m0t3p 5mo agoIt is really fun that the navbar has unaligned elements. (Docs is lower)
- anydigital 5mo agowe were focusing on Mobile and Desktop versions, are you somewhere in between? to be tracked here: https://github.com/anyblades/blades.ninja/issues/7 https://github.com/anyblades/blades.ninja/issues/7
- wccrawford 5mo agoThey look aligned to me, but Docs has an underline that's twice as tall as the others.
- wbadart 5mo agoGreat 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/ https://open-props.style/
- ramijames 5mo agoI'm so grateful that people are starting to see that Tailwind is insanity. Just write your class and your CSS as CSS. We don't need to pollute templates with endless hard to parse and reason about tailwind nonsense.
- KaiShips 5mo ago[flagged]
- 3vo-ai 5mo ago[flagged]
- SwiftyBug 5mo agoOne 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>
- pauxel 5mo agoThe part I’d miss most from Tailwind is not having to invent semantic-ish names for every wrapper, row, card, inner-card, card-content, etc.
- DeathArrow 5mo agoThe purpose of web is to display various things and let the user interact with them. Nobody cares about true REST (modern day RESTful is a different thing), HATEOAS or semantic web. People tends to simplify things. We probably can live with just 7 html tags,<title>, <style>, <div>, <form>, <input>, <button>, <a> and CSS.
- kylehotchkiss 5mo agoAuthor in 6 months: How I refactored my rats nest of CSS back to tailwind.
- dudeinjapan 5mo agoThe elephant in the room is AI. The frontier LLMs seem to prefer Tailwind by default. And they do a good job with it--likely because coupling style definitions to your HTML document structure is the least overhead way for an LLM to write code. The alternative--reasoning about a platonic ideal CSS structure, mapping the document structure to that an inferring how the layout will look, then juggling all that while making iterative edits--is a lot more "cognitive" work!
- icar 5mo agoThis feels like reinventing Tailwind, but worse.
- jakubmazanec 5mo agoFor me, the main thing I love about Tailwind is that I don't have to create ad-hoc class names. No more BEM.
- brokegrammer 5mo agoTwo great things about Tailwind: - AI already have data about its classes in their training data - No conflicting styles This means that AI doesn't need to reference any existing stylesheets when generating new styles, which is great for context management. With custom CSS, you'll have AI read existing stylesheets because otherwise its going to write conflicting styles or rewrite stuff you already have. This can be a problem if you have large stylesheets that take too much space in AI memory.
- andy_ppp 5mo agoGreat stuff, one thing I tend to do is set the body font size to be 10px but in ems so all calculations can be made easily - body { font-size: 0.625em; // 10px } and then if you want a heading to be 20px you just do h1 { font-size: 2rem }
- prokopton 5mo agoAlways happy to see a Tailwind/no-Tailwind flame war.
- fps-hero 5mo agoTailwind isn't just a framework; it's a design system. The creators of Tailwind wrote the brilliant book "Refactoring UI" [0], which presents a systematic design system, introducing ideas such a type-scales, color-scales, spacing, and tactics to minimizes the cognitive burden on the designer by forcing design choices. The ideas presented in this book basically are tailwind classes! When you build with Tailwind, everyone is speaking the same design language, and you end up with harmonious designs, even when components came from different projects or designers. I disagree with the author's approach. It's basically just copying the utility classes from Tailwind and implementing them in an unergonomic way. Perhaps the best idea is component level CSS which is something that's been enabled by better tooling. I would implore anyone who doesn't really get Tailwind, to read the origin story [1]. [0] https://refactoringui.com/ https://refactoringui.com/ [1] https://adamwathan.me/css-utility-classes-and-separation-of-concerns/ https://adamwathan.me/css-utility-classes-and-separation-of-...
- zdragnar 5mo agoBoth refactoring UI's ideas you mentioned and component css far predate tailwind. Atomic CSS really solves problems that only exist if you're holding the tool wrong, in my humble hot take.
- edgardurand 5mo ago[flagged]
- digitalblender 5mo agoFrom an accessibility point of view and working on an accessibility audit, using tailwind and utility classes can be really difficult. Working with tools like Siteimprove, will ask if there are matching selectors for things that may be similar, and idm there aren't you may find yourself, looking at each page separately, with that component in it.
- apollyx 5mo ago[flagged]
- Brajeshwar 5mo agoOnce upon a time, whenever I interview developers, most of them proudly announced their expertise in jQuery. I have to bring them down to the basics and ask them about JavaScript. Almost all of them were lost. I asked them, if not for this, but to learn JavaScript and all the other framework will that; a framework on top of JavaScript which one can just use (perhaps take a week or so ro learn). The same goes for CSS. Everyone bolded, and highlighted their experience with Bootstrap but missed the CSS. I did used Bootstrap, Foundation, Skeleton, Bourbon, and many others, especially when working with the team, so we all can speak the same language. This is true for Tailwind too. I remember when Tailwind was still in alpha and I realized that was the perfect tool to bring the team together and move fast. I was able to use it both as a utility and like most other people as the HTML polluter (but it worked). If one is keen, it is always a good idea to learn the core - HTML, CSS, JavaScript; all the frameworks that wraps them should just be syntactic sugar. Bootstrap came and went, so will Tailwind. PS. With AI/LLM Coding Assist, writing in plain CSS is becoming beautiful again. I can outline what I want, give it a checklist and make it do the strenuous part of writing them. I don’t even have to remember the cascades.
- yashasolutions 5mo agoI have found some nice middle ground with Frankenstyle [0] framework which take some inspiration from Tailwind (and Shadcn) but with no-build, which is the thing that I found really annoying with Tailwind. CSS with a build process is already not css anymore. But I understand the feeling of OP to want a cleaner code - without sparkling style details all over the html, though overtime I do feel it really gets out of hand and in the end having the styling in the html makes it less complexity to manage which class is where. [0]: https://franken.style/ https://franken.style/
- cypherpunk666 5mo agofor me i want more semantics. the top level thing we read and maintain and apply should be "roles". https://docs.google.com/document/d/1oIb025h3UcHMJA1zPtk1kauoKYOvGmuGzEP7zOQL76U/edit?usp=sharing https://docs.google.com/document/d/1oIb025h3UcHMJA1zPtk1kauo...
- ceedan 5mo agoFine for personal stuff and exploration. In a work setting, beware of DIY Syndrome. Move away from an established tool, and now your on the hook for documentation, onboarding and maintenance. When the one dev who cares about that leaves the company, everything will fester. It never ends well.
- moomoo11 5mo agooh god bikeshedding alert next thread
- deleted 5mo ago[deleted]
- chandima98 5mo ago[flagged]
- amys94fr 5mo ago[flagged]
- PUSH_AX 5mo agoI’ll catch some flack for this but having done this for a considerable amount of time, I just feel like there are harder and more time deserving engineering problems than how to make a div grey… I like tailwind because it lets you spend more time on things that matter and not bike shedding styles , it just doesn’t matter, zoom out more.
- lofaszvanitt 5mo agoI used the same structure 20+ years ago in the heyday of the web, when I was starting as a dev. If you use tailwind, that's a sure sign you don't understand css. That's all. It's a signal of your incompetence. And at the same time it shows that the dev ecosystem has serious usability issues.
- zelphirkalt 5mo agoPoints 1-8 all seem like basics. Smart, but ultimately basic, and what every web dev should know and learn how to do. I am not even a web dev mostly, only occassionally, and I have discovered most of those things by myself, as kinda logical consequence of what you can do with CSS and the desire to keep things simple. That said, it is a good post putting all those things into one post and give a sane baseline for people who are new to this, or don't know the web's basics well.
- deleted 5mo ago[deleted]
- Chipshuffle 5mo agoIt seems to me there are always two camps when it comes to CSS vs. Tailwind. The one claims that CSS was the right solution all along and it should just be learned and adopted. Then there are others that say that Tailwind makes CSS more approachable and learning CSS never had priority. I'd like to think that LLMs help with the first approach, I'm certainly now a little more curious to try plain CSS again.
- rishushrma 5mo ago[flagged]
- luodaint 5mo agoWhen 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.
- tancop 5mo ago[dead]
- kirtivr 5mo agoA less known hack that can help people build professional websites that do not have the crazy gradients, wonky logos, typography and other tell-tale signs of being LLM generated: Get the TailwindCSS lifetime membership. Costs about $50 if I remember correctly, but they give you all the UI blocks and CSS components, and then you can simply create a frontend-design skill based on Claude's (https://github.com/anthropics/claude-code/blob/main/plugins/frontend-design/skills/frontend-design/SKILL.md https://github.com/anthropics/claude-code/blob/main/plugins/...) that instructs the coding agent to only use TailwindCSS catalyst and UI blocks (you'll have to download these). This is how I built my own website.