<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ atomic css - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ atomic css - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 25 May 2026 22:37:44 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/atomic-css/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How Atomic CSS and Functional Programming Are Related ]]>
                </title>
                <description>
                    <![CDATA[ Hello, friends! My name is Ramazan, and I'm a front-end developer and enthusiast who loves looking at familiar things in web development from new perspectives. You might have heard of functional progr ]]>
                </description>
                <link>https://www.freecodecamp.org/news/atomic-and-functional-css/</link>
                <guid isPermaLink="false">69bc348fb238fd45a320a2f7</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ layout ]]>
                    </category>
                
                    <category>
                        <![CDATA[ atomic css ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mlut ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Tailwind CSS ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ramazan Maksyutov ]]>
                </dc:creator>
                <pubDate>Thu, 19 Mar 2026 17:38:23 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/64d0d72a-075e-42a9-b0fb-ca577f950999.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Hello, friends!</p>
<p>My name is Ramazan, and I'm a front-end developer and enthusiast who loves looking at familiar things in web development from new perspectives.</p>
<p>You might have heard of functional programming (FP). It's a paradigm characterised by the use of pure functions and the preservation of data immutability. There are even languages in which FP principles prevail, like Haskell, OCaml, and Elixir. Other languages like JavaScript, Python, and C++ also support this approach, although they're not limited to it.</p>
<p>But an attentive reader will look at the title and ask: "Functional programming is fine. But what does Atomic CSS have to do with it?" I'll answer that now!</p>
<p>The thing is, back when the atomic approach first appeared, it had another name: Functional CSS. Some people still use it quite often today to avoid confusion with other terms with the same <a href="https://css-tricks.com/the-atomics/">name</a>. But why is this approach to writing CSS called functional?</p>
<p>That's the question I'll try to answer in this article. First, I'll describe the basic principles of FP. Then, I'll talk about the basics of Atomic CSS (which I'll refer to here as ACSS), drawing analogies with functional programming. I'll also try to use simple examples to show what problems you can solve by applying Atomic CSS to styling.</p>
<p>When preparing the materials for this article, I relied a lot on <a href="https://www.youtube.com/watch?v=7g0BHu0kWXo">this tutorial</a> on FP and <a href="https://www.youtube.com/watch?v=uHVqbCPnOwU">this one</a> on Functional CSS.</p>
<p>Well, let's get started!</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>To follow along with this article, all you need is a basic understanding of HTML, CSS, and JavaScript. There are also some examples where we'll use the Atomic CSS framework <a href="https://mlut.style/">mlut</a>, but you don't have to know its syntax because I've provided the text with the equivalent CSS styles.</p>
<h2 id="heading-what-well-cover">What We'll Cover:</h2>
<ol>
<li><p><a href="#heading-the-basic-principles-of-functional-programming">The Basic Principles of Functional Programming</a></p>
<ul>
<li><p><a href="#heading-pure-functions">Pure Functions</a></p>
</li>
<li><p><a href="#heading-immutability">Immutability</a></p>
</li>
<li><p><a href="#heading-function-composition">Function Composition</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-how-the-principles-of-fp-meet-their-incarnation-in-atomic-css">How the Principles of FP Meet Their Incarnation in Atomic CSS</a></p>
<ul>
<li><p><a href="#heading-purity">Purity</a></p>
</li>
<li><p><a href="#heading-immutability-in-acss">Immutability in ACSS</a></p>
</li>
<li><p><a href="#heading-composition">Composition</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-the-basic-principles-of-functional-programming">The Basic Principles of Functional Programming</h2>
<p>Functional programming is a broad field that has been the subject of numerous complex articles and an entire scientific <a href="https://www.cambridge.org/core/journals/journal-of-functional-programming">journal</a>. So in my article, I'll focus on exploring only the basic principles of FP and drawing analogies with them in Atomic CSS.</p>
<p>This approach is based on the idea that all the actions we need to perform in a program should be done by calling certain functions and their compositions.</p>
<p>Let me outline the main concepts I'll use to explain the core idea of this approach:</p>
<ol>
<li><p>Pure functions</p>
</li>
<li><p>Immutability</p>
</li>
<li><p>Function composition</p>
</li>
</ol>
<h3 id="heading-pure-functions">Pure Functions</h3>
<p>A function is called pure if it:</p>
<ul>
<li><p>returns the same value for the same input parameters;</p>
</li>
<li><p>has no side effects (changes to external values or entities).</p>
</li>
</ul>
<p>Here are a couple of examples to illustrate this:</p>
<pre><code class="language-javascript">let c = 10;
let s = 0;

// Pure function
function pureSum(a,b) {
  return a + b
}

// Impure function
function notPureSum (a) {
  s = a + c
  return s
}
</code></pre>
<p>The first function is pure because if we enter the same arguments, we'll get the same result. Also, this function doesn't change any global variables and doesn't mutate objects.</p>
<p>The second function doesn't meet the concept of purity on both points. It changes the external variable <code>s</code> and uses another external variable <code>c</code> for calculations, which can change.</p>
<p>Pure functions allow you to write more predictable code. An application can grow and a function with an implicit parameter that can change over time can lead to great difficulties in debugging and maintaining the codebase.</p>
<h3 id="heading-immutability">Immutability</h3>
<p>Immutability is a principle which states that data objects shouldn't change after they're created. To make changes to data, you need to create a new instance of it and then work with that new copy.</p>
<p>At first glance, it may seem that this approach limits flexibility in the development process and reduces the speed of the program. But in reality, if the language or runtime has optimisations for immutable data, adhering to this principle helps you avoid many errors and use parallel calculations.</p>
<p>Here's a fairly simple example: let's take a React component that renders a task in a to-do list. The state of the task is described by an object. And in order for React to correctly redraw the state of the task component when the user changes something in it, it's necessary to pass as the new state not the mutated old object, but a new instance of the object with the current state. Here is the example where an immutable object is used for the state of the to-do:</p>
<pre><code class="language-JS">import { useState } from "react";

function TodoItem() {
  const [todo, setTodo] = useState({
    text: "Write article",
    done: false
  });

  const toggleDone = () =&gt; {
    setTodo({
      ...todo,
      done: !todo.done
    });
  };

  return (
    &lt;div&gt;
      &lt;span&gt;
        {todo.text} — {todo.done ? "✅" : "❌"}
      &lt;/span&gt;
      &lt;button onClick={toggleDone}&gt;
        Toggle
      &lt;/button&gt;
    &lt;/div&gt;
  );
}

export default TodoItem;
</code></pre>
<p>Here we'll see that clicking on the button will lead to changes in the state of the to-do and will cause re-rendering of the component. But we could define the function <code>toggleDone()</code> in a different way using mutations of the object:</p>
<pre><code class="language-JS">const toggleDone = () =&gt; {
  todo.done = !todo.done;
  setTodo(todo);
};
</code></pre>
<p>With such an event handler, the effect will not work because the link to the object is still the same, even though the object itself was mutated.</p>
<h3 id="heading-function-composition">Function Composition</h3>
<p>Function composition involves using the result of one function as an argument for another function. Here's an example of a program that capitalises the first letter of each word:</p>
<pre><code class="language-javascript">function compose(f1, f2) {
  return function (str) {
    return f1(f2(str));
  }
}

function makeFirstCapital(str) {
  return str.charAt(0).toUpperCase() + str.slice(1);
}

function upperEveryFirst(str) {
  return str.split(' ').map(makeFirstCapital).join(' ');
}

function lower(str) {
  return str.toLowerCase();
}

const capitalize = compose(upperEveryFirst, lower);
const string = 'this sTring should be Capitalized'

console.log(capitalize(string)) // 'This String Should Be Capitalized'
</code></pre>
<p>Here, we have defined the function <code>compose(f1, f2)</code>, which returns the composition of the functions passed to it in arguments. Next, we use this function to create the function <code>capitalise()</code>, which will capitalise only the first letters of words by composing the functions <code>lower()</code> and <code>upperEveryFirst()</code>. The first one is executed first and returns a string with all lowercase letters to the second function as an argument. The second function capitalises the first letter of each word.</p>
<p>In large projects and when complex calculations are required, such compositions can be larger, and the logic in them can be much richer. In such cases, this approach to calculations helps break down very large transformations into a series of relatively simple and compact functions that are applied one after the other. This makes it easier to develop, refactor, and debug code.</p>
<h2 id="heading-how-the-principles-of-fp-meet-their-incarnation-in-atomic-css">How the Principles of FP Meet Their Incarnation in Atomic CSS</h2>
<p>Now that we know a little about functional programming, let's try to answer the question: ‘What does Atomic CSS have to do with it?’ Let's draw an analogy between these approaches at the level of the principles described above.</p>
<h3 id="heading-what-is-atomic-css">What is Atomic CSS?</h3>
<p>But first, let's take a moment to explain what Atomic CSS is. It's a methodology of styling layouts in which we use small Atomic CSS rules, each of which performs a single action. These classes are called utilities. They usually apply one CSS property, but not necessarily just one.</p>
<p>For example, in the mlut framework, the <code>Bgc-red</code> utility corresponds to the <code>background-colour: red</code> property, and the <code>-Sz50p</code> utility corresponds to two properties at once: <code>width: 50%</code> and <code>height: 50%</code>.</p>
<p>Modern Atomic CSS frameworks, such as mlut and Tailwind, use a so-called JIT engine. This is a component that generates CSS based only on the utilities you used in your markup.</p>
<h3 id="heading-purity">Purity</h3>
<p>Purity in CSS is determined by which selectors, or more specifically, classes, are used to style elements. In clean CSS, the behaviour of an element should be determined solely by the classes that are attached to it in the <code>class</code> attribute. This means that, ideally, a stylesheet should not contain selectors such as <code>section</code> or <code>div &gt; ul</code>.</p>
<p>Firstly, they set too general rules, which are likely to be broken or supplemented in one part of the project or another. So when we style specific elements, we'll have to constantly keep these styles in mind in order to understand how to achieve the necessary styling without spoiling anything.</p>
<p>Secondly, the purity of CSS for each specific element is violated. Let's say we have the following markup:</p>
<pre><code class="language-html">&lt;button class="greeting"&gt;Hello!&lt;/button&gt;
&lt;div class="wrapper"&gt;
  &lt;button class="greeting"&gt;Hello!&lt;/button&gt;
&lt;/div&gt;
</code></pre>
<p>With the CSS styles below:</p>
<pre><code class="language-CSS">.wrapper &gt; .greeting {
  background-color: green;
}
.greeting {
  background-color: red;
}
</code></pre>
<p>As a result, we get that the first button is red, and the nested one is green. It seems pretty harmless in this simple case, but it will cause inconvenience when the project structure grows significantly.</p>
<p>Here we see that the result of the <code>.greeting</code> class's custom styles depends on where the corresponding element is located. This is similar to a function that produces different results for the same input data depending on where it's called.</p>
<p>Atomic CSS allows you to avoid this effect. In this approach, in most cases, styles are applied only to those elements for which the corresponding classes are specified. If you need to make several identical elements, the same utility is specified in the <code>class</code> attribute of each such element.</p>
<p>A similar example can be rewritten in mlut like this:</p>
<pre><code class="language-HTML">&lt;button class="Bgc-red"&gt;Hello!&lt;/button&gt;
&lt;div&gt;
  &lt;button class="Bgc-green"&gt;Hello!&lt;/button&gt;
&lt;/div&gt;
</code></pre>
<p>And JIT-engine will generate the following styles:</p>
<pre><code class="language-CSS">.Bgc-red {
  background-color: red;
}

.Bgc-green {
  background-color: green;
}
</code></pre>
<p>Here we can see that the styles of elements in this approach will depend only on the classes assigned to them.</p>
<p>It's worth noting here that the mlut syntax allows you to do things that deviate from the strict concept of CSS purity. Sometimes this is necessary to create relatively more complex effects.</p>
<p>Let's say we want to implement a card that changes the background colour of the button inside it when hovered. Then we would need to write the following in mlut:</p>
<pre><code class="language-html">&lt;div class="-Ctx"&gt;
  &lt;button class="^:h_Bgc-red"&gt;Greeting&lt;/button&gt;
&lt;/div&gt;
</code></pre>
<p>CSS:</p>
<pre><code class="language-css">.-Ctx:hover .\^\:h_Bgc-red {
  background-color: red;
}
</code></pre>
<h3 id="heading-immutability-in-acss">Immutability in ACSS</h3>
<p>By CSS immutability, I mean that element styles are not rewritten. Immutability in ACSS means that utilities do not typically mutate each other.</p>
<p>For example, in BEM (Block Element Modifier), the main styles are set by a block or element, and a modifier mutates these styles. In other approaches that use combined selectors, such mutations occur more often and less explicitly.</p>
<p>Let me give you a simple example. Suppose we have a product card that can be in its default state or in a highlighted state. In BEM it would look like this:</p>
<pre><code class="language-html">&lt;div class="product-card"&gt;Card 1&lt;/div&gt;
&lt;div class="product-card product-card--selected"&gt;Card 2&lt;/div&gt;
&lt;div class="product-card"&gt;Card 3&lt;/div&gt;
</code></pre>
<pre><code class="language-css">.product-card {
  background-color: red;
  padding: 5px;
}

.product-card--selected {
  background-color: green;
}
</code></pre>
<p>In this example, we see that the <code>product-card</code> class sets the default background colour of the card to red. And in order to somehow mark the selected card with a different background colour we have to add a modifier class that changes the colour from red to green. It does this by rewriting the <code>background-color</code> property, that is by mutating the block styles.</p>
<p>In the Atomic CSS approach, this problem is solved because utilities allow you to set CSS properties independently of each other and apply modifications without resorting to mutation.</p>
<p>Here's what this example would look like if you used mlut:</p>
<pre><code class="language-html">&lt;div class="P5 Bgc-red"&gt;Card 1&lt;/div&gt;
&lt;div class="P5 Bgc-green"&gt;Card 2&lt;/div&gt;
&lt;div class="P5 Bgc-red"&gt;Card 3&lt;/div&gt;
</code></pre>
<pre><code class="language-css">.P5 {
  padding: 5px;
}

.Bgc-red {
  background-color: red;
}

.Bgc-green {
  background-color: green;
}
</code></pre>
<h3 id="heading-composition">Composition</h3>
<p>Functional programming makes extensive use of function composition. In Atomic CSS, function composition is analogous to utility composition when styling elements. Just as in FP we obtain complex behaviour through the sequential application of a set of simple functions, so in ACSS we can obtain non-trivial styling through a set of simple utilities.</p>
<p>As an example, I'll show a simple smiley face made using only Atomic CSS:</p>
<pre><code class="language-html">&lt;div class="-Sz150 Bgc-yellow Bdrd100p M-a Ps"&gt;
  &lt;div class="-Sz20p Bgc-gray Bdrd100p Ps-a T30p L20p"&gt;&lt;/div&gt;
  &lt;div class="-Sz20p Bgc-gray Bdrd100p Ps-a T30p R20p"&gt;&lt;/div&gt;
  &lt;div class="W50p H40p Bdb5;s;gray Bdrd100p Ps-a T40p L25p"&gt;&lt;/div&gt;
&lt;/div&gt;
</code></pre>
<pre><code class="language-css">.-Sz150 {
  width: 150px;
  height: 150px;
}

.Bgc-yellow {
  background-color: yellow;
}

.Bdrd100p {
  border-radius: 100%;
}

.M-a {
  margin: auto;
}

.Ps {
  position: relative;
}

.-Sz20p {
  width: 20%;
  height: 20%;
}

.Bgc-gray {
  background-color: gray;
}

.Ps-a {
  position: absolute;
}

.T30p {
  top: 30%;
}

.L20p {
  left: 20%;
}

.R20p {
  right: 20%;
}

.W50p {
  width: 50%;
}

.H40p {
  height: 40%;
}

.Bdb5;s;gray {
  border-bottom: 5px solid gray;
}

.T40p {
  top: 40%;
}

.L25p {
  left: 25%;
}
</code></pre>
<p>This is how our result will look:</p>
<img src="https://cdn.hashnode.com/uploads/covers/69844106d7e8f3ad9f2dd000/de19a0ca-af4e-45f4-8a90-1a0f55db7950.png" alt="Smiley face" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>Thus, by applying the utilities one after another, we even made some small CSS art.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>To sum up, I will say that Atomic CSS truly embodies the basic principles of functional programming. Of course, not literally – but in the sense that is relevant for front-end developers and layout designers.</p>
<p>I would be happy to hear your additions and objections – it'll be interesting to read and think about them.</p>
<p>Finally, I would like to say: look at familiar things with a fresh perspective. And, as usual, I wish you success on your exciting journey of front-end development!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ In Defense of Utility-First CSS ]]>
                </title>
                <description>
                    <![CDATA[ By Sarah Dayan “Favor composition over inheritance”. This piece of wisdom from Design Patterns, one of the most influential software engineering books, is the foundation of utility-first CSS. It also shares many principles with functional programming... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/in-defense-of-utility-first-css-4f406acee6fb/</link>
                <guid isPermaLink="false">66c357f1e9895571912a0cbe</guid>
                
                    <category>
                        <![CDATA[ atomic css ]]>
                    </category>
                
                    <category>
                        <![CDATA[ bem ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Sass ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Utility First ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sat, 27 Jan 2018 01:13:30 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*nHfoojHD3eS-ggpdB6zNJw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Sarah Dayan</p>
<p><strong><em>“Favor composition over inheritance”</em></strong>.</p>
<p>This piece of wisdom from <a target="_blank" href="https://en.wikipedia.org/wiki/Design_Patterns"><em>Design Patterns</em></a>, one of the most influential software engineering books, is the foundation of <strong>utility-first CSS</strong>. It also shares many principles with <strong>functional programming</strong>: immutability, composability, predictability, and avoidance of side-effects. The goal behind all those fancy terms is to write code that’s <strong>easier to maintain and to scale</strong>.</p>
<p>Despite its growing popularity, utility-first CSS still hasn’t convinced everyone. While some <a target="_blank" href="http://jon.gold/2015/07/functional-css">praise it</a>, others have been <a target="_blank" href="http://www.zeldman.com/2017/01/03/kiss-my-classname">vividly critical</a> about such a practice. <strong>I used to be in the latter group</strong>. I was a BEM fan, sold to an approach I adopted for its advantages and ended up rooting for it like we do for a sports team. I rejected utility-first because it implied that my beloved and familiar approach wasn’t good anymore.</p>
<p>Since then, I’ve dived <em>a lot</em> deeper into the topic. I studied design patterns and functional programming. This allowed me to <strong>radically revise my judgment</strong>.</p>
<p><a target="_blank" href="https://css-tricks.com/growing-popularity-atomic-css/">CSS Tricks</a> and <a target="_blank" href="https://adamwathan.me/css-utility-classes-and-separation-of-concerns">Adam Wathan</a> have done a brilliant job at taking us on a journey from “regular” CSS to utility-first, and explaining the “why” behind it. Rather than paraphrasing, I’ll focus on <strong>the recurring criticism of utility-first</strong> and debunk common misconceptions.</p>
<h3 id="heading-might-as-well-use-inline-styles">“Might as well use inline styles”</h3>
<p>People often compare utility-first CSS to applying CSS rules to HTML nodes through the <code>style</code> attribute. This way of styling is unanimously considered a bad practice, and we have since moved on to separate stylesheets and class abstractions.</p>
<p><strong>Utility-first CSS is no different</strong>. All styles are defined and maintained separately. This allows code reuse, usage of pseudo-classes, pseudo-elements, pre-processors, and browser caching.</p>
<p>Yet, atomic CSS detractors hurriedly associate it to inline styles. Atomic classes are small, they often have only one rule, and they’re named in a <em>functional</em> way instead of being <em>semantic</em>.</p>
<p>All that being said, just because it <em>looks</em> the same doesn’t mean it <em>is</em> the same. Understanding how both practices differ is key to grasping the benefits of utility-first.</p>
<p><strong>Inline styles allow you to do anything you want</strong>. You don’t have to follow any pre-existing definition. You’re re-writing everything from the ground-up every time you style a new HTML node. Similar elements end up with duplicate code, which makes the page unnecessarily heavier. If you’re not careful, it’s easy to ignore pre-existing solutions and reinvent the wheel every time.</p>
<pre><code>&lt;h2 style=<span class="hljs-string">"font-size: 16px; font-weight: bold; color: purple"</span>&gt;Stranger Things&lt;;<span class="hljs-regexp">/h2&amp;gt;&lt;p style="font-size: 13px; font-style: italic"&gt;Stranger Things is an American science fiction-horror web television...&lt;/</span>p&gt;<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"font-size: 16px; font-weight: bold; color: purple"</span>&gt;</span>;Game of Thrones<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"font-size: 13px; font-style: italic"</span>&gt;</span>Game of Thrones is an American fantasy drama television...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
</code></pre><p><em>Unnecessarily verbose, heavier file size, multiple sources of truth for a single design concept.</em></p>
<pre><code>&lt;button style=<span class="hljs-string">"padding: 5px 8px; font-size: 13px"</span>&gt;Button&lt;<span class="hljs-regexp">/button&gt;&lt;button style="padding: 0 8px; font-size: 13px; line-height: 23px"&gt;Button&lt;/</span>button&gt;<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"display: flex; padding: 0 8px; font-size: 13px; height: 23px; align-items: center"</span>&gt;</span>Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
</code></pre><p><em>Three attempts at solving the same problem. This is easily induced by the absence of a single source of truth, and likely to cause visual inconsistencies.</em></p>
<p><strong>Utility classes expose a well-defined API that you can use to compose more complex components</strong>. You’re not re-writing styles; instead, you’re relying on classes that define styles and behaviors once and for all.</p>
<pre><code><span class="hljs-comment">// HTML</span>
</code></pre><pre><code>&lt;h2 <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"font-16 font-bold font-purple"</span>&gt;Stranger Things&lt;<span class="hljs-regexp">/h2&gt;&lt;p class="font-13 font-italic"&gt;Stranger Things is an American science fiction-horror web television...&lt;/</span>p&gt;<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"font-16 font-bold font-purple"</span>&gt;</span>Game of Thrones<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"font-13 font-italic"</span>&gt;</span>Game of Thrones is an American fantasy drama television...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
</code></pre><pre><code><span class="hljs-comment">// CSS</span>
</code></pre><pre><code><span class="hljs-comment">/* Font sizes */</span>
</code></pre><pre><code>.font<span class="hljs-number">-13</span> { font-size: <span class="hljs-number">13</span>px } .font<span class="hljs-number">-16</span> { font-size: <span class="hljs-number">16</span>px }...
</code></pre><pre><code><span class="hljs-comment">/* Font styles */</span>
</code></pre><pre><code>.font-bold { font-weight: bold }.font-italic { font-style: italic }...
</code></pre><pre><code><span class="hljs-comment">/* Font colors */</span>
</code></pre><pre><code>.font-purple { <span class="hljs-attr">color</span>: purple }...
</code></pre><p>Using a defined set of existing CSS rules, no matter how atomic, forces you to pick styles from a <strong>limited list</strong>. You’re not granted total freedom like you are with inline styles. You’re maintaining a consistent catalog of <em>allowed</em> styles, and using them to <em>compose</em> larger components.</p>
<p>This approach enforces consistency by limiting the ways you can style elements. Instead of having access to 16+ million colors, you only have access the number of colors defined in your theme.</p>
<p><strong>It also provides a single source of truth.</strong> Instead of re-declaring the same <code>color</code> for each element that uses it, you define it once in a class and use that class wherever you need it. In addition, using separate styling (with atomic classes or not) gives you access to pseudo-classes and pseudo-elements, pre-processors, caching… a whole load of benefits that aren’t available with inline styles.</p>
<p>You may argue that it doesn’t matter if atomic styles are limited: carelessly mixing them may result in inconsistent layouts like with inline styles. But that’s <strong>a human issue, not a technical one</strong>. You get the exact same problem with any approach, and any language for that matter, whether you’re able to scope or not. If you don’t follow the rules, style guides, and best practices that your team put in place, you’re the one to blame. Not the program, not the language, and not the architecture.</p>
<h3 id="heading-it-violates-separation-of-concerns">“It violates separation of concerns”</h3>
<p>One of the biggest arguments against functional CSS is that it goes against separation of concerns. That CSS should strictly be in charge of the styling, and HTML should semantically structure the page. That by using atomic classes and composing components in the HTML, you’re somewhat delegating styling to the HTML instead of doing it in CSS.</p>
<p><strong>This is an extreme, and ultimately warped, vision of what “separation of concerns” means.</strong></p>
<p>A few years ago, I was on a job interview with a front-end developer who told me about his sheer disdain for Bootstrap. According to him, using extra markup to create a grid was a heresy: that’s a job for CSS, and CSS only. HTML should be 100% oblivious to how it’s rendered.</p>
<p>The problem with that kind of thinking is that it’s <strong>deeply impractical</strong>. It raises design principles to a dogmatic level, ignoring concrete use-cases and context. It pushes you to be more concerned about checking all the “good practice” checkboxes than solving actual problems.</p>
<p>Adam Wathan <a target="_blank" href="https://adamwathan.me/css-utility-classes-and-separation-of-concerns">explains it well (see: “Separation of concerns” is a straw man)</a>: when it comes to HTML and CSS, you can’t look at it from a strict “separation of concerns” perspective. <strong>It’s a “which depends on which” relationship</strong>.</p>
<p><strong>Make no mistake:</strong> just because style composition is performed in the HTML <em>document</em> doesn’t mean it’s done <em>in HTML</em>. We’re not using <em>style</em> or <em>align</em> attributes on HTML nodes. We’re assembling pieces that we defined in a proper stylesheet, <em>in CSS</em>. Our HTML becomes a <em>consumer</em> of our CSS “API.” As Vue.js explains it in their <a target="_blank" href="https://vuejs.org/v2/guide/single-file-components.html#What-About-Separation-of-Concerns">documentation</a>, separation of concerns doesn’t equal separation of file types. Your styles can be composed on HTML nodes, <strong>it’s still a CSS job</strong>.</p>
<h3 id="heading-it-bloats-the-html">“It bloats the HTML”</h3>
<p>When people mention code bloat, they usually mean one of two things (or both): code that’s <a target="_blank" href="https://frontstuff.io/in-defense-of-utility-first-css#its-ugly-and-hard-to-read"><strong>hard to read</strong></a>, and a <strong>heavier codebase</strong>.</p>
<p>The complexity of your layout has to exist <em>somewhere</em>. A component-first approach doesn’t remove “bloat,” it only <em>deports</em> it to the stylesheet. Even so, because your larger components reuse the same atomic styles as others, <strong>you inevitably end up with duplicate code</strong>.</p>
<pre><code>$green: #<span class="hljs-number">74</span>b759;
</code></pre><pre><code>.component {  &amp;-title {    <span class="hljs-attr">color</span>: $green;    font-weight: bold;  }}
</code></pre><pre><code>.widget {  &amp;-title {    <span class="hljs-attr">color</span>: $green;    font-style: italic;  }}
</code></pre><pre><code>.footer {  &amp;-links {   <span class="hljs-attr">color</span>: $green;   text-decoration: underline;  }}
</code></pre><p><em>Even with Sass, you get duplicate rules in the source code. <code>@mixin</code> can help, but you still get duplicates in the compiled CSS.</em></p>
<p>Now I know what you’re thinking. We got <code>@extend</code>. That’s an ideal use case for it, right?</p>
<p>Not so fast.</p>
<p><code>@extend</code> may avoid ruleset duplication in the compiled CSS, but the mega comma-separated selector it will generate could end up being <strong>a lot heavier than if you had duplicated the rule</strong>. So much for avoiding bloat.</p>
<p>You’re also concatenating unrelated classes <strong>and moving them all to the top</strong>, where the first <code>@extend</code> takes place. This can quickly result in specificity issues and odd overrides. Not to mention that you can’t <code>@extend</code> an outer class or placeholder from within a media query. So yeah, definitely not a silver bullet.</p>
<p>From a file size standpoint, <strong>you shouldn’t worry about repeated class names in the HTML</strong>. That’s what Gzip is for. The <em>deflate</em> algorithm was <a target="_blank" href="http://www.gzip.org/algorithm.txt">specifically made</a> to handle duplicate strings, so there’s no point in trimming away characters in your HTML. The resulting file size will make <strong>little to no difference</strong> whether you use a few or a lot of classes.</p>
<p>On the other hand, the more a <em>selector</em> is repeated in a stylesheet, <strong>the more work your browser has to do to resolve all styles</strong>. If you have a single <code>.title-green</code> class for a given style, it simply matches all <code>.title-green</code> in the page. But if you have many classes doing the same thing (using <code>@mixin</code>) or similar selectors doing different things (using <code>@extend</code>), the more expensive it will be for the browser to match.</p>
<p>HTML “bloat” doesn’t matter, <strong>but CSS does</strong>. The network and engine don’t care how many classes you have in your HTML, but the way you write your CSS counts. If your decision-making process revolves around performances, make sure you focus your attention on the right things.</p>
<h3 id="heading-bem-is-enough">“BEM is enough”</h3>
<p>OOCSS and all derived methods (SMACSS, BEM, etc.) drastically improved how we handle CSS. Utility-first CSS is an heir of this approach: it, too, defines reusable <em>objects</em>.</p>
<p>The problem with BEM is that it focuses on building components first. Instead of looking for the smallest, unsplittable patterns, you’re building <em>blocks</em> and their child <em>elements</em>. BEM does an excellent job at namespacing and preventing style leaks, but its component-first nature inevitably leads to <a target="_blank" href="http://wiki.c2.com/?PrematureAbstraction">premature abstraction</a>. You make a component for a certain use-case and end up never reusing it (a navbar component, for example).</p>
<p>BEM encourages you to use <em>modifiers</em> to handle component variations. This may seem smart at first, but unfortunately leads up to other problems. You end up creating tons of modifiers you only use once for a specific use-case. Worse: from one component to another, you might end up with similar modifiers, further breaking the <a target="_blank" href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> principle.</p>
<pre><code>.card {  <span class="hljs-attr">background</span>: white;  border: <span class="hljs-number">1</span>px solid grey;  text-align: justify;}
</code></pre><pre><code>.card--left {  text-align: left;}
</code></pre><pre><code>.card--right {  text-align: right;}
</code></pre><pre><code>.tooltip {  <span class="hljs-attr">background</span>: black;  color: white;  text-align: center;}
</code></pre><pre><code><span class="hljs-comment">/* Oops, looks like duplicate rules down there! */</span>
</code></pre><pre><code>.tooltip--left {  text-align: left;}
</code></pre><pre><code>.tooltip--right {  text-align: right;}
</code></pre><p>At scale, components can become hard to change without breaking instances throughout a project. Premature abstraction keeps components from evolving and splitting into independent entities if they need to. Modifiers multiply as an attempt to fix it, resulting in non-reusable variations for unicorn use-cases, and undo band-aids when we realize our component does too much.</p>
<p>BEM is a great attempt at fixing inherent CSS problems, but making it the core CSS approach of your project brings all the problems you meet when favoring inheritance over composition.</p>
<h3 id="heading-its-a-whole-other-language-to-learn-on-top-of-css">“It’s a whole other language to learn on top of CSS”</h3>
<p>This statement can be said of any naming system for any specific project, whatever methodology you pick. Your CSS class names ecosystem is a layer of abstraction on top of pure CSS. Whether you’re using semantic names like <code>.card</code> or functional ones like <code>.bg</code>, new contributors will need to familiarize themselves with what does what and when to use it.</p>
<p>You can’t escape having to use a naming interface between your HTML and CSS, unless you’re willing to describe your exact markup in CSS or write inline styles. Ultimately, functional class names are <a target="_blank" href="https://frontstuff.io/in-defense-of-utility-first-css#its-ugly-and-hard-to-read">easier to understand</a> because they describe the style. You know what they do without having to lookup the actual styles, while semantic names force you to either look at the rendering or browse code.</p>
<h3 id="heading-its-unmaintainable">“It’s unmaintainable”</h3>
<p>When people say utility-first CSS is unmaintainable, they often mention that when something changes in the design, you have to change it everywhere. You have buttons with regular corners and you decide to make them rounded, so you need to add the <code>.rounded-corners</code> utility class on every button in the code. Yet, the whole point of utility-<em>first</em> is that you start composing with utility classes, and then create components when you start identifying repetitive patterns.</p>
<p>A button is an ideal and most obvious candidate for being abstracted into its own component. You might not even need to go through the “utility-first, then component” phase for this case. When it comes to larger components, favoring composition <em>first</em> is the best choice for maintainability. Why? <strong>Because it’s safer to add or remove classes on a specific HTML node</strong> than to add or remove styles in a class that applies on many elements.</p>
<p>Too many times have I been subjected to changing designs, and had to duplicate existing components to make them behave differently because I had no other choice. Even when a designer supplies all designs at the beginning of a project, and even if you do a great job at identifying components before you code, <strong>you can’t predict the future</strong>.</p>
<p>Let’s say initial designs have white cards with an inset box shadow and a little ribbon in the corner.</p>
<pre><code><span class="hljs-comment">// CSS</span>
</code></pre><pre><code>.card {  <span class="hljs-attr">position</span>: relative;  background: white;  padding: <span class="hljs-number">22</span>px;  border: <span class="hljs-number">1</span>px solid lightgrey;  text-align: justify;  border-radius: <span class="hljs-number">5</span>px;  box-shadow: <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">5</span>px <span class="hljs-number">0</span> rgba(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">.2</span>);  overflow: hidden;}
</code></pre><pre><code>.card::after {  <span class="hljs-attr">position</span>: absolute;  top: <span class="hljs-number">-11</span>px;  right: <span class="hljs-number">9</span>px;  display: block;  width: <span class="hljs-number">10</span>px;  height: <span class="hljs-number">50</span>px;  background: red;  transform: rotateZ(<span class="hljs-number">-45</span>deg);  content: <span class="hljs-string">''</span>;}
</code></pre><pre><code><span class="hljs-comment">// HTML</span>
</code></pre><pre><code>&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"card"</span>&gt;...&lt;/div&gt;
</code></pre><p>This solution is simple, semantic, and reusable. You handle everything in CSS and have minimal HTML to write. But suddenly you get new designs for new pages, and they use the card without the ribbon. Now you have to find a way to remove the ribbon for these new cards.</p>
<pre><code>.card-no-ribbon::after {  <span class="hljs-attr">display</span>: none;}
</code></pre><p>Problem is, this class is <em>undoing</em> something that was previously designed. Having to <em>add</em> a class to <em>remove</em> a feature is an anti-pattern: <strong>it’s counter-intuitive and hard to maintain</strong>. When you decide to change how the base class behaves, you need to keep an eye on the undo modifier to make sure it still works.</p>
<p>We now need to add another ribbon to the bottom left.</p>
<pre><code>.card::before,.card::after {  <span class="hljs-comment">/* shared code */</span>}
</code></pre><pre><code>.card::before {  <span class="hljs-attr">top</span>: <span class="hljs-number">-11</span>px;  right: <span class="hljs-number">9</span>px;}
</code></pre><pre><code>.card::after {  <span class="hljs-attr">bottom</span>: <span class="hljs-number">-11</span>px;  left: <span class="hljs-number">9</span>px;}
</code></pre><p>But now we need to update <code>.card-no-ribbon</code>!</p>
<pre><code>.card-no-ribbon::before,.card-no-ribbon::after {  <span class="hljs-attr">display</span>: none;}
</code></pre><p>This, right here, <strong>is the fragile base class anti-pattern in action</strong>. Because your base class was abstracted too soon, is doing too much, and now needs to evolve, you can’t edit it without worrying about possible side-effects. If new people start contributing to the project, those risks multiply by ten.</p>
<p>The only option you have left this stage is to do a refactor: have a nude <code>.card</code> as the base class, and add the ribbons with <code>.card--top-ribbon</code> and <code>.card--bottom-ribbon</code> modifiers. But now you have to edit all the existing <code>.card</code>s in your code that <em>do</em> need to have a ribbon.</p>
<p><strong>Early refactors are a pretty good indicator of unmaintainability</strong>.</p>
<p>You could argue that a smart developer <em>could</em> have seen it coming. That they <em>should</em> have made a naked <code>.card</code> base class and a <code>.card--ribbon</code> modifier, right from the start.</p>
<p><strong>That’s actually making a case <em>in favor</em> of utility-first and composition</strong>.</p>
<p>You’re taking the decision to break down a given design element that you deemed too monolithic, so it’s easier to scale. <strong>That’s a good call.</strong> The more you go, the more you’ll realize this leads to utility-first.</p>
<p>You might think it doesn’t, and that your job is to <em>foresee</em> what is the bare minimum for a given component. But unless you own a crystal bowl, this is a risky assessment. This is also short-sighted. What if parts of your component need to be extended to other components? For example, what if you now need buttons with ribbons? If you duplicate the <code>.card--ribbon</code> class, your code isn’t DRY anymore, which makes it even more unmaintainable. So? Make a mixin and import it into both modifiers? Again, that’s extra work and “wet” code.</p>
<p>The best solution for this use-case is to write a single utility class for the ribbon, and modifiers for sizes and colors if necessary. This allows you to have <strong>a single source of truth</strong> and use the ribbon anywhere you want to. If you need to put ribbons on avatars, panels, unordered lists, modals, you can do it without having to write a single extra line of CSS.</p>
<p><strong>This is the definition of scalability and maintainability</strong>. All you have to do is reuse the available code you wrote <em>proactively</em>, instead of having to tweak existing code <em>reactively</em>.</p>
<pre><code>.ribbon {  <span class="hljs-attr">position</span>: relative;  overflow: hidden;}
</code></pre><pre><code>.ribbon::after {  <span class="hljs-attr">position</span>: absolute;  display: block;  top: <span class="hljs-number">-11</span>px;  right: <span class="hljs-number">9</span>px;  width: <span class="hljs-number">10</span>px;  height: <span class="hljs-number">50</span>px;  background: red;  transform: rotateZ(<span class="hljs-number">-45</span>deg);  content: <span class="hljs-string">''</span>;}
</code></pre><p><em>By breaking down designs into small elements, we write much more reusable code.</em></p>
<p>Calling utility-first CSS “unmaintainable” is absolutely inaccurate. In fact, <strong>it may be the most maintainable and scalable CSS methodology to this day.</strong></p>
<p>You can’t predict the future. This is why you should always favor composition over inheritance. <strong>A good sign of a healthy and scalable codebase is how things go when you need to change it.</strong></p>
<p>If a new change makes you anxious because you might break something, it’s a sign of poor design. But I would go a step further and say that if you need to write new CSS to make an existing component do something that another component already does, your code isn’t as scalable as you think it is.</p>
<p>If you need to reuse behavior that exists somewhere, <strong>you shouldn’t have to write new code</strong>. You should be able to trust and use what you already wrote and go from there. You have one source of truth on which you can rely, instead of two or more slight variations that you must not forget to keep up to date. <strong>This is the definition of maintainability.</strong></p>
<h3 id="heading-its-ugly-and-hard-to-read">“It’s ugly and hard to read”</h3>
<p>Do you remember the uproar when BEM started to become popular? I do. I remember many people who rejected the whole thing because of its syntax. Praising the model, but disgusted with the idea of chaining two underscores or two hyphens.</p>
<p>As humans, it’s in our nature to be easily put off by what we’re not familiar with. Yet, letting subjective cosmetic considerations come in the way of a potentially useful technique is where developers should draw the line. Our job is to <strong>solve problems</strong>. Our main concern should be <strong>the end user</strong>.</p>
<p>Look at the source code of many big projects: most of them have ended up adopting BEM. Chances are not all their front-end developers were sold at the beginning.</p>
<p>Overcoming initial feelings, especially if driven by personal preference, isn’t that hard <strong>when you’re putting the success of a project first</strong>.</p>
<p>Now on the topic of legibility, I get that long strings of classes can be “scary” when you open a file for the first time. This is not an insurmountable task though. More verbose code is a trade-off of composition, but it’s a <strong>much lesser inconvenience than unscalability</strong>.</p>
<p>I don’t use shorthands like <code>.pt-8</code> or <code>.bb-lemon</code> in my own code. I favor full-length class names like <code>.padding-top-8</code> and <code>.border-bottom-lemon</code>, which are much easier to read. Autocomplete solves the problem of having to type long class names, and there are tools you can use to re-hash class names into smaller ones for production. I doubt this will make any significant change to your performances but hey, if it makes you feel good to shave bytes away, knock yourself out ?</p>
<p>Ultimately, the nature of functional class names might actually be <strong>more expressive</strong>. It’s easy for your brain to make a connection between such a class and what’s happening on screen. Even if you don’t get to see how it renders, you can get a pretty good idea of what <code>.hidden</code> or <code>.opacity-6</code> are supposed to do.</p>
<pre><code>&lt;blockquote <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"border-thick-left-red padding-left-medium font-navy"</span>&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>You know how they call a Quarter Pounder with Cheese in Paris?<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>&lt;/blockquote&gt;
</code></pre><p><em>Stylistically speaking, it’s pretty easy to know what’s going on here.</em></p>
<p>Semantic class names don’t convey the same thing. It works for small components like buttons or alerts, which are common enough to be easily recognized. Yet, the bigger and the more complex a component gets, the less obvious it is to know what class name maps to what element on the screen, or what it looks like.</p>
<pre><code>&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"entry"</span>&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"entry-title"</span>&gt;</span>The Shining<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span>  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"widget widget-lead"</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"widget-content"</span>&gt;</span>      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>His breath stopped in a gasp. An almost drowsy terror stole through his veins...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"author"</span>&gt;</span>      <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"author-avatar"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"..."</span>&gt;</span>      <span class="hljs-tag">&lt;<span class="hljs-name">h3</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"author-name"</span>&gt;</span>Stephen King<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Stephen Edwin King (born September 21, 1947) is an American author of horror, supernatural fiction, suspense, science fiction, and fantasy...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn-group"</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>;Website<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>Twitter<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
</code></pre><p><em>Harder to know what class does what without going through the stylesheet.</em></p>
<p>In that way, functional classes are a lot easier to understand than semantic class names. They demand less catching up time and less file-switching. Ultimately, they give you the very bit of information you’re looking for anyways.</p>
<h3 id="heading-its-not-how-you-write-css">“It’s not how you write CSS”</h3>
<p><strong>CSS specificity is a <em>feature</em>, not a bug.</strong> Use it correctly, and it will give you amazing control.</p>
<p>That’s what CSS veterans say when yet another article about the dangers of specificity pops up. And technically <strong>they’re right</strong>: the CSS priority system isn’t an accident. It usually bothers people who don’t master CSS because of the lack of scope. But a language isn’t broken because it doesn’t behave like what you’re used to. Nested CSS rules are like <code>!important</code>: they’re handy, but have been so poorly used for years that we now see it as something to <em>avoid</em>.</p>
<p>Specificity should be used proactively, not reactively. They should be <em>design decisions</em>, not a quick fix when your styles don’t apply. Harry Roberts explains it well in <a target="_blank" href="https://cssguidelin.es/#specificity">CSS Guidelines</a>:</p>
<blockquote>
<p>“The problem with specificity isn’t necessarily that it’s high or low; it’s the fact it is so variant and that it cannot be opted out of: the only way to deal with it is to get progressively more specific”.</p>
</blockquote>
<p>Specificity is a powerful tool, but it needs to be used with uppermost caution and a good long-term vision of the project. Use them wrong, and you’ll feel the pain of having to go back. Keeping specificity low avoids problems altogether: it relies solely on source order, which is <a target="_blank" href="https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture">a lot easier to manage</a>. With atomic CSS, if a style doesn’t apply, fixing it is as simple as adding or removing a class on an HTML node. You don’t have to call your stylesheet’s structure into question, which is a lot easier and safer to manage.</p>
<pre><code><span class="hljs-comment">// CSS</span>
</code></pre><pre><code>.color-navy {  <span class="hljs-attr">color</span>: navy;}
</code></pre><pre><code>.color-red {  <span class="hljs-attr">color</span>: red;}
</code></pre><pre><code><span class="hljs-comment">// HTML</span>
</code></pre><pre><code>&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"color-red color-navy"</span>&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>- Whose motorcycle is this?<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>- It's a chopper baby.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>- Whose chopper is this?<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>- It's Zed's.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>- Who's Zed?<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>- Zed's dead baby, Zed's dead.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>&lt;/div&gt;
</code></pre><p><em>Want the text to be navy? No need to touch the CSS. Simply remove the <code>.color-red</code> class from the encompassing <code>&lt;d</code>iv&gt;. If you need one of the children to be red, then mov<code>e the .col</code>or-red</em> on it.</p>
<blockquote>
<p>“If a feature is sometimes dangerous, and there is a better option, then always use the better option.” — Douglas Crockford</p>
</blockquote>
<p>Using specificity or not isn’t about showing how well you master CSS and how <em>you</em>, unlike others, can keep it under control. It’s about <strong>understanding the advantages and flaws of the features at your disposal</strong>, and making choices in the best interest of the project.</p>
<h3 id="heading-you-end-up-with-plenty-of-unused-css">“You end up with plenty of unused CSS”</h3>
<p>Let’s say you’re using Sass maps to <a target="_blank" href="http://frontstuff.io/generate-all-your-utility-classes-with-sass-maps">generate your utility classes</a>. Colors, font sizes, backgrounds, everything is automatically compiled into proper, ready-to-use CSS. Problem is, if you don’t <em>use</em> everything, you’re left with useless extra bytes in production. This can easily be fixed with <a target="_blank" href="https://github.com/giakki/uncss">UnCSS</a>.</p>
<p>UnCSS is great at dusting off your stylesheets, but it comes with <strong>two caveats</strong>: it only works on HTML files (so, no PHP and no template files) and it only takes into account the JavaScript that’s executed on page load (not classes added on user interactions, for example). If you’re using a language like PHP to render your pages, you can add a job in your deployment workflow that compiles pages into temporary HTML and runs UnCSS on them. For the second issue, you can use the <code>ignore</code> option to list out that are classes added on user interaction.</p>
<p>Now it’s also important to ponder this issue. The cost of unused classes is heavier stylesheets (longer to download) and longer parse time. If you have a lot, and by that I mean a large percentage of your total styles, of unused classes, <strong>this can hurt performances</strong>. If you only have a few here and there, <strong>the impact will be negligible</strong>.</p>
<p>Maintaining your CSS codebase is your job as a developer. No matter what methodology you choose, you have to keep an eye on the project and make sure to remove dead code when things change.</p>
<p><strong>Being careless with that is how you end up with plenty of unused classes, not because you’re generating some of them</strong>.</p>
<p>Need a text color class only for the main color? Make a class for this one only. Need backgrounds for most colors in the theme, yet unsure you’ll use them all right away? Generate the damn classes. They’ll be ready when you need them, you won’t have to maintain them when you add new colors, and the extra code will cost <em>nothing</em>. <strong>This is not where your app’s bottlenecks are</strong>. If you’re having performances issues, there are a million other things to consider before even looking into your CSS.</p>
<h3 id="heading-it-makes-it-hard-to-know-whats-available-to-use">“It makes it hard to know what’s available to use”</h3>
<p>When your CSS codebase is a large collection of small utility classes, reading the source code won’t help you get a good overview of the available styles. But <strong>is it the role of the source code anyway</strong>?</p>
<p>It certainly isn’t. That’s what <strong>style guides</strong> are for.</p>
<p>Exploring source code is <em>far</em> from being enough to get a good understanding of how a full API is designed. This isn’t limited to atomic CSS: OOCSS or BEM projects, even small ones, can reach a level of sophistication which requires at least a <code>README</code>.</p>
<p>Can you imagine having to crawl back in an unminifed version of the master Bootstrap stylesheet every time you don’t remember if this is <code>.col-md-offset-6</code> or <code>.col-offset-md-6</code>? Would anyone new to Bootstrap understand what such a class means without a little literature on how the grid works? Documentation, style guides, and API references are designed to help us make sense of complex systems. Sure, it doesn’t mean documentation should justify poor design and unclear naming conventions, but thinking you should be able to understand an entire project only by reading the source code is pure fantasy.</p>
<p>There are plenty of tools out there to help you generate documentation right from your code. I use <a target="_blank" href="http://warpspire.com/kss/syntax">KSS</a> for most of my projects, but CSS-Tricks shares a <a target="_blank" href="https://css-tricks.com/options-programmatically-documenting-css">list of alternatives</a>. Give it a try!</p>
<h3 id="heading-utility-classes-should-be-used-along-with-components">“Utility classes should be used along with components”</h3>
<p>Yes. Absolutely. That’s precisely why it’s called utility-<em>first</em> and not utility-<em>only</em>.</p>
<p>Utility-first isn’t about ditching components altogether. It means you should start off with utility classes, make the most of them, and only abstract when you see repeating patterns. You’re allowing your project to grow while remaining flexible, and identifying actual components over time, when patterns start to emerge.</p>
<p>It is crucial to understand that a component isn’t <em>just</em> a similar-looking “block” that you <em>can</em> reuse. It’s a pattern that is strongly tied to your specific project. Sure, you’re probably going to use tons of <code>.btn</code> and <code>.modal</code>, so it makes sense to abstract them early on. But are you positive you’re going to ever reuse <code>.testimonial</code>? Or at least reuse it <em>enough</em> to make it worth being a new component? Will it always look like this in every context, or is it specific to the homepage? Keep your options open. It’s a lot easier to later abstract a composite style into a component than to try and undo one.</p>
<h3 id="heading-it-makes-redesigningtheming-a-nightmare">“It makes redesigning/theming a nightmare”</h3>
<p>Because atomic CSS is strongly tied to your design, this can make things more difficult when you have to do a redesign or develop an alternate theme. It’s far from impossible though, and there are a few things you can do to make your utility-first CSS more suited to these kinds of needs.</p>
<p>You can start by keeping class names not too specific. Instead of <code>.margin-bottom-8</code>, you can use a more abstract name like <code>.margin-bottom-xxs</code>. This way you can change the value without making the names invalid.</p>
<p>Another approach would be to create <strong>aliases</strong>. Imagine you’re building an app that has light and dark mode: some colors would change, some others wouldn’t. We don’t want to make all our color utilities contextual: <code>.background-primary</code> and <code>.background-secondary</code> don’t tell us what color is behind the class. You don’t want an entire color system like that. Yet, you could still have color utilities with proper color names (<code>.background-lime</code> or <code>.background-red</code>), and generate aliases for those which might need to change for theming purposes.</p>
<pre><code><span class="hljs-comment">// CSS</span>
</code></pre><pre><code><span class="hljs-comment">/* Backgrounds */</span>
</code></pre><pre><code>.background-lime {  <span class="hljs-attr">background</span>: #cdf2b0;}
</code></pre><pre><code>.background-off-white, .background-light {  <span class="hljs-attr">background</span>: #ebefe8;}
</code></pre><pre><code>.background-dark-grey, .background-dark {  <span class="hljs-attr">background</span>: #<span class="hljs-number">494</span>a4f;}
</code></pre><pre><code><span class="hljs-comment">/* Colors */</span>
</code></pre><pre><code>.color-lime {  <span class="hljs-attr">color</span>: #cdf2b0;}
</code></pre><pre><code>.color-off-white, .color-light {  <span class="hljs-attr">color</span>: #ebefe8;}
</code></pre><pre><code>.color-dark-grey, .color-dark {  <span class="hljs-attr">color</span>: #<span class="hljs-number">494</span>a4f;}
</code></pre><pre><code><span class="hljs-comment">// HTML</span>
</code></pre><pre><code>&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"background-light"</span>&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"color-lime"</span>&gt;</span>Ezekiel 25:17<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span>  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"color-dark"</span>&gt;</span>The path of the righteous man is beset on all sides by the inequities of the selfish and the tyranny of evil men...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>&lt;/div&gt;
</code></pre><p>From here, all you have to do is write a JavaScript function that toggles all <code>.*-light</code> and <code>.*-dark</code> classes. And for elements that don’t need to change, you can use the original color classes.</p>
<p>This method works well, but if you have a lot of classes to switch it may end up hurting performances. DOM manipulations are expensive. You want to reduce them as much as possible if you can. Luckily, there’s a nifty technique involving CSS variables (thanks to Adam Wathan for coming up with it) which makes everything simpler.</p>
<pre><code><span class="hljs-comment">// CSS</span>
</code></pre><pre><code>:root {  --green: #<span class="hljs-number">42</span>f49b;  --off-white: #ebefe8;  --dark-grey: #<span class="hljs-number">494</span>a4f;}
</code></pre><pre><code>.theme-dark {  --background: <span class="hljs-keyword">var</span>(--dark-grey);  --text: <span class="hljs-keyword">var</span>(--off-white);}
</code></pre><pre><code>.theme-light {  --background: <span class="hljs-keyword">var</span>(--off-white);  --text: <span class="hljs-keyword">var</span>(--dark-grey);}
</code></pre><pre><code>.color-lime {  <span class="hljs-attr">color</span>: <span class="hljs-keyword">var</span>(--green);}
</code></pre><pre><code>.color-theme {  <span class="hljs-attr">color</span>: <span class="hljs-keyword">var</span>(--text);}
</code></pre><pre><code>.background-theme {  <span class="hljs-attr">background</span>: <span class="hljs-keyword">var</span>(--background);}
</code></pre><pre><code><span class="hljs-comment">// HTML</span>
</code></pre><pre><code>&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"theme-light"</span>&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"background-theme"</span>&gt;</span>  <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"color-lime"</span>&gt;</span>Ezekiel 25:17<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"color-theme"</span>&gt;</span>The path of the righteous man is beset on all sides by the inequities of the selfish and the tyranny of evil men...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>&lt;/div&gt;
</code></pre><p>We defined colors with CSS variables and assigned different values for each context. Depending on the encompassing class, <a target="_blank" href="https://jsfiddle.net/hurmktbz">all colors will change thanks to ancestor inheritance</a>. If you were to allow theme switching, all you’d have to do is change <code>.theme-light</code> into <code>.theme-dark</code> on the parent <code>&lt;d</code>iv&gt;, and all colors would adapt.</p>
<p>This technique only works if you don’t have to support Internet Explorer and Edge below version 15. Otherwise, go for the first technique and use CSS ancestor inheritance system to avoid having to toggle too many variables. If you have to assign a text color to an entire block, <strong>set it on the parent instead of the children</strong>.</p>
<pre><code><span class="hljs-comment">/* Nope */</span>&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"background-light"</span>&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"color-lime"</span>&gt;</span>Ezekiel 25:17<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span>  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"color-dark"</span>&gt;</span>The path of the righteous man is beset on all sides by the inequities of the selfish and the tyranny of evil men.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"color-dark"</span>&gt;</span>Blessed is he, who in the name of charity and good will, shepherds the weak through the valley of darkness, for he is truly his brother's keeper and the finder of lost children.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"color-dark"</span>&gt;</span>And I will strike down upon thee with great vengeance and furious anger those who would attempt to poison and destroy my brothers.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"color-dark"</span>&gt;</span>And you will know my name is the Lord when I lay my vengeance upon thee.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>&lt;/div&gt;
</code></pre><pre><code><span class="hljs-comment">/* Yes */</span>&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"background-light color-dark"</span>&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"color-lime"</span>&gt;</span>Ezekiel 25:17<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span>  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>The path of the righteous man is beset on all sides by the inequities of the selfish and the tyranny of evil men.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Blessed is he, who in the name of charity and good will, shepherds the weak through the valley of darkness, for he is truly his brother's keeper and the finder of lost children.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>And I will strike down upon thee with great vengeance and furious anger those who would attempt to poison and destroy my brothers.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>And you will know my name is the Lord when I lay my vengeance upon thee.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>&lt;/div&gt;
</code></pre><h3 id="heading-embracing-change-within-reason">Embracing change, within reason</h3>
<p>Having strong opinions is great. Not everything has to be settled by finding a middle ground. But there’s a clear line to draw between <strong>being opinionated</strong> and <strong>being reluctant to change</strong>.</p>
<p>We, as developers, <strong>must be the first to embrace change</strong>. Looking back at my first reaction towards utility-first CSS, I realize how important it is we keep an open mind instead of rushing to pick a side. <strong>It doesn’t matter how experienced <em>we think</em> we are</strong>. Experience is great, but it can also make us believe we already have all we need to make judgment calls and don’t need to dive deeper to understand new concepts.</p>
<p><strong>Software development changes every day</strong>. Our industry is still young, and we’re figuring things out as we go. It doesn’t mean we should throw away the past, and continuously refactor all our projects to keep up with the latest trends. Past knowledge is the foundation of today’s discoveries. But just because something is tried and true, doesn’t mean it’s set in stone. It’s important we approach novelty with critical thinking.</p>
<p>We’ll probably move on from utility-first CSS at some point, like how we got past many things we used to consider the pinnacle of front-end development. In the meantime, let’s try to stay as open-minded as possible, and <strong>do what’s best for the industry, the projects, and the users</strong>.</p>
<p>Want to learn more about utility-first CSS and how to use it in your projects? Go read <a target="_blank" href="https://css-tricks.com/growing-popularity-atomic-css/">On the Growing Popularity of Atomic CSS</a> on CSS Tricks and <a target="_blank" href="https://adamwathan.me/css-utility-classes-and-separation-of-concerns">CSS Utility Classes and “Separation of Concerns”</a> on Adam Wathan’s blog. You can also check out utility-first libraries on this <a target="_blank" href="https://css-tricks.com/need-css-utility-library/">curated list</a> by CSS Tricks.</p>
<p>Originally published at <a target="_blank" href="https://frontstuff.io/in-defense-of-utility-first-css">frontstuff.io</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
