In defense of functional CSS - <AUTHOR> https://www.mikecr.it/ramblings/functional-css/ <comment><USER3> How is this any different from saying "don't write functions, just repeat the same 10 lines the function would have in each place you'd use the function"?

The real kicker:

> _" I don't want to have to repeat the same 20 classes on every single > button." That's understandable. I will say that there's a chance that > repeating those 20 classes can actually be somewhat valuable, because when > you get into a situation where one of the buttons needs to have slightly > more margin-top than the others, then it's easy to fix._

That's just... bizarre, sorry.

It's infinitely better programming practice to use a "button" CSS class, because then every time you want to tweak all buttons on the site, you tweak it in one place. With 100 buttons in different places, can you imagine the maintenance nightmare?

The author suggests creating button HTML templates instead... but _why_? That's what CSS already _does_. And when one button needs more margin or whatever other unique tweak... you just add an additional class so it becomes e.g. class="button button-extra-spaced".

For the life of me I can't see _any_ advantages to the "functional CSS" described here at all -- it looks like a nightmare programming practice.

<comment><USER4> Disclaimer: we have been using functional css for about 2 years.

Let's review the main use case you present "I want to tweak all buttons on the site, I tweak it in one place":

\- How many times do I have to change all the buttons on my app?

\- Does changing one class work to change all buttons in practice? Don't I end up having the color overloaded 3 times, cascading over and leaking in 5 others spots?

\- Are most of my edits in CSS tweaking existing rules, or piling up more CSS? Usually, in a large codebase, I end up just adding a class instead of tweaking one and figuring out if I broke anything anywhere.

\- If I use a component-based approach, like Angular or React, do I really have to change classes everywhere with functional css, or just in the button component?

\- Is styling "functional"? Can I always change the styling of a class without changing its semantics - like if I put the primary button the same as the secondary, did the naming help?

Your case may be different and our point of view may also evolve. With functional CSS + component-based approach, I rarely have to use the style inspector - and produce beautiful, maintainable app with 14KB of CSS and no styling bug. All my other attempts using CSS "the right way" lead me to 1MB+ of CSS.

The benefits of CSS to factor style by function seems very infrequent compared to the problems they introduce.

<comment><USER5> > \- How many times do I have to change all the buttons on my app?

When making a styling change like this, it's typical to change it app-wide.

> \- Does changing one class work to change all buttons in practice? Don't I > end up having the color overloaded 3 times, cascading over and leaking in 5 > others spots?

I can change the border-radius on all of my buttons, and they will all change, and still have their color-specific classes.

> \- Are most of my edits in CSS tweaking existing rules, or piling up more > CSS? Usually, in a large codebase, I end up just adding a class instead of > tweaking one and figuring out if I broke anything anywhere.

This is unfortunately quite common in practice - because maintenance is hard and practices are bad. But it is definitely possible to have robust, reusable css.

> \- If I use a component-based approach, like Angular or React, do I really > have to change classes everywhere with functional css, or just in the button > component?

Phew! A component just for a button. What a twist! I don't think most people are making components for each html element. In fact, I'd say this is pretty redundant and overengineering things in a bad way. Guess what - html has these nifty components called buttons too, and you can also style them. Wouldn't any minor change to your button component require then passing in props (just like classes)? <Button propName={"danger"}><button></button></Button> doesn't really seem better than <button class="btn--danger"></button> to me.

> \- Is styling "functional"? Can I always change the styling of a class > without changing its semantics - like if I put the primary button the same > as the secondary, did the naming help?

Not really sure what you're getting at here.

<comment><USER6> > Phew! A component just for a button. What a twist! I don't think most people > are making components for each html element. In fact, I'd say this is pretty > redundant and overengineering things in a bad way.

Welcome to the world of web components. This is actually really common, especially in React with css modules - this way you can use your custom button without even having to think about the CSS (or any extra complexity like tooltips and accessibility), even from a common library used across projects.

<comment><USER7> I want to call this "transverse encapsulation."

</comment></comment></comment></comment></comment><comment><USER8> Yikes.

I agree that this might help you move quickly when starting a project and might be a fine approach for a small prototype or personal site (or, more unkindly, in a consulting project). But you pay a huge cost: maintainability. There is no encapsulation at all, not to mention the pain of having all these generic classes floating around, colliding with anything that might accidentally match. I've worked on projects like this where huge HAML views chain many of these functional CSS classes. It makes it very difficult to accommodate new external components or design updates which I would say are pretty much inevitable in any product company. Even if you don't add anything new, good luck updating the entire system to adjust the padding on all buttons unless you were disciplined enough to truly create encapsulating classes (which is really the opposite approach of functional CSS anyway).

I really think CSS modules got it right (or similar approaches where you have a unique class name per component). Our team approaches component styles like a UIView in iOS—it should render acceptably with reasonable constraints. This means any parent component / view can render this and set display: block, flex, etc and the contents should largely adapt. These days this is pretty easy with flexbox and grid. Even better—you can ensure that the markup classes stay private to you and only allow modifications through JS (or mark some classes as :global). Even better than that—your components can adopt delegation or renderProps to allow parent views to replace / modify with their own markup so everything in the component can truly be encapsulated.

<comment><USER9> > Yikes.

Agreed. Wholeheartedly.

> I agree that this might help you move quickly when starting a project

I don't even see this... at least I can't imagine a case where I'd want to replace "background: #333;" with "bg-gray-darker". The CSS has at least been well established for years/decades, and it'll be much easier to find documentation/support/etc.

> But you pay a huge cost: maintainability. There is no encapsulation at all,

He's advocating that the encapsulation happen at the level of templated markup (or JSX, whatever), rather than at the level of CSS classes.

<comment><USER10> The big difference between this and "background: #333" is that in the later case it could also be "background: #334" or "background: #435". The functional framework approach forces a minimal amount of consistency.

</comment></comment></comment><comment><USER11> Author here. In retrospect a couple months after writing this post, I don't love it. I still am in love with Tailwind and Functional CSS, but I did a poor job defending it.

I'd suggest that everyone read this post [1] by Adam Wathan, the creator of Tailwind CSS. It does a much better job explaining and defending than I did.

[1] [https://adamwathan.me/css-utility-classes-and-separation- of-...](https://adamwathan.me/css-utility-classes-and-separation-of-concerns/)

<comment><USER12> To be clear, you don't love the post, or you've changed your mind on functional CSS?

<comment><USER11> Ah sorry, I just meant I don't love the post (and I just updated my comment to make that more clear). If anything I am even more a fan of functional CSS now than I was when I wrote this.

But my post is just a bad defense of it. The section about the separation of concerns is especially unconvincing, and I spent almost no time talking about the benefits of it. I'd like to rewrite it at some point.

<comment><USER13> Well, hey, I dig the honesty.

</comment></comment></comment></comment><comment><USER14> Functional CSS is a terrific approach. Tailwind in particular is exemplary.

Absent this approach, in web projects of nearly any size, the CSS inevitably grows and becomes increasingly difficult to maintain. It takes very very few cases of "I'll just write a bit more CSS" as the default solution to bug fixes or changing requirements, before the best-intentioned design system becomes a brittle nightmare. Whereas functional CSS supports composition, and makes refactoring a reasonable proposition.

As a 20-year veteran of web UI development, I encourage skeptics to read Tailwind's docs, which make a better case than the OP or I are doing here.

<comment><USER15> so i'm on board with your central concern here. my issue with functional css is that your markup has no semantics. you can't just look at it and know what things _are_ by their names. ie,

what the hell is that thing described by all those styles?

versus:

and i know immediately what it is, and can instantly map the markup to what i see on the page.

you just lose too much by not having that imo.

i really like composing styles out of small little semantic utility classes as in the first example above, but you can do that _and_ still have semantically named classes easily enough with a preprocessor.

i'd be curious to hear your thoughts on that. when i've discussed this concern with functional CSS purists they usually just shrug and say something like "you get used to it" or "you just don't need those semantic class names" but i find that response unsatisfactory.

clean, readable markup is _so much_ more pleasant to work with.

<comment><USER16> One possible solution is in the article - nothing prevents you from using:

with "profile-card" being use just for identifying the component.

Other than that, I rarely go through HTML without Dev Tools, which shows me exactly what a certain div is for.

<comment><USER15> yeah that's better than nothing, but your markup is still super noisy and hard to scan.

> Other than that, I rarely go through HTML without Dev Tools, which shows me > exactly what a certain div is for.

I do all the time. I'd much prefer to work in my text editor, without being obliged to use chrome tools to extract semantic meaning from my code.

</comment></comment></comment></comment><comment><USER17> But wait, what exactly is so hard about doing something like

        // _profile.scss
        .profile-card {
          @extend .m-5;
          // several more lines of extending
          @extend border-gray-light;
        }

and just get the best of both worlds? That variant also has the advantage of letting us JS folk use element classes for useful stuff, and makes changing all instances of "profile-card" simultaneously a lot simpler.

<comment><USER18> Most of the people commenting are missing one of the major point in "functional CSS": Keep specifity low = lower code size, less side-effects, higher maintainability.

Yes, you add bits of complexity in the HTML, but you also gain almost no specifity on the CSS side.

<comment><USER19> Could you elaborate on this more? All three of these points seem counterintuitive to me.

1\. "profile-card" takes fewer bytes than "m-5 p-5 text-gray-light bg-gray- darker border border-gray-light", so the space-savings of not defining profile-card within the CSS seems to be lost the more you reuse semantic styles within your HTML.

2\. "m-5 p-5 text-gray-light bg-gray-darker border border-gray-light" and "profile-card" should amount to the same CSS styling applied at the same level of specificity in an apples-to-apples comparison, so I'm unsure about side effects. Are you saying that using exclusively functional styling you can count on naming conventions to know if two styles would conflict?

3\. "m-5 p-5 text-gray-light bg-gray-darker border border-gray-light" looks a heck of a lot harder to maintain than "profile-card" once I have 50 profile cards in my application styling, spread out across multiple app development teams (and even development languages).

Are you saying it provides other maintainability benefits which are cross- cutting improvements that outlay the ability to think of your HTML as being made up of semantic components? Or are you saying that you are relying on component frameworks which make component definition in CSS a duplication?

<comment><USER18> 1\. Think about this: You have to write or customize .profile-card for every project, with "m-5 p-5 text-gray-light bg-gray-darker border border-gray- light" you're writing 0 lines of CSS. Zero. All your CSS will be your utility framework (sizes around 5~15kb) and it will never increase in size. Now, tell me you never seen a two year project where CSS alone reached 2+Mb because at every edit someone added another class to the list...

Also: When you gzip your HTML those repeated classes will compress pretty well.

2\. Yes, you're right! Same specifity for the example in question. My point was more in general. Think @extend[0], nested selectors in SCSS. They look less scarier than "m-5 p-5 text-gray-light bg-gray-darker border border-gray- light" but they do not always do good.

And I can tell you'll have no side effects: If you look at the HTML only, what ".profile-card" does? Does it add padding, typography, borders, transitions? How do you extend it? I can't tell. But I know for sure that "m-5" will add margin and margin only. "bg-gray-darker" will add background-color and background-color only. And so on. Every class does only one thing. They don't overlap. Once you memorize the simple naming convention you can't go wrong.

3\. Why it looks harder to maintain? Do you all really get scared by a few, readable, classes? Also, classes are no meant to be semantic or content- dependent[1].

At the end, I don't want to defend to death this practice. Maybe it's a concept that is hard to explain (and the OP tried a bit lightly) but I assure you, there are concrete benefits in using this approach. Many may not like it, and it's completely fine, but it's not the hell most of you are shouting here.

Peace! :)

[0]: [https://webinista.com/updates/dont-use-extend- sass/](https://webinista.com/updates/dont-use-extend-sass/) [1]: [http://nicolasgallagher.com/about-html-semantics-front- end-a...](http://nicolasgallagher.com/about-html-semantics-front-end- architecture/)

<comment><USER19> > At the end, I don't want to defend to death this practice.

I tried to phrase things such that I didn't seem to come across as aggressive. We all have such limited views of the world, and opinions are an expression of those views. I found attempting to understand other opinions can widen your own viewpoint, sometimes in surprising ways :-)

My expectation of what people would give as their three benefits are as follows:

1) abstraction of CSS - CSS is not especially crafted to be readable, and you typically need to code workarounds for older browsers using legacy/vendor styles and progressive enhancement. Merely using a functional CSS framework can make the CSS much more readable than manually specifying style information.

2) DRY/directness in component frameworks - if I'm abstracting a profile card into a component, there is little value to stylize based on a profile-card class, especially if that means my style is now separate from the rest of the component definition.

However, if you are _not_ using a component framework but instead using something like templated HTML pages, you really do worry about whether people will identify a particular piece of markup as a profile card or the like, or that profile cards on one page will start to deviate from the rest of the app.

3) (Harder for me to explain) one of the maintenance issues with CSS comes from (logical) components, selectors, and styles all having M:N relationships with each other. So I might define my profile-card styling entirely within a single selector. But I might also elsewhere say something like:

``` a, .nav .selected, .profile-card .info { color: #ed0a1f; } ```

This is slightly different from the concept of side effects, but IMHO this is what makes CSS so difficult to reason about and maintain.

Use of functional CSS (and encouragement to embed styles within the HTML directly, rather than composing new classes via something like @apply in a stylesheet) means that you have created a pretty clear/classical relationship of styles to presentation.

So you might make an argument that classes should be leveraged more for semantic information, the actual styling becomes much simpler.

That sort of argument would make me wonder if there is a potential tool for those who are using templating rather than component frameworks for their buildout - a CSS lint tool that encourages you to use semantic classes, but that those classes must be composed entirely from an extensible set of functional components, rather than raw CSS.

<comment><USER18> I'm sorry, didn't want to appear aggressive either. Maybe when I wrote my comment I was influenced by the great number of negative comments here, but obviously, nothing personal!

Maybe there is a lot of confusion also because the naming of this methodology. The whole "functional" thing. It's funny that the very same practice has also been called "Atomic CSS" and "Object-Oriented CSS (OOCSS)"(!).

I would name it "Non-Cascading Style Sheets" because the whole point is actually giving away most of the "C" in "CSS".

I was also thinking that another point of such negativity may be that to use it you have to somehow master all the CSS rules, where not-so-experienced developers may rely on some "trial and error" or some bad pratice (eg. adding many nested selectors) to achive the same result. I might be wrong.

I remember that there are tools that throw a warning when a class is mutated (ie. overwritten by another rule) because you don't really want to - let's say - add a border when using something like "bg-gray-darker".

Yes, this practice can be a great choice for component frameworks. But it's also great for rapid prototyping and designing UI components or whole web pages directly in the browser.

And for templated HTML pages you can be more expressive using something like

        "profile-card: m-5 p-5 text-gray-light bg-gray-darker border border-gray-light"

Where the "profile-card:" bit has no effect on the presentation but gives the code reader an insight of the markup.

I actually used to do something like this at first during prototyping/designing, but then I stopped. Maybe just because at some point I became so accustomed that I was able to catch every part of the page at first sight.

</comment></comment></comment></comment></comment></comment><comment><USER20> Awful idea. Just awful. The reason for splitting content (+hooks in form of CSS classes) and presentation is to make problem space smaller. If you say that HTML is now concerned with presentation too, you are basically going back to inline styles. And yes, I would prefer style "font-size: 10px" to class "fs10" anytime. At least I don't need to learn new classes with every single codebase I come across. There is a reason developers get emotional when someone tries to defend ideas like this - it's not because we don't understand, it's because we do, and we've been there. The location of the CSS is a solved problem, just let it be.

</comment><comment><USER21> This is really bad advice.

You reduce errors by reducing code by wrapping your code in functions, thats functional and its how classes work. This article suggests the opposite just write everything from scratch perfectly, not going to happen.

> there's nothing stopping you from continuing to add those semantic classes, > even if they're irrelevant for styling If they are irrelevant to style then > it could be applied to anything, it has no meaning and is not semantic.

They don't know what separation of concerns is, or why its a good thing.

>when you get into a situation where one of the buttons needs to have slightly more margin-top than the others

Yea just break your designs consistency im sure your users will love that.

<comment><USER22> I tried this at one company. I have never gone back. It's terrible advice? You can only reconcile this as a matter of experience.

<comment><USER21> > You can only reconcile this as a matter of experience.

I was able to give three common and specific reasons why its bad advice, none of them where to just trust me, or my experience.

If the only reason you like something is because you like it, fair enough, good for you, you like a thing. Its ok to like things, but that doesn't mean there is any solid logic backing the things you like.

</comment></comment></comment><comment><USER23> This seems to misunderstand the basics of why we have CSS in the first place, to separate "how something appears" from "what something is", and suggests to mix the two.

The obvious result is that you would end up with similar objects with different styles. A button with "main" role should have a consistent style across instances, not be green in one place and grey in another because you forgot to add the "green" class. Also changing the color of "main" buttons from green to blue should not entail changing each usage of the "green" class to a usage of a "blue" class.

<comment><USER24> I often wonder how useful this septation actually is. Most of the apps I have worked on seem to be horribly coupled despite separate css.

<comment><USER25> You can introduce implicit coupling in any app (i.e. in a non-CSS programming language). It's bad practice in both cases.

This kind of separation doesn't magically make your frontend code good, it just gives you the freedom to architect it well. Whether you do is up to you.

Admittedly it is very difficult to find an example where this has been done well, but this is I guess why we have abominations like AMP.

<comment><USER24> Sure it is bad design, I won't argue with you on that.

But the other thing is that we rarely upgrade just CSS, usually we get a whole new front end, or even more likely a whole new app.

</comment></comment></comment></comment><comment><USER26> This stuff never scales. No one can remember the class names, no one want's to search through the examples and style guides for a project, no one want's to standardise naming of their own hacks etc and so you start of with good intentions and end up with a lot of duplication and a whole lot of shit.

CSS is an expressive markup. You shouldn't try to turn it into programming.

<comment><USER27> > This stuff never scales. No one can remember class names

Are you saying that with a CSS file with one-class-per-component it's easier to remember the hundreds if not thousands of class names, compared to a functional library, where you only have to remember a handful of them?

You might not like it, but the very reason of existence of functional CSS libraries is to limit the number of classes and improve reusability and composition.

<comment><USER28> Have you written a line of CSS, ever?!

Why would anyone restrict themselves to one class per component? Do you know that classes can be combined? Do you know how specificity works?

CSS fundamentally lends itself to being compositional. Suggesting that this isn't the case without added libraries is either ignorance or madness.

</comment></comment></comment><comment><USER29> As a frontend developer of 15-20 years now I've been pretty dumbfounded and unconvinced by any arguments for this style of css, I think it's especially hard for frontend developers of such duration because this is effectively the first ever style of css you write, and then you were force fed xhtml, semantic web and then later responsive became the "Told you so!" of the methodology.

Despite my scepticism of extremes of semantic web, I realise now when I read articles talking about switching to this style of css, their problems are entirely unrelatable to me because I implicitly see the conceptual structure of a design vs its visual specifics.

This just feels like a new age of developers don't see the need for the abstraction and so it's a constant mental burden for them without any benefit.. I think what has propped this up is that some of the problems that semantic css has historically only ever been able to solve (such as responsive) are now being solved differently, either through more powerful css layouts that implicitly layout better responsively, or that they rely instead on javascript to switch classes/html/components out with media query listeners.

Ultimately I think whatever you decide should be based on what your team aligns to best, don't feel guilty about 'not getting' this pattern, but I think it's important you pick one way, as mixing these worlds just doesn't work (at a project level), but certainly you should always try new things for new projects or experiments.

<comment><USER30> I'm a frontend developer of about 15 years as well and I think functional css makes a lot of sense. My biggest argument for it is not having to name every thing. You know how many times I've had to think of a name for a random container that exists simply to align some crap? Then if you need another wrapper or something for that for some reason? It eliminates the name game (whenever you want it to).

<comment><USER31> > My biggest argument for it is not having to name every thing.

This x 100. As a guy who is the only American on a team with a bunch of non- native speakers, taking away naming responsibility is a big win.

</comment></comment></comment><comment><USER16> Wow, this gets some real hate on HN. I highly recommend reading [0] instead (which is by the way linked in the main article).

If you're writing HTML by hand, then yes, it will be a PITA changing all those "bg-blue" Profile Cards using functional CSS (while it's just a single change when using .profile-card instead). In reality, it's not the functional CSS being the issue, but the markup duplication. If I extract a real reusable ProfileCard _component_ , I can apply functional CSS to it exactly once. If the color changes, it's just a single place I need to look into.

There is no silver bullet. If you design web _sites_ , try some templating language to extract your components. If you develop web _apps_ , take any modern framework like React, which enforces using reusable components. If you still prefer writing HTML by hand, then yes, functional CSS is not for you.

[0] [https://adamwathan.me/css-utility-classes-and-separation- of-...](https://adamwathan.me/css-utility-classes-and-separation-of-concerns/)

<comment><USER32> > If I extract a real reusable ProfileCard component, I can apply functional > CSS to it exactly once. If the color changes, it's just a single place I > need to look into.

Then you're basically moving re-use from CSS to HTML templates. And if both exist only once, it shouldn't matter where you have to adjust that one line.

<comment><USER16> You're right. My main point was to separate your code by purpose instead of technology. That's where component-based development is heading to. _If_ you're using components, then you're still free to choose one or another CSS aproach, but most functional CSS downsides don't apply anymore.

My team in fact combines both approaches. I don't need to define a CSS component just to add some margin, but I am also free not to use 15 functional classes to clutter the HTML.

<comment><USER33> I don't understand why I'd use functional CSS over inline styles. With inline styles I have editor auto-complete, no confusion as to whether it "pt-10" or "pt-15" even exists.

I make pretty heavy use of cascades and don't put classes on every single HTML tag and try and keep my HTML as semantic as possible even though I actually do have components for every button. I will put an inline style of something if that is the most logical approach but proper semantic classes allow me to work at a higher level than individual styles.

<comment><USER16> For me, it's about atomic design. I want to use predefined, reusable values only. So I'm only able to use "pt-10" for 10px and "pt-20" for 20px (as an example). With inline styles, nothing prevents me from using "padding-bottom: 11px" (which may not be defined in the style guide).

Also, from the article:

\- Inline styles don't respect media queries, which basically rules out responsive design

\- Inline styles aren't limited to pre-defined options, meaning you can still end up with 90 different shades of blue)

\- Inline styles cause specificity issues, since they trump separate stylesheets.

\- Inline styles don't support print-specific styles.

\- Inline styles can't address pseudo-elements (such as ::before and ::after)

\- Inline styles can't apply to multiple elements. Utility classes can define .bg-blue once and have it apply to many things, which leads to shorter markup and quicker rendering speed.

\- Inline styles are a pain to type. Compare class="f-sm bg-blue" to style="font-size: 10px; background-color: #0000ff;".

<comment><USER33> > For me, it's about atomic design. I want to use predefined, reusable values > only. So I'm only able to use "pt-10" for 10px and "pt-20" for 20px (as an > example).

I would call these "padding-small" or "padding-big" in that case. Of course, a better way would probably be to abstract that even further in actual purpose rather than style.

> Inline styles don't respect media queries, which basically rules out > responsive design

I question how you could have style-like-classes like pt-10 and be responsive at the same time. So this style is padding-top: 10px as it's name suggests _except_ on mobile. That makes no sense.

> Inline styles aren't limited to pre-defined options, meaning you can still > end up with 90 different shades of blue)

That's fine. Although why limit yourself to calling the class "blue" when you could call it "brand-color" and actually be able to change it something other than blue in the future.

> Inline styles cause specificity issues, since they trump separate > stylesheets.

I don't think you want your "pt-10" style to be "trumped" by another style otherwise that would be confusing. So again this is not an advantage to this style.

> Inline styles don't support print-specific styles.

Again, it would be confusing if "pt-10" suddenly didn't apply when printed.

> Inline styles can't apply to multiple elements. Utility classes can define > .bg-blue once and have it apply to many things, which leads to shorter > markup and quicker rendering speed.

So the advantage is you get to type 5-10 fewer characters per element you apply it to?

> Inline styles are a pain to type. Compare class="f-sm bg-blue" to > style="font-size: 10px; background-color: #0000ff;".

Only if you know all the classes that actually exist for the particular project you are working on. Does f-md exist? Is really "fd-small" in this project? My editor will autocomplete inline styles so they might actually be easier to type.

<comment><USER16> >> For me, it's about atomic design. I want to use predefined, reusable values only. So I'm only able to use "pt-10" for 10px and "pt-20" for 20px (as an example).

>I would call these "padding-small" or "padding-big" in that case. Of course, a better way would probably be to abstract that even further in actual purpose rather than style.

This is perfectly fine. Functional CSS does not enforce any naming. In Bootstrap it's just "p-1" through "p-5". But I would rather go with more semantic names, too.

>> Inline styles don't respect media queries, which basically rules out responsive design

>I question how you could have style-like-classes like pt-10 and be responsive at the same time. So this style is padding-top: 10px as it's name suggests except on mobile. That makes no sense.

Following your example, you can have "padding-small" with different paddings on Desktop and Mobile. Which is not possible using inline styles. For Bootstrap you get media query suffixes for many classes. One common usage is "d-flex flex-column flex-md-row", which makes an element "flex", with column direction on mobile and row direction on desktop. Handy for simple use cases like that.

>> Inline styles aren't limited to pre-defined options, meaning you can still end up with 90 different shades of blue)

>That's fine. Although why limit yourself to calling the class "blue" when you could call it "brand-color" and actually be able to change it something other than blue in the future.

Again, I think you're mistaking a single Functional CSS implementation (like the one used by the author) with the concept itself. You are not forced to use color names and numbers in your functional CSS class names. And I fully agree that semantic naming is way better.

>> Inline styles cause specificity issues, since they trump separate stylesheets.

>I don't think you want your "pt-10" style to be "trumped" by another style otherwise that would be confusing. So again this is not an advantage to this style.

What the author means: using only functional classes, you know exactly that your "pt-10" padding is not overwritten (unless you use another "pt" class by mistake). With "traditional" classes, you can't be sure of that. And more often than not you will get problems with the cascade, especially in bigger projects with many developers. That's where all the "!important" hacks are coming from.

>> Inline styles don't support print-specific styles.

>Again, it would be confusing if "pt-10" suddenly didn't apply when printed.

You can do much more with CSS than adding padding ;) Hiding elements for print is the main use case here. You can't achieve this with inline styles only. A "print-hidden" utility class can do that.

>> Inline styles can't apply to multiple elements. Utility classes can define .bg-blue once and have it apply to many things, which leads to shorter markup and quicker rendering speed.

>So the advantage is you get to type 5-10 fewer characters per element you apply it to?

No, the advantage is that you can use only pre-defined, reusable, atomic definitions. If the style guide says there are only 2 types of padding ("padding-small" and "padding-big"), you won't be able to set another padding using functional CSS only. With inline styles, you can do whatever you want. This also applies to raw CSS stylesheets. That's why pre-processors are so valuable - you can define your SASS/LESS/whatever variables and achieve the same effect. And before you ask: "then why do I need functional CSS in the first place?" \- it's because of the other advantages, like not having to use a pre-processor or defining/importing a stylesheet in the first place.

>> Inline styles are a pain to type. Compare class="f-sm bg-blue" to style="font-size: 10px; background-color: #0000ff;".

> Only if you know all the classes that actually exist for the particular > project you are working on. Does f-md exist? Is really "fd-small" in this > project? My editor will autocomplete inline styles so they might actually be > easier to type.

If you don't know all the classes, then you need to know all the style guide values. Otherwise, how do you implement a consistent-looking design? Take our "only 2 padding values defined" example. You will have to look stuff up, be it functional class names, traditional class names, SASS variables or simply the values to be used. Also, _my_ editor will autocomplete functional CSS classes, too.

<comment><USER33> > I think you're mistaking a single Functional CSS implementation (like the > one used by the author) with the concept itself.

Honestly at some point what you describe I would just describe as normal CSS.

Functional CSS is classes based on their visual function rather than an abstract concept. This the definition. But the more semantic your names are the less they related to an actual visual function.

If on mobile you don't apply any padding then your padding CSS class is a lie. And if you don't call it "padding" in some way then it's not Functional CSS. I also think conceptually having a few utility classes like "print-visible" or "print-invisible" is not really applying Functional CSS as an overall concept.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER34> What about theming/branding so that you can make your enterprise web-app fit in with each of your clients other web-apps?

If your class names are semantic like _profile-card_ it's easy to have a branding css file for each client.

If your class names are functional like _m-5 p-5 text-gray-light bg-gray- darker border border-gray-light_ you're going to... what? make code changes for each client?

Obviously if the website is only going to have one branding, this isn't an issue, but advice like "use semantic css" or "use functional css" needs to be put in context. What you do in an agency context for content sites would be different from an in-house web-app context, or a web-app for SAAS context.

<comment><USER35> It's all about tradeoffs, there are no silver bullets. If your class name is like _profile-card_ then it _could_ be simpler... until it's not. Because it turns out that one of your client _profile-card_ needs to behave slightly differently on hover or whatever. In theory, _profile-card_ is a great idea, in practice it can be a headache

<comment><USER34> What I'm saying is you have files client-alice.css and client-bob.css, and you define different profile-card:hover rules in each. But with functional css you have nothing to hang your rules on.

</comment></comment></comment><comment><USER36> I usually don't want people to be able to create infinite variations of things because of a lack of consistency.

I like defining a few concrete component styles BEM style and having it easy to re-use them and other people not abuse them too much. After the initial components are defined I don't want to think about what border or colours are involved I just want to drop profile-cards in various places. It feels like this "functional" approach doesn't solve enough real-world use cases (that I have experienced at least) to justify using it.

<comment><USER37> > It feels like this "functional" approach doesn't solve enough real-world use > cases (that I have experienced at least) to justify using it.

I suggest reading:

[https://hackernoon.com/full-re-write-with-tachyons-and- funct...](https://hackernoon.com/full-re-write-with-tachyons-and-functional- css-a-case-study-part-1-635ccb5fb00b)

</comment></comment><comment><USER38> We did this at my last job, but inevitably ended up with a mix of half functional CSS and half component CSS.

If you have lots of repeated components on a page (comments, thumbnails, tags) then it's difficult to defend repeating, potentially dozens, of the same declarations. You're better off with the component defined in a stylesheet.

I think the real use for functional CSS is for one-off adjustments on those components:

..

..

..

It's also a pain to edit all of the instances of an object when you want to update styles consistently. One upside, though, is that you have to consider the impact of the change in each spot.

<comment><USER37> > If you have lots of repeated components on a page (comments, thumbnails, > tags) then it's difficult to defend repeating, potentially dozens, of the > same declarations.

That's where you have two choices:

1\. Use your HTML templating language to define a dynamic variable representing the set of classes and use that.

2\. Like the article says, make use of the functional CSS's tools to create a new class that includes the styles you use. Same idea to #1, just at a different stage.

<comment><USER39> Both "solutions" don't address the problem of repeated class names, they just help repeating them in a correct but not less obscene way. Bloated markup cannot be defended.

<comment><USER37> Yes they do, at least in a way that's no worse than every other CSS toolkit in widespread use.

And there's nothing "correct" or "incorrect" about it. I suggest reading [1] if you want some real data on the usefulness of functional CSS.

[1] [https://hackernoon.com/full-re-write-with-tachyons-and- funct...](https://hackernoon.com/full-re-write-with-tachyons-and-functional- css-a-case-study-part-1-635ccb5fb00b)

<comment><USER39> I mean "correct" in the formal sense that every element gets the intended style, which is possible even with bad design and bad technology.

</comment></comment></comment></comment></comment><comment><USER40> I've used BEM, atomic design and functional CSS. I actually like some kind of combination of all three. This is my 2c:

The pros of functional CSS as a replacement for CSS/SASS variables:

\- You define your 'palette' up front: which margins, font sizes, colors are acceptable, etc. You could do something similar with CSS/SASS variables, but you'd give up the capability to rapidly prototype on any machine with any browser and you'd need HMR set up everywhere. Also since it's a class you can (de)compose it with other classes and build up 'abstractions'. So I'm really using functional CSS as a better replacement for SASS variables.

\- It's easiest to start hacking away at designing widgets without worrying about things looking inconsistent eventually, because you're working with a limited palette

And then what I take out of atomic CSS is splitting up the code into different levels. Instead of atoms, molecules, organisms, I have: palette, abstractions, components. Abstractions are composed of other abstractions and/or things from the palette. Ie: an abstracted class might be like: .center-vertical, .center- horizontal, and then composing those would give the .center class. Components are concrete widgets like buttons, popovers, modals, tables, lists, etc.

And I use the submodule idea from BEM. So if I need to create custom themes, it would be the like .button .button-(theme name) and writing the theme works just like inheritance would here but I'd be using composition instead

</comment><comment><USER41> Why does it seem like no one knows anything about CSS? BEM, "Functional" CSS, all this nonsense simply because nobody know about the child selector as opposed to the "any descendant" selector. (Maybe because it wasn't supported in IE6 and we're still reeling from that to this day...)

Take ten minutes and learn. Here's some tips:

Attribute selector:

      button[disabled]
        background-color: gray

Modifiers are just classes, never have disconnected .some-classes floating around. Keep them scoped to their element :

      button.large, a.button.large
        font-size: 2rem

Child selector:

      profile-card > h2
        font-size: 1rem
        margin: 0

Everyone forgets to put in the alligator and then complains that their ridiculously nested markup gets out of control. This way a card can contain _anything_ and not have to worry about stomping its styles.

Semantic elements:

      profile-card
        display: block

      profile-card.active
        background-color: green

You don't need to be limited by span/div-itis. It's 2018 go wild.

Pro-tip:tm: try learning CSS before creating or adopting a CSS "framework" to solve problems that CSS already solves.

Hope this brief rant saves a life or two. Hang in there people.

</comment><comment><USER42> Applying CSS using utility classes it just a different way to abuse HTML for the purpose of inline styling.

\- How do you set a class for states like hover, focus, active, hidden, checked, etc

\- How to you use/create/style pseudo-elements?

\- How do you add responsive control (like CSS media queries)?

'Functional CSS' is like sitting down at a full piano keyboard and trying to bang out a tune by only hitting one key - there's a LOT more range possible in CSS, and it's only difficult mostly because we MAKE it difficult by ignoring this.

The only/best 'functional' CSS tooling I would even look at these days is [http://css-blocks.com](http://css-blocks.com) from the people who made Sass, it's a much more modern approach and you end up with highly optimized code, HOWEVER you write human-readable CSS stylesheets and you let the CSS-Blocks compiler and Opticss optimizer output the 'functional css' you need.

Let humans do what humans are best at (writing nice stylesheets) and computers do what computers are best at (compiling things). It will outperform and human pretending to be a compiler, and with better accuracy.

<comment><USER30> This is how you can do all of that:

      class="hover:red" -> .hover\:red:hover { color: red }

      class="before:red" -> .before\:red::before { color: red }

      class="medium:red" -> @media (min-width: 500px) { .medium\:red { color: red }

The important thing though is it doesn't need to be used for everything. I think it makes a lot of sense for structural stuff. When you dig into like, children of a hovered element I can see it getting a little messy.

<comment><USER42> How come people who do this only ever use class names? Why not invent your own data attribute like data-hover="red" where you create new namespaces for things like hover, or pseudo classes, why it it always only ever class names?

<comment><USER30> Totally talking without thinking about it too much here:

The classList API makes modifications to the class property very easily.

You'd be essentially limited to one identifier in attribute selectors. You can't really select from multiple identifiers with a data attribute without doing like:

      [data-hover*="foo"]

which would search for "foo" anywhere in the attribute, which could mean incorrect substring matches.

Chaining attribute selectors would be rough too:

      [data-hover*="foo"][data-hover*="bar"] {}

vs

      .foo.bar {}

<comment><USER42> > The classList API makes modifications to the class property very easily.

So does the dataset interface for custom data attributes: [https://developer.mozilla.org/en- US/docs/Web/API/HTMLElement...](https://developer.mozilla.org/en- US/docs/Web/API/HTMLElement/dataset)

> You'd be essentially limited to one identifier in attribute selectors. You > can't really select from multiple identifiers with a data attribute…

That's just not true, there's an attribute selector that targets strings in a whitespace separated list: [attr~=value], so you could think of .demo as being a shorthand for [class~="demo"], or #demo as a shorthand for [id="demo"].

      [data-hover~=foo][data-hover~=bar] {}

would target a tag like this:

But not a tag like this:

More info about attribute selectors: [https://drafts.csswg.org/selectors-4/#attribute- representati...](https://drafts.csswg.org/selectors-4/#attribute- representation)

<comment><USER30> I wasn't aware of the tilde attribute selector. Still a lot more characters, though.

The classList api is still a lot more suited for this than dataset. None of the modifications done through the dataset api would reflect in the DOM and be readable by CSS unless you were to convert the list to a space separated string and explicitly set the attribute. classList handles all of this for you.

<comment><USER42> > None of the modifications done through the dataset api would reflect in the > DOM and be readable by CSS unless you were to convert the list to a space > separated string and explicitly set the attribute.

I'm really not sure what you mean by this. If you set the data attribute any of these ways, it can be targeted in CSS with [data-demo="example"]:

        el.dataset.demo = 'example'
        el.dataset['demo'] = 'example'
        el.setAttribute('demo', 'example')

CSS doesn't require a space separated anything. When you use an attribute selector in CSS it treats the entire value as a string, spaces included. But it's not classes versus attribute selectors, as class is an attribute, and therefore also something you can select with attribute selectors.

Also, think about the asymmetry between CSS and HTML when considering saving characters, one CSS selector targets ∞ tags, so I'd rather write slightly longer selector one time, than need to use a much longer 'namespaced' value on each element where I want the style to apply. That's leveraging what CSS does best!

<comment><USER30> I'm just saying if you want to target something on an element it needs to be set in an attribute and classList takes care of this.

I use classes strictly for styling. I change these styles by adding and removing class names and classList handles it very well without me needing to read the data attribute, make it an array, manipulate it, join it and update the attribute.

<comment><USER42> I feel like you're still thinking small in terms of attributes, and big in terms of values. Many many values all crammed into one attribute (class), but the reality is you can invent infinite (∞) data attributes. There's literally no need for you to format the values as a list of space-separated values…unless you want to. But if you don't want to, there's no need. Consider this, instead of targeting something with classes like this .active.demo, and setting it like this

        el.classList.add('active')
        el.classList.add('demo')

You would NOT need to do something like this to use data attributes, [data- example~=active][data-example~=demo] and to set it like this:

        if (!el.dataset.example.split(' ').includes('demo')) {
          el.dataset.example += ' demo'
        }

You could instead easily set two attributes and test for their presence, even if they don't have values (or you're not using them)

        el.dataset.active = el.dataset.demo = true

And then you can target that in CSS with [data-active][data-demo]. To remove them later is just as simple:

        el.dataset.active = false

And it's gone! Try to think BIG in terms of attributes, and small in terms of values. It's a lot nicer than trying to cram all of your values into just one attribute when you literally have infinite attributes available to work with!

Not only do you have infinite attributes to work with, but you can

Using classes as your only way to target styles, and ignoring the other aspects of how CSS selectors can target elements is like picking up a guitar and trying to play a song, but only plucking one string. You might be making it harder on yourself to get the job done, and the result isn't any better for the effort.

EDIT: Just for kicks, have you ever considered the flexibility of what data types you can set as an attribute value other than a space separated list of strings? Try this:

        // set JSON to attribute value
        document.documentElement.dataset.example = JSON.stringify({one: 1, two: 2})

        // get JSON from attribute value
        JSON.parse(document.documentElement.dataset.example)

You can even stick a bit of JSON there as the attribute value, which can be parse/stringified by JS, is _easy_ to add or remove properties from and work with on the JS side (not requiring helper methods like classList), and is _still_ targetable by CSS once set on an element :D The possibilities are endless, the apparent limitations a lot of people butt up against are self- imposed.

<comment><USER30> I'm sorry I'm just not seeing the value in it. I'm just seeing more complexity JS and CSS wise without solving any problems.

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER43> I'd call this style "compositional" rather than "functional". You're composing an element's style from smaller chunks.

My main problem with this is that some people like working that way and some people don't. This leads to a mish-mash where you have two completely different places to look for where your styling might be. Since you can't specify _all_ of your styles in this fashion, then in order for there to be one spot where the styles live, putting them in CSS files with semantic classes is the sensible default.

My other problem with it is that it encourages many DOM elements with one style each as opposed to fewer elements with more style rules. I feel like I'm swimming whenever I'm looking through the markup with an inspector.

More ideally what I'd like to see is styled-components, so the entirety of a component lives all in one code file. I don't particularly care for the use of javascript to specify literally everything on the page, from the markup to behavior to styling, but the siren song of having everything there in one place makes up for it. If you want terseness in style definition, which is the main problem this "functional" approach solves, then you can simply invoke short javascript functions.

My ideal approach though actually would lean on a text editor / IDE to keep a list of components, and opening up the markup, styling, and scripting of a component all at the same time, and just using HTML templates, SCSS, and vanilla Javascript, keeping each file unsullied by the syntax and semantics of the other languages.

I'm unconvinced that everything really needs to be Javascript, but I don't mind wandering down that rabbit hole with everybody else until the React fascination passes. It's not the worst way in the world to specify UI.

</comment><comment><USER44> As usual maybe it is wiser to take the good parts from different approaches, rather than going "all in" with one ideology / methodology.

For my sites I find it useful to have a small collection of very generic classes. One common case that was annoying is how the spacing keeps changing as you move text and components around a page, and you end up fiddling with the rules all the time to adjust for how the top/bottom margins merge. No matter how "logical" it is, from a graphic design pt of view, the spacing is right when it _looks_ right.

So I have a few very generic classes like this:

        .mb-0   { margin-bottom:0; }
        .mb-1   { margin-bottom:1em; }
        .mb-2   { margin-bottom:2em; }

         /* text */
        .txt-lg { font-size:1.4em; }
        .ta-r   { text-align:right; }
        .ws-nw  { white-space:nowrap; }

These are useful for making small adjutments to the layout. That said, going all in with atomic css doesn't make sense to me.

<comment><USER45> I do the same. I have a scss file with a few margin and padding mixins that I can throw into the dom when I need to. Otherwise, I'll stick with updating all my buttons at once in my css `button` class.

</comment></comment><comment><USER46> This ridic argument boils down to code reuse and components.

The whole reason for css is to facilitate style reuse when writing markup. In normal html pages you write a bunch of markup, chunks of that markup might represent the same "component" and so css is a great way to style those similarly using semantic class names.

If you use small components that exist in some type of template (react, vue, etc...) you can take advantage of that to facilitate your code reuse instead of a "semantic-component" css class. I think that is where utilities become valid because you still only change a components styles in one place.

</comment><comment><USER47> Why is this named "functional" CSS?

Something like "const FIVE = 5" doesn't seem to capture the essence of functional programming either?

<comment><USER48> Maybe it's not a reference to functional programming but to that other definition of "function", you know, the one used by everybody except programmers.

</comment></comment><comment><USER49> _Have you ever really looked at a thing with class= "profile-card" and said "oh this is a profile card", when it wouldn't have been just as easy to tell that based on the context or what it contains?_

Wait, what? Who _hasn 't_ done this?

</comment><comment><USER50> Oh God. Please don't let this be a thing. I hate to be negative but this is a bad direction for a set of technologies (HTML/CSS/JS) that have already veered heavily down a miserable path.

</comment><comment><USER12> This thread is why I love HackerNews. I'm in the middle of considering something like this w/ Tailwinds and share some of the concerns expressed in some comments here, but I'm still keeping an open mind.

Is there anyone who's tried it for a project and still hated it? Seems like a lot of the detractors haven't actually used it yet.

</comment><comment><USER51> I used this technique in my previous startup. I even had shell scripts that generated my LESS files.

One of the driving philosophies was that when one saw a CSS class, they should easily be able to find it's definition in the source. Another driving philosophy was that one should easily be able to determine what the class is doing.

This lead to classes like `u-centered`. The `u` tells me it's in the utils.less file. Classes starting with `l-` were layout classes, `t-` text classes, etc..

I had classes like this:

u-{max,min}-width-{xxs,xs,s,m,l,xl,xxl}

t-white

u-bg-red (red background)

t-h3

l-container-{xxs,xs,s,m,l,xl,xxl}

You get the picture.

(The nice thing about xl and xs is that you can keep adding x's as you need.)

I found it to be very effective. I understand the arguments that it kind of defeats the purpose of CSS, but I think CSS is pretty easy to mess up, and this give you a solid, consistent structure to work with.

Of course, I didn't follow this style 100%. There were some cases where it just made sense to use a more semantic style, but I found those case to be few and far between.

<comment><USER33> Seems like a waste of time when you can just do style="background: red;". You're not adding anything to CSS you're just renaming and enumerating all the style attributes and values.

I think it makes sense in small doses but I think once you're using shell scripts to generate all these combinations you've lost the plot.

<comment><USER51> There's a big difference between class="u-bg-red" and style="background: red;". The big difference being that the class make it so that it is first- class application idea.

And I think that may be one of the larger points here. CSS can be simple, and using techniques like this forces it to stay that way. You have to take a step back and understand what we're trying to do as engineers. I would argue that being able to quickly understand code (e.g. the context to understand a line of code is small) should be a top priority of most software project.

<comment><USER33> "u-bg-red" vs. "backround:red" is just the same thing aliased. If you were to introduce an actual concept like "warning" or "error" that was red that would be different.

<comment><USER51> You are correct from one point of view. But, the point I was making was that the class definitions for bg color can be contained within a single file in your application. Using `style` is completely different in that anything is possible. This is a big deal, as cutting down on possibilities/simplifying is a very important process in software engineering.

<comment><USER33> > But, the point I was making was that the class definitions for bg color can > be contained within a single file in your application.

But that doesn't matter because it's not an abstraction. If you have 10 HTML files and 1 CSS file, you can make a class called "warning" and have it be a background color red you've simplified those HTML files because you have less style information in the HTML.

But if you are using classes like "bg-red" or "pt-10" then you're not actually reducing the style content of your 10 HTML files. You've just renamed a style to a class. Sure you've reduced some possibilities but you've actually made the situation worse because now you have 11 files with style information. You've added new names for basic styles which adds even more complexity.

If you take that idea of reducing style possibilities to the logic extreme then you wouldn't be using classes like "bg-red" and "pt-10" anyway. You'd just do what everyone already does with CSS and abstract your styles appropriately.

</comment></comment></comment></comment></comment></comment><comment><USER52> My experience with functional CSS was skepticism followed by delight. Reading BEM style actually makes me more skeptical now. A class of "Button Button__Primary" tells me much less about the styles of that button than a string of functional CSS classes would.

<comment><USER39> When the customer asks me to change the background of primary buttons from green to yellow and the background of nonprimary buttons to red, while changing other green backgrounds to a green-brown gradient, classes like "Button Button__Primary" tell me much more than classes like "bg-green".

<comment><USER53> Your customers speak a different language than most of mine. The requests are more like "I need the green buttons to be yellow now!" It's easy to find bg- green on buttons and just find/replace with bg-yellow.

Also, using Tailwind/functional CSS for items that are repeated over and over on your site like buttons, you can easily extract them to a component. Switching from bg-green to bg-yellow would be as simple as opening your SASS/LESS file for components or button components and replacing it in that one spot.

<comment><USER54> > It's easy to find bg-green on buttons and just find/replace with bg-yellow.

Oh, that's because running sed over all your project files, all in a set of weak typed languages is easier than changing a definition in a single place. I totally get it.

</comment></comment></comment></comment><comment><USER55> Everything old is new again (sort of). There was a similar paradigm being promoted several years back that was dubbed "Object-Oriented CSS (OOCSS)": [https://www.smashingmagazine.com/2011/12/an-introduction- to-...](https://www.smashingmagazine.com/2011/12/an-introduction-to-object- oriented-css-oocss/)

It's a little unfortunate that the use of the terms "functional" and "object- oriented" were chosen in these cases as they can easily be confused with functional vs. OO programming, when in reality CSS or any paradigm of writing CSS has nothing to do with this distinction.

<comment><USER28> This was my first thought too.

There's nothing novel here. There's just a misunderstanding of how CSS works, an over-engineered solution to a non-existent problem, and then a misused name added for a veneer of sophistication.

</comment></comment><comment><USER56> Neat.

Now add a way to hierarchically roll-up these micro-classes into semantic classes behind the scenes (Perhaps in webkit?). Compile things so you only carry-around the css micro-classes you've used, and make a flag to either deploy using the semantic or micro class method.

Best of both worlds. There are also some other mix-and-match ways of doing this. Where the real value is separating the tiny CSS adjustments you make from the business-class stuff, creating a middle tier (which this guy deploys directly)

It might make things easier. Or it could be yet another dumpster fire. I think it depends on how it's used.

<comment><USER34> You could do this with SASS or LESS.

Make all the "functional" classes as _abstract_ mixins or placeholder selectors (in SASS parlance), and then use them to define your _concrete_ semantic classes.

<comment><USER57> variables and mixins, clean css, readable templates instead of some overloaded hodgepodge of classes.

<comment><USER56> Yeah. I was reading this thinking "If only we had some way of abstractly creating CSS!"

Which of course we already do. Maybe there's a case that the toolchain or conventions need tweaking. So it's worth the discussion in my mind. Most times you really don't realize what you need from a tool/framework until you've reinvented it, so we need folks like this doing sanity checks on where the rest of the industry is going.

</comment></comment></comment></comment><comment><USER58> Functional CSS changes a mistaken way of thinking about CSS classes: as a unit of visual abstraction.

When you have a "ProfileCard" class, you expect it to encapsulate the profile card without leaks, and with perfection. But that is never the case - <USER2> are so many variations of profile cards that almost everyone who uses "semantic" CSS (BEM, SMACSS etc.) end up with hundreds of tiny variation of this class, each one of them scoped to their particular container or page. Not to mention the proliferation of different shades of the same color, inconsistent typography, and ad-hoc spacings.

The right level of abstraction for user interface is the DOM+CSS; neither of them stand alone. This idea "separation of concern" has taught us to think of them in separation, and feel guilty everytime we have messy CSS that breaks that idea. But it is the idea that is wrong.

The right level of abstraction is the "component". eg: in a React component library you might have multiple Buttons, each of which is a highly reusable non-leaky abstraction. Here Functional CSS abstracts a lower granularity: design tokens/scales. It will give you consistent spacings, colors, and typography. These two in tandem is a fantastic way to look at building UIs that are consistent, reusable, and extremely easy to write and maintain.

</comment><comment><USER59> I really hate this style.

I think the solution is using elements/components as the means of sharing styles. If you need a slightly different style you extend and modify an existing component. This can be achieved using libraries like `styled-jsx`, `styled-components`. Or hopefully as the shadow-dom spec progresses this will take care of this issue. I also think doing a way with the `scoped` attribute on the style tag was a dumb idea. As it made compartmentalization way easier.

</comment><comment><USER60> First of all I love reading arguments about CSS architecture like this, since even for me doing CSS 19 years now I still haven't found a "goldstandard" - and I think he makes good points.

However, I would be more inclined to use his utility classes as one layer in an ITCSS architecture and then have component styles that inherit from them, keeping them away from the markup as much as possible, while allowing to use those utility classes in the markup for quick prototyping.

</comment><comment><USER61> > Also, if you find yourself in a situation where you're using the exact same > classes in a bunch of different places, that's probably a DRY problem with > repeated markup, and you should likely consider abstracting that into a > reusable fragment or template so that you can define it in one place and > just include it wherever you need it.

This pretty much resolved my objections towards this approach. I think it makes a lot of sense with react.

</comment><comment><USER62> Another interesting CSS framework taking this approach: UniversalCSS: [https://github.com/marmelab/universal.css](https://github.com/marmelab/universal.css)

A few advantages: self-documented classnames, zero dependencies, classnames are reusable across projects, removes the need for a CSS preprocessor or bundler, no need to switch between HTML and CSS file while developing, etc...

</comment><comment><USER63> This is all really terrible advice and my only conclusion is that you have never actually had to maintain websites that use this approach toward CSS as they grow past being a little one off blog into a large, customer facing, PWA.

With this method of CSS it will take years to consolidate, update and redesign your application. Ask me how I know. :-)

</comment><comment><USER64> In the old days, I was doing CSS by hand for every site I made. It kind of sucked.

Then Bootstrap came out, and the idea of CSS frameworks was a thing. I loved Bootstrap, but so did a lot of other people, and as a result you started seeing Bootstrap everywhere...like when you buy a car and you start seeing everyone else driving one where ever you go.

So I started trying to customize Bootstrap to make it look less like other bootstrap sites by adding custom CSS, which basically _brought me back to where I started_.

In practice it has been much, MUCH easier to work with CSS frameworks that use utility classes, because it makes customization easier. I do think there needs to be an intermediate layer where it's easy to define semantic classes as composites of utility classes. I would think this should be possible in the days of Less, Sass, and precompiled web sites.

</comment><comment><USER65> I tried using Tachyons for a project and it really broke down when I needed to make really custom components.

For instance, one component was a cropping viewport that had to be a set height and width. There really isn't any solution for that other than adding a very specific utility class, or creating a semantic class.

<comment><USER66> I think the point is that Tachyons should be good for 90/95% of the styling you want to apply to the site. I think the creator would be the first to say that if you need something specific which Tachyons can't do you should do that but it doesn't make Tachyons redundant.

Personally, Tachyons still provides me tremendous value even though I sometimes have to write custom classes. I'm also often surprised to find that something that I thought would need a custom class, could be done with Tachyons when I dug a bit deeper.

</comment></comment><comment><USER67> We did this for a project a few years ago and it was alright. In the end we decided against doing it again purely because the DOM became so extreme with one-rule classes that it became a nightmare to read the templates. So much noise.

For building things out and prototyping it was amazing though.

On the plus side our css file was so tiny.

</comment><comment><USER68> Most of the "a lot to love" points are also hit by BEM/SMACSS. In regard to this point:

>You never have to deal with one instance of a thing needing a slightly different style than the other instances, which screws up your reusable classes.

...what I found was that just as often, I'd need a new Atomic class different in a subtle way from existing ones, and this was annoying to implement because

a) it expands the kludge-dictionary of short class names you have to memorize, but often in a way that's too situational for anyone to actually memorize it, meaning the next time someone runs into the same problem they will re-invent the same solution rather than reread the entire list of Atomic classes to see if one exists, and

b) the whole point of Atomic is that I _shouldn 't_ have to be writing CSS, and I was, all the time.

<comment><USER58> Tailwind takes care of this. You just need to define your spacings, colors, typography, and a few other details like borders and shadows, and all the classes you'll need are all there. You can use PurgeCSS to trim down the final CSS size to just the classes you use.

</comment></comment><comment><USER69> I agree somewhat for web _pages_ , but this looks like a maintenance disaster for a web app of any significant size. I will probably turn down any offer to work on a team with a large project that uses this approach, unless fixing it would be part of my job.

For web apps, I contend that _modularity_ ought to be the goal for HTML, JS, _and_ CSS. In the project I'm working on now, each widget/component has its HTML, JS, and CSS together in a single folder. When a widget/component is first loaded, its CSS is added to the DOM. Each component has a unique parent class name, and all its markup and styles are nested under it.

Having cross-cutting styles that are re-used throughout the app sounds decidedly un-modular. Why not re-use components/widgets instead?

</comment><comment><USER70> More fundamentally speaking, I'm wondering what the intrinsic value of CSS is when you compare the work involved in building a UI in web-land and native- land.

I remember once looking up on the proposed alternatives to CSS. One was basically a lisp, or at least the syntax, as far as I recall it. Think of what you could do with that!

However the problem now is that the problem CSS intended to solve can only be considered in terms of CSS itself. I'm curious what other approaches could be taken if we worked entirely from a clean slate. Would it involve changing the DOM? Would it require a separate language? Who knows...

CSS works great for websites but not so much for full-blown apps, where you're programming with a totally different mindset than what the web originally anticipated.

</comment><comment><USER71> Problem is, defining quantity in the class name doesn't work.

.m10 may be fine for desktop but not for mobile.

Then you'll have media queries which define .m10 as margin: 5px or something, which is nuts.

You could go for unspecified .mSmall etc, but in real life, things tend to be more specific and messier, in my experience.

<comment><USER72> In bootstrap 4 you get responsive variants like .m-sm-1 and .m-lg-1. Then you can have class="m-3 m-sm-1" to have different margins for mobile and desktop.

</comment></comment><comment><USER73> _> I think that separation of concerns (i.e., the whole idea that the markup should be completely independent from the styling) is something that has been burned into our brains because of the history of CSS (trying to get people away from using tables, sites like CSS Zen Garden, etc.)_

CSS has come a long way since CSS Zen Garden.

With CSS grid and flex, you can create components with less markup and small amounts of CSS.

The example on the tailwind site [https://tailwindcss.com/docs/what-is- tailwind/](https://tailwindcss.com/docs/what-is-tailwind/) just looks like a steep learning curve to me. I could write that same component with much less HTML and just a few lines of responsive css.

</comment><comment><USER74> I believe this type of CSS works well in projects with no real concept or design - I call it wild-west front-end where you design as you go ending up with no patterns and real identity.

If it's popeprly designed functional CSS would be exaclty what it actually looks like - garbage.

</comment><comment><USER75> Can't you do the same with SCSS and at least keep the DOM clean and have it nest more naturally?

Like include "materialShadow(3)" for a hovering button, but when you want to build a special card thingy you include "card", which than includes the shadow already.

</comment><comment><USER76> Using sketch / photoshop these days gives you "Copy CSS Attributes" functionality for most of the elements, which is basically 50% of your CSS, the rest is layouts ( super easy these days with flex box / grid ), media queries and probably some more.

I agree that Cascading part of the CSS is very troubling, but I don't think functional CSS solves it in an elegant way. Actually I think it's hardly readable and confusing :(

As of the argument that you don't need to write CSS properties anymore, I would suggest using a plugin like Emmet [1].

(1): [https://docs.emmet.io/css-abbreviations/](https://docs.emmet.io/css- abbreviations/)

</comment><comment><USER63> I don't get why people are still defending this method of CSS. When - or, perhaps I should say 'if' \- your webapp has to scale you will realize the enormous amount of problems you've created for yourself using this method of CSS.

</comment><comment><USER77> I'm not particularly good at identifying satire, but this is a joke, right?

I mean, the ONE BEST THING about CSS is its ability to promote consistent styling across a site by creating REUSABLE, NAMED styles that are SEMANTIC and applying them consistently.

Let us run through the author's claimed list of advantages:

> You don't have to write any CSS of your own (which, to me, is fantastic)

This one is an obvious troll.

> You can likely build things faster (obviously non-scientific, but > anecdotally I've seen many people confirm this)

The combination of "likely" and "obviously non-scientific" undermines this claim (and rightly so) in the middle of making it.

> You don't ever have to think about naming things

Again, I presume this is a troll. Naming things is hard _if you care about having meaningful names_. If you don't care, then naming is trivial. This approach eliminates meaningful names so it is hardly a benefit.

> You can tell what something looks like by just reading the markup for it

That one is an actual advantage, and makes me wonder slightly what's going on.

> You don't ever have to worry that changing the styles for one thing will > break something else (which may make visual regression testing irrelevant)

Another obvious troll. If you never reuse anything, you'll never have to worry about a change breaking anything else. Also true if you never change anything. Also completely meaningless.

> You never have to deal with one instance of a thing needing a slightly > different style than the other instances, which screws up your reusable > classes.

True enough... if you never reuse anything, then you never need to worry about the impacts of reuse.

> Your CSS always stays the same size rather than expanding over time

Well, sure! If you move all of the intent out of the CSS file and into longer and more complex style attributes, then the CSS file itself will get shorter (while the length of the CSS file PLUS the style attributes will get longer).

> It's easy to un-apply a style by just removing the class (as opposed to the > traditional cascade where you typically have to override, adding even more > CSS)

This isn't even well-considered. Using a fixed set of single-visual-effect- not-semantic-intent styles will have no effect on the complexity of cascading. Choosing to apply styles only to individual elements and eschew the use of cascading WILL avoid all the complexity of cascading, but the choice to do that is independent.

> Rendering speed performance is supposedly improved (though I have seen no > proof of this)

There is no reason this would be true, and the author isn't even claiming it.

After reading it through, I am beginning to seriously doubt that this was intended as satire. In which case the author is very, VERY wrong. I continue to hope that I am simply missing the joke.

<comment><USER78> Same thoughts as you, and it looks like we both went through the benefits line-by-line with a comment in this thread!

It sounds like the author wants Functional CSS to be the Ultimate CSS Solution™, when in most cases, you can write better CSS and/or stick to a design system and/or plan out and manage your components better.

</comment></comment><comment><USER79> I think, in the end, I'd much rather use JavaScript + React + react-jss for this kind of work. It's actually really nice with material-ui and re-using most options from the theme and/or existing components. yeah, 2/3 of my app come from react-dom and material-ui, but at the same time it's very consistent, easy to inherit from and easier to comprehend.

Web-Components may help someday, but so long as component properties are effectively strings, and hard to pass in from the outside, same for events, it makes it harder to manage discreetly.

</comment><comment><USER80> This "functional CSS" approach is obviously wrong.

It causes repetition that would be avoided by defining a single CSS class (this can and probably should be done inside in the file defining the component), and also prevents making appearance changes outside of the component (e.g. in non-component JavaScript or with a CSS-changing browser extension).

If you want to obfuscate the semantics, then "minimized" class names are a better solution.

If you don't care about repetition, then inline styles are just as good, and actually better since you can for instance use any of the 2^24 sRGB colors.

None of the "downsides" listed in the document are reasonable arguments:

> Inline styles don't respect media queries, which basically rules out > responsive design

"Utility classes" also don't, unless you define one for each possible media query and style (that's > 2^16 possible widths, > 2^16 possible heights, > 2^8 attributes...).

> Inline styles aren't limited to pre-defined options, meaning you can still > end up with 90 different shades of blue

That's a downside, and also CSS has built-in color names.

> Inline styles cause specificity issues, since they trump separate > stylesheets.

Use !important.

> Inline styles don't support print-specific styles.

True I suppose, but nobody cares about printing webpages nowadays, and those who are meticulous enough to care probably aren't choosing between inline styles and utility classes since they are both bad approaches.

> Inline styles can't address pseudo-elements (such as ::before and ::after)

You can just put the content in the HTML itself if you are explicitly specifying the appearance.

> Inline styles can't apply to multiple elements. Utility classes can define > .bg-blue once and have it apply to many things, which leads to shorter > markup and quicker rendering speed.

class="bg-blue" has to be repeated just as much as the equivalent background style...

> Inline styles are a pain to type. Compare class="f-sm bg-blue" to > style="font-size: 10px; background-color: #0000ff;".

You should use IDEs with autocomplete, and then they are going to be easier to type, and most importantly developers already know them and can thus easily read and write them without consulting any documentation or CSS file.

<comment><USER72> > CSS has built-in color names.

You can't be serious can you? Css has what around 150 color names? That is jut not good enough for any serious work.

> Use !important.

Please don't use !important, avoid it as much as possible. It just compounds the issue.

> class="bg-blue" has to be repeated just as much as the equivalent background > style

But the definition of what shade of blue we're using is in only one place. Forget bg-blue and think of theme-blue, theme-blue-highlight, theme-blue-mid and so on. A professional design needs vocabulary.

> You should use IDEs with autocomplete

Do these IDEs help with reading and interpretation?

</comment></comment><comment><USER81> The way people using CSS ties to the way they write markup. I like to think like thinking about Big O; read, insert, delete, update. Database design involves this kind of thinking too. What operation you do most on your data structure (html in this case)

Atomic CSS

What's time complexity for each operation(by human)?

Read: O(sigh)

Insert: O(1)

Delete: O(n)

Update: O(n)

Pre-BEM era CSS

What's time complexity for each operation(by human)?

Read: kinda O(1)

Insert: O(1)

Delete: O(1) without garbage collect (unused css)

Update: kinda O(n^n)

That's a quick thought, maybe your operations are more arbitrary.

Probably when someone introduces new css framework/technique, showing some kind of complexity measurement (if possible) would be good idea?

</comment><comment> mind-blight I've been a semantic CSS proponent for years, but I'm intrigued. CSS puts everything in a global namespace, which is an anti-pattern everywhere else. Most modern approaches have been moving towards limiting the scope of Cascading (CSS Module, Styled Components).

The semantic approach forces you to generalize your HTML up front and leads to over-engineering styles. Plus JS component libraries make refactoring across a project a lot simpler.

</comment><comment><USER82> The everydollar web app used to have a lot of utility classes and it was a nightmare to work on. We've spent a lot of engineering hours cleaning that up. I suppose if you were completely strict about only using utility classes you might get a little farther, but I still wouldn't recommend utility classes. The best idea I've seen is utility SCSS mixins applied behind the scenes to BEM classes or locally scoped css.

</comment><comment><USER83> I moved away from "utility-first" CSS in favor of heavy usage of SASS mixins. If you can modularize your CSS to the degree shown in Tailwind, then you can get the best of both worlds by keeping your class names in BEM while the underlying SASS is primarily composed mixins.

Referencing the OP's example in short:

      #m-5 {
        margin: 20px;
      }
      .card {
        @extend #m-5;
        /* custom styles */
      }

Edit: formatting

</comment><comment><USER84> Has anyone ever maintained an SCSS codebase like this, with all kinds of logic, mixins, deep nesting, and variables? It's a nightmare.

Keep your CSS as absolutely shallow, declarative, and "noun-based" as possible. Stay away from utility classes and "adjective-based" classes. Preferably everything should be within it's own component (React/Vue/Web component/etc.).

</comment><comment><USER85> I'm still a little confused. The wording in the example makes it difficult to figure out which example is really "functional css"

</comment><comment><USER86> Like most things, the best approach lies somewhere in the middle. I've had a lot of success with using component driven CSS (BEM, SMACSS, etc style) in combination with utility classes. The components keep everything consistent and make building pages much faster. The utility classes let you do the inevitable little tweaks without a bunch of one off, weird component modifier classes.

</comment><comment><USER87> After using bootstrap4 i have come to use this approach more often. Its just easy to use d-flex, justify-content- _, p-_ , m-* classes to construct a component.

After reading [https://adamwathan.me/css-utility-classes-and-separation- of-...](https://adamwathan.me/css-utility-classes-and-separation-of-concerns/) i might use it even more!

</comment><comment><USER88> That seems much more procedural than functional. There's nothing functional about "set this element a 5px margin and a light gray text and a darker background and a light gray border" which is quite literally the statement of the first snippet's @class.

Composing .profile-card out of these _could_ be a functional approach, but you're just writing @style via @class.

</comment><comment><USER89> I think producing atomic css classes falls should be done by a computer. [Styletron]([https://github.com/styletron/styletron](https://github.com/styletron/styletron)) and [CSS Blocks]([https://css-blocks.com/](https://css-blocks.com/)) comes to mind.

</comment><comment><USER90> If using React and looking for a similar approach -- check out Rebass and styled-system ([https://github.com/jxnblk/styled- system](https://github.com/jxnblk/styled-system)). Their APIs are a pleasure to work with

</comment><comment><USER91> I'm about to start writing a very simple html page ( think search panel + result table underneath) after having stayed out of html for a few years. What are the current best practices regarding css tools and framework that could make my life easier ?

<comment><USER92> HTML + CSS, pure and simple. Don't overthink. Frameworks like bootstrap were useful back when they started: column layout (and other popular patterns) were hard to achieve, and each browser (and version) had their own quirks to work around.

Today, CSS Grid and Flexbox are easier and more powerful than any framework, and aside from bleeding-edge features the major browsers have converged.

<comment><USER91> thanks, indeed last time i checked (a few years ago), flexbox weren't really widespread. I think i'll stick to that.

</comment></comment></comment><comment><USER93> I use Webflow so I don't have to deal with these types of decisions.

</comment><comment><USER78> The benefits?

> You don't have to write any CSS of your own (which, to me, is fantastic)

This applies to any CSS or UI framework.

> You can likely build things faster (obviously non-scientific, but > anecdotally I've seen many people confirm this)

Yes, this is anecdotal and debatable. At the end of the day, you still have to read the documentation of __this __specific CSS framework.

> You don't ever have to think about naming things

I don't think developers that are creating anything don't ever have to think about naming things. If you're creating something, you have to name it. But yes, you don't have to add that name to your CSS class.

> You can tell what something looks like by just reading the markup for it

You could also tell what something looks like by just reading the CSS for it.

> You don't ever have to worry that changing the styles for one thing will > break something else (which may make visual regression testing irrelevant)

There's a couple other approaches to this like style localization/isolation that the author called "ton of crazy randomly-generated class names". As opposed to the ton of single-purpose utility class names, which is more sane? You could also write stricter CSS selectors (like BEM or your own).

> You never have to deal with one instance of a thing needing a slightly > different style than the other instances, which screws up your reusable > classes.

Sure, as long as if you stick to a framework. If you're building a one-off with no collaboration with other people, then this is easier to pull off with an off-the-shelf CSS/UI framework.

> Your CSS always stays the same size rather than expanding over time

Okay!

> It's easy to un-apply a style by just removing the class (as opposed to the > traditional cascade where you typically have to override, adding even more > CSS)

You could isolate styles that are prone to removal into a single class with regular CSS too. Hate to be the nerd to say this, but the "Cascade" in CSS is what makes it such a versatile interface styling engine.

> Rendering speed performance is supposedly improved (though I have seen no > proof of this)

Once again, anecdotal.

————

Sounds like the author is allergic to reading/writing CSS and wants the markup to be heavily coupled with styling. Also sounds like having a strict framework makes their developer experience happy, which is applicable to any well- designed design system.

There's nothing wrong with any specific CSS methodology or framework, and there's a time and place for every single one of them.

I think I would prefer vanilla CSS with strict rules for one-offs before using something like this, though.

</comment><comment><USER94> I like using functional CSS for utility classes

e.g.

> .mb-1 {margin-bottom: 1rem}

> .text-center {text-align: center;}

> .flex {display:flex;}

But why would you give up the templating win of CSS?

Make a standard button class.

When you want it to have a different (standard) margin, use a utility class on it.

<comment><USER84> >When you want it to have a different (standard) margin, use a utility class on it.

Then when the next PM wants this button to be blue, you make another utility class and end up editing HTML. It's better to just think entirely in terms of components that are independent of any external framework or guideline, which are only responsible for themselves. Everything on your page is a concrete implementation of an abstract component, and in that implementation you can customize all you want. Otherwise you end up with a massive dependency graph between components of various "utility classes" rather than a completely flat hierarchy of components which handle their own dependencies.

<comment><USER33> > Then when the next PM wants this button to be blue, you make another utility > class and end up editing HTML.

So you're suggestion that when the PM wants this button to be blue, you make another component for that button? You haven't changed the problem, or the amount of work, you are just using a different layer to implement it.

<comment><USER84> > You haven't changed the problem, or the amount of work, you are just using a > different layer to implement it.

Changing the layer you're implementing on is the whole point. It's about maintainability and keeping things encapsulated.

Now when someone comes back to look at this button a year later, they're not left wondering why this usage of "Button" is colored blue, and tracking down the utility class. They will know that it's an instance of "BlueButton" and can just edit the component directly.

<comment><USER33> How is a component called BlueButton more informative than <button class="blue">? The information content is _exactly_ the same.

Now, more than likely the component isn't called BlueButton and the CSS class isn't called "blue" but rather both would have a name more semantically appropriate.

</comment></comment></comment></comment></comment><comment><USER95> Found myself in agreement up until the concept of "semantic CSS class names". If you want semantic markup, then CSS is absolutely not the place to implement it IMHO.

<comment><USER96> It doesn't seem to me that the author defends semantic class names

</comment></comment><comment><USER97> I see functional css classes as a better primitive than raw css. Using tacyon's + less, all my classes can be composed from functional classes. Best of both worlds.

</comment><comment><USER98> Today is the day I deleted last atomic class in my project. It was a long journey but it was worth it!

</comment><comment><USER99> Functional CSS reminds me of React and JSX - there are plenty of people who will argue at length what a bad idea it is, having not tried it.

</comment><comment><USER100> i don't see a big difference here to plain inline styles. seems to be very inconvenient

</comment><comment><USER101> Font + colour scheme made this article unreadable.

<comment><USER67> I found the background colour a bit easier on the eyes personally. The font is a bit ugly though.

</comment></comment><comment><USER102> As a native-focused engineer I find it fascinating how web developers always find new ways to make their platform even worse than it already is...

</comment><comment><USER103> [deleted]

<comment><USER104> The second paragraph "Isn't that basically the same thing as inline styles?" discusses exactly that.</comment></comment>