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

I'd love it if you expanded on that last comment - my instinct is that functional CSS is a footgun, but I'm not nearly good enough at CSS to really be able to unpack that into concrete problems it causes.


Sure thing. Due to an NDA, I can’t get into granular detail about the site, but I’m more than happy to expand on the problem.

When I started here, I sort of “inherited” a large stylesheet written in the classic BEM/Tachyon style of CSS. I can see why the author chose this method, because at the time the website was small and functional classes seem like a really good thing, as they help you get up and running quickly.

Over the years, however, the site got more popular, and now the demands of the interface are increasing. At one point, it was perfectly OK to do, say, “container mt-5 mb-5 p-20 text-green” etc. This flexibility allowed the site to grow, and while the CSS did bloat, the impact was seen as negligible for years.

Now the site sees 50-80k+ DAU, and seeing as the business is very established, it makes sense that we would want to add bells and whistles to the UI that wasn’t on the roadmap those years ago, like theming, widgets, or simply making a previously non-responsive page responsive.

In Tachyons, and in Tailwind, the abundance of utility classes means that even the best, most organized authors will create inconsistencies. The original container styles from earlier might look something like “container mt-5 mb-5 p-20” in one place and “container mb-30 mt-30” or “container bg-dark pt-5” in others.

It may seem trivial to just add and remove classes at will, but it isn’t. Removing a margin-bottom from one element inevitably affects the position of another on the same page, and trying to reconcile these inconsistencies _usually_ means an override, because figuring out how to rearrange functional classes without breaking anything else is a time suck.

Removing this style of CSS from the project has been tedious, but necessary. Now that we build with small, immutable, scoped components, its trivial to drop in a new component (or remove it) from anywhere without affecting anything else. And you avoid the unexpected inconsistencies created using utility classes by, well, avoiding them. As someone that used to love BEM, tachyons, Atomic CSS, etc., the lack of scope, unpredictability and huuuuge bloat created by overrides steers me away from it even for the tiniest of projects.


> container styles from earlier might look something like “container mt-5 mb-5 p-20” in one place and “container mb-30 mt-30” or “container bg-dark pt-5”

I've only used Tailwind briefly for some side project, but I thought the docs made it clear that whenever you have a situation where you feel you're repeating styles you should extract them into a new CSS class. There's a whole section dedicated to that in the docs:

https://tailwindcss.com/docs/extracting-components

How would this have been prevented if those same developers weren't using Tailwind and instead simply created .container1, .container2, and .container3?

> Now that we build with small, immutable, scoped components

What do you mean by the word component? Are you talking about a React or <insert framework here> component? I don't really see how it's related. It seems like your team quickly iterated and didn't think forward about creating a common look for "containers" until a good amount of development was done. The common look could have been accomplished by extracting the common styles like the above link suggests or creating a common "Container" UI component with isolated styles. The mistake was not thinking ahead and seems unrelated to Tailwind IMHO.


> Now that we build with small, immutable, scoped components, its trivial to drop in a new component (or remove it) from anywhere without affecting anything else.

Any suggestions for further reading on "small, immutable, scoped components" ? I'm half sure I know what you mean and entirely sure I don't understand it well enough to explain it to somebody else.

(thanks for your already expansive reply)


There’s no magic. Remember that at the end of the day, no matter what approach you take to your CSS, we are all dealing in trade offs.

I like to say, that with components, you encounter “a new level of bugs.”

With Functional CSS, you deal mostly with incidental bugs. “This container has margin 10 and this one has 15!” or “This text-red is overriding all my text!” Individually, these are annoying, but together they can compound into unfuckable problems. Right now I’m working on rebuilding a header that was styled with this approach, and ultimatley wound up unable to remove certain classes without breaking other elements. Something as simple as moving the text from one side of the screen to the other involves building an understanding of how they work individually, which is very challenging in a site as large as ours.

Enter my new header, a component. Its got a parent of .HeaderComponent and everything is scoped inside of it. If I delete, say, a .Link here, it doesnt affect links elsewhere on the site. And since I include re-usable mixins for base styles, like text, its easy to (say) @include BodyFont; or HeaderFont; without affecting the page or the site as a whole.

What I mean when I say “a new level of bugs” is that how and why you build things becomes more important. If I build a header component, but a large change happens elsewhere on the site, its unlikely I will change my original component. I’ll make something new and call that, instead.

In this process you can wind up with poorly built components, things that wind up not being used as much as you thought, etc. But the beauty of it is that getting rid of them is SIMPLE. I made a lot of mistakes when I started building doggos.com with components, but I’m really excited about how easy they were to remove. If you just make something new when you need something new, you wont have a bunch of legacy code following you around everywhere.

That probably isn’t a greaaat explanation, but I’m very happy to expand further or give you some links. In particular, Airbnb.design has some great lessons on why they ultimately went this direction, and they do a much better job of explaining it than I!


I followed far enough, I think, and will look at the airbnb site for more.

Much appreciated!


If there are common elements then you name it and reuse the existing classes. So you are not adding much CSS just naming few conventions.


Mixins FTW!!


Yes. That is the purpose.




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: