paint-brush
Why Functional CSS Got so Popular?by@tokenvolt
189 reads

Why Functional CSS Got so Popular?

by Oleksandr KhrustalovOctober 23rd, 2024
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Functional CSS is a popular approach in today's web development. A brief history and insights into how it got its popularity.
featured image - Why Functional CSS Got so Popular?
Oleksandr Khrustalov HackerNoon profile picture


There is an annual developer survey called State of CSS which explores which tools developers use to produce CSS code, what are the current industry preferences and sentiments.


Looking at the results of section "CSS frameworks" a Tailwind has been an indisputable leader in satisfaction rankings for consecutive 4 years from 2019 to 2023, meaning it has been so since its initial release in May 2019. No wonder it accumulated usage rankings throughout these 4 years from 6% in 2019 to 50.5% in 2023 making it the 2nd most popular CSS framework after Bootstrap.


I would not call myself a huge fan of Tailwind and to be honest I was a bit skeptical about it for quite some time. But I think I understand the appeal to it. In this article I will try to explore why Tailwind and other utility CSS solutions are so popular and what I think the future holds for it.

But first a little bit of history

Let's get back to 2013 when the first commits to Basscss were made public. While traditional CSS frameworks at the time focused on certain components, like alerts, inputs, modal windows, etc., Basscss took a different approach focusing on abstract non-semantic utilities.


For instance, take a look at Bootstrap. It has alert which is a certain semantic component with a well-defined purpose. There are even more complex components like dropdown and components that combine multiple ones, but there is always semantics in mind. It's almost impossible to reuse the parts of alert component in a dropdown - it doesn't make any sense because they serve different business purposes and therefore their semantics are completely different.


Basscss does not have any of this. Zero components. What it has is a set of simple and pre-defined CSS rules that could be used in any context where this rule is suitable to be applied.


Check this out.


.m0 {
  margin: 0;
}

.p0 {
  padding: 0;
}


Using narrow utility classes aimed to be highly reusable. Consider the following CSS code.


.success {
  background-color: green;
  color: white;
}


You can use .success class only when both `green` background and white text color are required. You would need to create a new class with a different name when only one rule of these two is required. Basscss confronts the semantic CSS approach.


Instead of coming up with a class name and assigning properties for a specific semantic meaning


<style>
  .panel {
    margin: 0;
    padding: 0;
  }
</style>
<div class="panel">This is a panel</div>


you use multiple classes like m0 and p0 mentioned above to achieve the same effect.


<style>
  .m0 {
    margin: 0;
  }

  .p0 {
    padding: 0;
  }
</style>
<div class="m0 p0">This is a panel</div>


Basscss contains shorthands not only for padding and margin, but for typography, borders, positions, colors, etc.


It was a strange approach but it got its fans and its own name called "Atomic CSS" inspiring a lot of other frameworks. One of them was Tachyons which introduced pseudo-classes for :hover, :active, :focused.


In this example zero margin is applied only when an element is hovered.


<div class="ma0:hover">This is a panel</div>


Another framework was ACSS, now known as Atomizer which used even more complex syntax and required a build step.


<div class="M(0)">This is a panel</div>


Inline styles or something more?

At first sight it looks like an inline styling, but it is actually more than that. It is a composition tool giving us an ability to construct different small pieces of software to produce a complete solution. This is exactly what we are getting by using Basscss and other atomic CSS solutions.


To achieve high quality composition one needs to have pieces of software that are

  1. reusable in different semantic contexts
  2. easily combined with each other in an arbitrary way


Going back to the example of .success class let's break it down into 2 classes


.bg-green {
  background-color: green;
}

.color-white {
  color: white;
}


By splitting the .success class we are no longer tied to a certain semantic and we can reuse individual classes in completely different and unrelated to each other contexts combining them with other such classes.

And finally… Tailwind

Of course, Tailwind took inspiration from all of the libraries mentioned above. Composition is the core concept in Tailwind and that’s how developers are expected to reason about it - by composing utility classes forming complex components. It focuses on being easy to use and very friendly to newcomers and developers who are not keen on frontend development.


What Tailwind got right is a good balance between API and functionality and a tooling which has nice defaults being highly-configurable at the same time. But is it actually a sustainable story?

Critics of functional CSS.

There are a lot of critics of utility (functional) CSS. But I would mention only one, which is the strongest one, and that is mixing markup and styling results in having a messy class string in HTML.


<div class="bg-indigo-500 text-white px-4 py-2 rounded-md shadow-md hover:bg-indigo-600 transition duration-200 ease-in-out cursor-pointer flex items-center justify-center">


You might argue that it is a developer’s responsibility to keep it clean, but it is actually quite common to see this. Tailwind does not offer a way to clean the long class strings other than apply directive but even that is discouraged by Adam himself. Here is a quote.


I can say with absolute certainty that if I started Tailwind CSS over from scratch, there would be no `@​apply`


The behavior is outrageously complicated, everyone struggles to build the right mental model of what it's supposed to do, and it encourages bad CSS architecture.


And it makes sense, because it defeats the whole purpose of writing utility CSS in the first place. Why even bother with it if you end up writing a separate semantic class name with a vendor specific keyword? You don’t need a library for that, just write a plain CSS.


Another way to fight it is to use a component based approach with a JavaScript library of your choice (React, Vue, etc.) and use something like tailwind-variants. This is also not a new concept, as it was popularized by styled-system, a Basscss author by the way. It works, and it works great despite introducing an imminent complexity.


But it still leaves critics with the question: Why go through all the hassle when I could just write a CSS class?


For now I will leave this question open. But I’m sure in the future we will see new approaches as CSS standards are constantly evolving.