Minid the blog, August 12, 2019:
Summary:
Functional CSS is a new concept and like any new concept, it requires adoption and practice, but it also requires understanding all the situations for which we have been programming inefficiently. Our OOCSS bias is bigger and sometimes it does not let us see the true advantages of working with this recent methodology. In this article I describe some of the arguments in defense of Functional CSS.
I recently had the opportunity to read more articles and forum posts about CSS Utilitarianism or Functional CSS as some might have known it. These articles and comments in general are against this methodology. Not exactly everyone is against it. Most people who’s against this methodology doesn’t understand it completely —and, believe me, I understand them—. They only see the wrong problems as the biggest trade-offs. Basically, for those who are not yet aware of what is being discussed over the last 3 years; there are two recent trends in the frontend development world: those who believe that programming with encoding structural annotations in string names (BEM, object-oriented approach) is the best and those that use the functional form of CSS as a way of development (single-class utility purpose). Both methodologies have their pros and cons, however, when analyzing both, these articles never make a fair analysis of Functional CSS, leaving the impression that the current popular way of writing CSS is the only effective way to do it.
At the time of analyzing and giving judgment on both methodologies in articles, we must recognize these problems of the current web development as the biggest trade-offs to have in mind but that they never do correctly:
- Code recycling is an urban legend.
- They always forget the Technical Debt.
- They never really talk seriously and deeply about performance.
- It is assumed that everyone will know how to build good CSS architectures.
- It is forgotten that people come and go in companies.
- It is forgotten that it is complicated to retake up projects.
- Some believe that it is only a problem of communication between employees.
- There is an absurd fear to increase the HTML size.
It is because of these arguments that Functional CSS has convinced me that it is the correct way, at least for now until the empirical evidence tells me otherwise. Given the volatility that exists on the internet, investing so many hours and personal health in creating “the perfect architecture” makes little sense when you can be explicit in intentions in the same code. Such is the conviction that I have, that I even disagree with the position of Jeffrey Zeldman on this subject, imagine that!. I’ll comment on the points of Jeffrey —whom I admire— and, with whom I have just 2 years of difference of professional experience on the Internet.
Recycling code is an urban legend
In 25 years working as a developer or leading projects as product manager, I have never recycled 100% code or I never saw people recycling code to an interesting level, I repeat it again, I have never seen a significant recycle of code. Do not believe that I have worked on the same project all my life, I have directly participated in more than 100 websites creations and more than 25 on native platforms for smartphones. I want to believe that someone on the Internet made a big project, just touching CSS without changing the whole HTML structure as well as the critics of Functional CSS preach. What I usually see is people starting from scratch all the time. Most devs told me on this matter that “it’s faster to start from scratch than undo countless lines of legacy code”. They may import some parts of the code, but the whole idea of “only develop in CSS” is kinda an urban legend. This bias started when examples such as Zen Garden and preached that CSS was powerful because it allowed you to change the entire appearance without touching the HTML. This bias perdured over the years but nothing could be further from reality: every web project that could be redesigned not only mutated all its HTML code from scratch, but also its CSS code. In my research on CSS I show it: all the internet projects that I researched since 1996 have always made drastic changes, but even more terrifying is knowing that while they maintained a style of development, the code does not stop growing, therefore, affecting the loading, rendering and painting performance of each web document.
CSS Zen Garden was, in my opinion, one of the best experiments on web development to demonstrate the flexibility of development that existed in HTML and CSS, but not to demonstrate that you would never again need to touch up your HTML code whatever the project. In 2003 –when this project was born– the average weight of the CSS files was 6KB. Today (2019) we are at an average of ~500KB, so using the CSS Garden argument card is, in my opinion, wrong. First, because it never adapts to the reality of developments, second because the difference in code size required is higher when new development parameters are taken, based mostly on philosophies such as BEM or others. CSS Garden is a web document, with just 54 CSS classes, against more than 2000 classes that can be found in current projects.
The code recycling argument has failed. No one recycles code as the UCSS detractors preach. No one. Neither Zeldman has done this in his projects and you can check it by going to the internet archive. It will always be an absurd argument, because since we implemented CSS, the argument of not doing everything in HTML has already lost strength. We no longer edit documents as in 1996 or 2001. Today everything is dominated by content generators, JS frameworks, etc. It is no longer a problem, on the contrary, the problem now is to serve things beyond HTML, since it increases the rendering time and total painting of each page.
Site-wide changes can be managed perfectly in the Functional CSS world. Since we edit the templates, we don’t have the feeling that we need to do extra work anymore and we also get the security of site-wide changes are explicit changes that impact our work according to our strategy. In the OOCSS world, you need to understand that changing the contents of one class will impact (or not at all) the entire website, and probably creating more problems. You still can use site-wide CSS rules that can affect everything and that can be managed easy in a separate file, where you can only find “special rules”. This is way better than inspecting 500kb of possible rules.
A methodology that reduces technical debt
Technical debt is a recurrent problem in the world of development and no methodology is safe from it, but we must recognize which methodology are more prone to suffer it and which methodologies are not. How is it possible that there is technical debt in CSS? It is very simple: if all the architecture is relegated to the mental capacity to define semantically of each developer, over time these will create a redundant and slow code, either by the pressure to do new things, or as the lack of definitions, the need of new abstractions, the employees recycle in the company or the change of service providers. From the election of selectors and slow selectors, property overwriting -and repetition thereof- the technical debt ends up affecting everyone.
How is it possible that Functional CSS does not have this problem? It is explicit in context, therefore, we should not think about the context but just apply it. To be clearer with my explanation: if you have to create a new structure in your project, you do not have to think what CSS architecture already created serves the purpose, you do not have to think about new forms of nomenclatures and even more, other variants. Simply build explicitly and functionally on the components of JS and your CSS file will hardly grow, unless you need to radically change each design as the size of the browser screen changes, which would present another type of strategy.
Technical debt is bad, really bad, so much so that in the researched projects I verified that the same amount of horrible done code exists and it is carried for years just because it takes too long to fix both HTML templates and CSS. With Utilitarian CSS this does not happen, since the support is legacy by default; since classes are used with explicit instructions of CSS properties (display--block
, align-items--center
) and not a pack of custom class names as occurs in other projects. UCSS can be written by hand, without the need to use the original framework. While the strictness of its methodology is respected (writing the CSS property name using the original syntax) the support is assured.
About performance and the HTML file size fear
This is the thorn that I always have after reading the comments written by the critics of utilitarianism: they never really talk about performance completely. They only recognize that functional CSS is better because the archives are noticeably smaller, but they do not recognize the rest of the benefits and they mostly shout out the fear of the size of HTML will be bigger, therefore, it’s a big problem. They mostly argue that it has a solution: “write good CSS and it will be smaller”. At one point, UCSS is infinitely superior for these reasons uses:
- Tiny file size factor.
- Faster selectors.
- Fewer selectors and properties.
Increasing a bit the HTML file size using more classes names will not be a big deal or a huge trade-off in performance. When you do this, you will realize your website is way, way faster in any way. First, most of the projects do HTML caching, only few parts of the screens are updated (hello React, Vue) and HTML by default will be always the first resource to download and load. Faster by nature. HTML is the first and most priority resource that is downloaded. The average HTML load is ~52ms against ~600ms of CSS files. If the browser requests more than 6 resources (styles, fonts, images, etc.), STALLED blocking occurs. You can check this on your Chrome inspector. When we request too many TCP packets and when we exceed 6 connections, we reach the limit. This means no file is on the browser loaded. This applies to HTTP 1.0 and 1.1 only. Interestingly, this is what causes the STALLED state, which adds countless milliseconds to the process of loading resources into the browser. If I rely on the articles or comments of the developers that I usually read, I could say that for them the performance happens only by the delivery of CSS resource, in compressed or cached form and not by its loading, processing and painting time. It seems that what matters to them is that the customer downloads a file and now, what happens next is irrelevant, the cache will do magic.
That said, it is not very macabre to think that everything happens by writing a CSS with a beautiful semantic architecture, as Jeffrey Zeldman well mentions, but that does not mean that CSS is the best. Is it better because it is understood among developers or better because it really helps the web page load, render and paint everything faster? If Jeffrey believes that the most important thing is how well written the CSS is then it becomes clear that performance is no longer important among these people, since they assume a readability trade-off by a performance one, that is, that it comes before the ego or the happiness of the developers over the interests of the users.
The harsh reality is that traditional methodologies are never better when it comes to performance. It is enough to note that the OOCSS methodology already repeats CSS properties —increasing the size of the file—by nature, therefore, they are considered anti-performant. I have seen projects with over 1,5 MB of CSS code. This linearly increase the loading time of resources. A 15kb file of UCSS rules is x10 faster in generating CSSOM than a 500kb of rules. They also have by nature the idea of using slow selectors and pseudo-selectors of all kinds: generalists, inherited, attributed. This means that developers are always working in inheritance mode and creating selectors that are slow by default. A functional CSS selector is direct: a class and that’s it. The class .display--none { display: none }
will be way faster than: .header .nav .item span { display: none }
. When our architecture, by nature of the methodology used, already encourages us to write nested or conditional rules, what we are doing is increasing the time it takes to render the page. Every page visited will pay the price to render. And this time is always random because it will be affected by other resources and computer conditions (ex. CPU priorities, memory rewriting).
On the other hand, UCSS starts from the philosophical point of always focusing on performance first, encouraging reuse and when it is no longer possible, extending functionality adding more single purpose clases. This philosophy is pro-user: ensure always offer the smallest and optimized file in terms of rules as well as pro-developer, since it encourages the relegation of architectures using an easy understanding and easy maintenance system, although there are developers who believe they would never understand a site made with functional CSS.
On the semantics of the classes
Most assume that everyone —sooner or later— will know how to build good CSS architectures; including choosing the right names for each component. The problem with this argument is that it estimates that the developer or the development team will be the same for a long period of time and that they will do it consciously every time without making mistakes in the process, but the reality dictates the opposite: employee turnover is immense. Search studies on Internet and get scared with these incredible numbers: like “44% of employees say they would consider taking a job with a different company for a raise of 20% or less” or “65% of employees are confident they can find a better position that pays more”. The employee turnover and retention is a hot topic, specially on IT. So much so that many people are likely to change projects, companies, suppliers and, consequently, the essence of the original architecture will be lost for sure when new additions get into the company. They will look at the code and scratch their heads with countless lines of CSS and HTML that has to be learnt in order to understand the architecture. Most of them will refactor it to their vision of CSS architecture and a lot of them will just add their own architecture creating multiples architectures in the same CSS file. This is so common that in some big projects you can see 3 o 4 styles of coding. Let me know how that can be superior to Functional CSS and a benefit for the customer.
Of course, you can argue that everything can be solved by writing “a well done style guide”. Documentation about CSS in a company is kinda an urban legend too. The style guides are something so unusual to find that, when I run into some kind of document that explains the CSS, I find that it has been written with haste, as if it were something unfortunate to do and there was no choice. In 25 years experience working in projects I have never found well maintained documents. Rather, it was always not finding documents at all. Landing at a project already involves wasting a lot of time understanding how the architecture was made and how classes can be taken advantage in our development tasks. The existence of a style guide does not imply that the architecture will be respected or that there is no abuse in the code. Guides without someone who enforce it are plainly useless. They are like speed signals in the roads while cruising in the middle of nowhere: people don’t even respect them.
It is much easier if you have to change something in UCSS: one opens the JS module, HTML whatever you want, and right there you make your changes by reading the explicit CSS, as if it were inline CSS but with the power of the classes. You don’t have to think about class nomenclatures, you don’t have to think about dependencies, you just have to apply the context and it is explicit.
Is not about team communication either
25 years ago there was no code review concept in web development. We simply uploaded the hot changes to the servers and then, when it was too late, we made the relevant arrangements. Today we have another type of workflow, full of tools that do hundreds of tasks automatically and above that we have code reviews. If in your company you do not do code review, you may be alone or you are already in a big hurry.
Today, communication between teams is more obvious and direct. We have Slack channels, Git, sprint meetings, etc. The problem isn’t to dispose of means for communication but more to reach an agreement quickly and efficiently. It is difficult to agree on what class names to use, re-use, modify, etc. The list of issues goes on until you fall asleep with this matter. That is why the functional programming in CSS is more explicit and removes all types of friction when composing a component. One does not have to meet or ask work buddies what class name to use, or what modifiers would accomplish the job or read outdated and poorly written style guidelines, no, you directly write the necessary CSS classes to achieve the design and that’s it.
There is no more mystery. There are no worries of the kind of “but, will I have broken something elsewhere in the site by modifying this?”. All these things speed up the development and the way in which the employees work, taking away a lot of stress from reviewing and checking that what they are doing cannot break something already done by another or increasing the speed or technical debt of the product.
It is forgotten that it is complicated to retake up projects
Sometimes one sins naively in believing that we will always remember all the code we’ve made. It always happens because the security of making our own code biases us with the idea that in the future, I can open this project and continue working as if it were done today. The reality in my career has been the opposite and when I talk with students about this subject, I have also concluded that retaking architectures made by us is not always a guarantee that we can understand it instantly, specially on those projects that weren’t touched for long periods of time.
There is the possibility of having a better idea, but not a complete idea of what has been done. We can remember and guess things because we always use the same names and some structures we repeat until we are fed up, but then there are other more specific cases and that is where we begin to suffer our own creation. Recently I have rewritten a large personal project, made with BEM to UCSS and it has been funny to realize how lost one is and the mistakes one finds even when reading old code. The original file, without compression was 42,9Kb and the final UCSS file ended up being only 12,6KB. Things like “I would have done this differently” are repeated every 20 minutes of code analysis. Sometimes you even grab your hair when you realize how complicated it was when you coded something, that’s why for me, resuming projects made with UCSS are no longer a problem because what I need to touch is there, at hand and easy to understand. The architecture is abstracted from the CSS therefore, I do not worry more about relearning how I made the grid in a project, but in applying the relevant changes in the place they touch. I can come back 2 months later to that personal project I’ve been porting to UCSS and feel like I was coding it today.
Why is it possible to work with Functional CSS
Some people I have read on Hacker News and on Twitter have expressed their concerns when doing projects with functional CSS. Their concerns are based on the comfort of development, the complexity of the project (can I do X with functional CSS?), speed, learning curve, etc. All this is solved by doing a small personal project and seeing the results and then escalate to bigger things. Maybe the first times you will feel awkward but after you tasted the sweet side of Functional CSS I tell you: you will never want to look back.
In my case, I have reduced at least 3/4 the amount of time used to build and deliver the product thanks to CSS programming. In terms of complexity, it is where I have noticed most profit: I no longer think about architecture but what properties my component needs to look 100% like the design they have given me. The speed of composition using one-use classes is fast, way faster. It is clear that each person has a different speed but in general you will notice a significant increase in working speed once you get used.
Like all methodologies, it simply requires you to practice it until it becomes the default option in your workflow. It will take you less time to assume how to code with UCSS than understating the proper way to doing CSS architecture for your projects.