<?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[ Utility First - 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[ Utility First - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 31 May 2026 05:06:29 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/utility-first/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How I dropped 250KB of dead CSS weight with PurgeCSS ]]>
                </title>
                <description>
                    <![CDATA[ By Sarah Dayan I’m a big advocate for utility-first CSS. After trying several methods over the years, it’s what I’ve found to be the best, most maintainable and scalable way of writing CSS to this day. When my coworker Clément Denoix and I built api-... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-i-dropped-250kb-of-dead-css-weight-with-purgecss-28821049fb/</link>
                <guid isPermaLink="false">66c34d9f30aba6677fb9f9ea</guid>
                
                    <category>
                        <![CDATA[ Utility First ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Accessibility ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tailwind ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 03 Jul 2018 14:42:35 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*UHrztp4ppPEPiHl_Zwo2Mg.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Sarah Dayan</p>
<p>I’m <a target="_blank" href="https://frontstuff.io/in-defense-of-utility-first-css">a big advocate for utility-first CSS</a>. After trying several methods over the years, it’s what I’ve found to be <strong>the best, most maintainable and scalable way of writing CSS to this day</strong>.</p>
<p>When my coworker <a target="_blank" href="https://github.com/clemfromspace">Clément Denoix</a> and I built <a target="_blank" href="https://www.api-search.io/">api-search.io</a>, I decided to use <a target="_blank" href="https://tailwindcss.com/">Tailwind CSS</a> to style it. Tailwind CSS is a theme-agnostic, fully customizable, utility-first library.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/MilXaM3nNEeiZFyTo-R1O4tkdjjh-spHRRGS" alt="Image" width="800" height="444" loading="lazy"></p>
<p>The whole point of a library is to give you access to a broad set of tools to use at will. The problem is, since you usually use only a subset of it, <strong>you end up with a lot of unused CSS rules in your final build</strong>.</p>
<p>In my case, not only did I load the entire Tailwind CSS library, but I also added several variants to some modules. That ended up making the final minified CSS file weight <strong>259 KB</strong> (before GZip). That’s quite heavy when you consider that the website is a simple single-page app with a minimal design.</p>
<p>You don’t want to load each utility by hand when you need it. That would be a long and cumbersome task. A better scenario is to have everything at your disposal during development and <strong>automatically remove what you didn’t use during the build step</strong>.</p>
<p>In JavaScript, we call it <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Tree_shaking">tree-shaking</a>. Now, thanks to <a target="_blank" href="https://www.purgecss.com/">PurgeCSS</a>, <strong>you can do the same with your CSS codebase</strong>.</p>
<p>PurgeCSS analyzes your content files and your CSS, then matches the selectors together. If it doesn’t find any occurrence of a selector in the content, it removes it from the CSS file.</p>
<p>For the most part, <strong>this can work out of the box</strong>. However, there are some areas in any website that may require some more thinking before letting PurgeCSS do its magic.</p>
<h3 id="heading-splitting-my-css">Splitting my CSS</h3>
<p>The project contains three main CSS files:</p>
<ul>
<li>A CSS reset called <a target="_blank" href="https://github.com/necolas/normalize.css">normalize.css</a>, included in Tailwind CSS.</li>
<li><a target="_blank" href="https://tailwindcss.com/">Tailwind CSS</a>, the most substantial part of my CSS codebase.</li>
<li>Some custom CSS, mostly for styling the <a target="_blank" href="https://community.algolia.com/react-instantsearch/">InstantSearch</a> components to which I couldn’t add classes.</li>
</ul>
<p>PurgeCSS can’t detect that I need to keep selectors such as <code>.ais-Highlight</code>, <strong>because the components that use it only show up in the DOM at runtime</strong>. Same goes with <code>normalize.css</code>: I’m relying on it to reset browser styles, but many of the related components will never be matched because they’re generated in JavaScript.</p>
<p>In the case of classes starting with <code>.ais-</code>, we can sort them out with <a target="_blank" href="https://frontstuff.io/how-i-dropped-250-kb-of-dead-css-weight-with-purgecss#whitelisting-runtime-classes">whitelisting</a>. Now when it comes to reset styles, selectors are a bit trickier to track down. Plus, the size of <code>normalize.css</code> is pretty insignificant and isn’t bound to change. So in this case, I decided to ignore the file altogether. Consequently, <strong>I had to split styles before running PurgeCSS</strong>.</p>
<p>My initial CSS configuration looked like this:</p>
<ul>
<li>A <code>tailwind.src.css</code> file with three <code>@tailwind</code> directives: <code>preflight</code>, <code>components</code> and <code>utilities</code>.</li>
<li>An <code>App.css</code> file with my custom styles.</li>
<li>An npm script in <code>package.json</code> to build Tailwind CSS right before starting or building the project. Every time this script runs, it outputs a <code>tailwind.css</code> file in <code>src</code>, which is loaded in the project.</li>
</ul>
<p>The <code>@tailwind preflight</code> directive loads <code>normalize.css</code>. I didn’t want PurgeCSS to touch it, so I moved it to a separate file.</p>
<pre><code><span class="hljs-comment">// tailwind.src.css @tailwind components;</span>
</code></pre><pre><code>@tailwind utilities;<span class="hljs-comment">/* normalize.src.css */</span> @tailwind preflight;
</code></pre><p>Then, I changed my existing <code>tailwind</code> script in <code>package.json</code> to build <code>normalize.src.css</code> separately.</p>
<pre><code>{  <span class="hljs-string">"scripts"</span>: {    <span class="hljs-string">"tailwind"</span>: <span class="hljs-string">"npm run tailwind:normalize &amp;&amp; npm run tailwind:css"</span>,    <span class="hljs-string">"tailwind:normalize"</span>: <span class="hljs-string">"tailwind build src/normalize.src.css -c tailwind.js -o src/normalize.css"</span>,    <span class="hljs-string">"tailwind:css"</span>: <span class="hljs-string">"tailwind build src/tailwind.src.css -c tailwind.js -o src/tailwind.css"</span>  }}
</code></pre><p>Finally, I loaded <code>normalize.css</code> in the project.</p>
<pre><code><span class="hljs-comment">// src/index.js</span>
</code></pre><pre><code>...import <span class="hljs-string">'./normalize.css'</span><span class="hljs-keyword">import</span> <span class="hljs-string">'./tailwind.css'</span><span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">'./App'</span>...
</code></pre><p>Now, I can run PurgeCSS on <code>tailwind.css</code> without fearing it might strip down needed rulesets.</p>
<h3 id="heading-configuring-purgecss">Configuring PurgeCSS</h3>
<p>PurgeCSS comes in many flavors: a command-line interface, a JavaScript API, wrappers for Webpack, Gulp, Rollup, and so on.</p>
<p>We used <a target="_blank" href="https://github.com/facebook/create-react-app">Create React App</a> to bootstrap the website, so Webpack came <a target="_blank" href="https://github.com/facebook/create-react-app#get-started-immediately">preconfigured and hidden</a> behind <a target="_blank" href="https://www.npmjs.com/package/react-scripts">react-scripts</a>. This means I couldn’t access Webpack configuration files unless I ran <code>npm run eject</code> to get them back and manage them directly in the project.</p>
<p>Not having to manage Webpack yourself has many advantages, so ejecting wasn’t an option. Instead, I decided to use a custom configuration file for PurgeCSS, and an npm script.</p>
<p>I first created a <code>purgecss.config.js</code> at the root of the project:</p>
<pre><code><span class="hljs-built_in">module</span>.exports = {  <span class="hljs-attr">content</span>: [<span class="hljs-string">'src/App.js'</span>],  <span class="hljs-attr">css</span>: [<span class="hljs-string">'src/tailwind.css'</span>]}
</code></pre><ul>
<li>The <code>content</code> property takes an array of files to analyze to match CSS selectors.</li>
<li>The <code>css</code> property takes an array of stylesheets to purge.</li>
</ul>
<p>Then, I edited my npm scripts to run PurgeCSS:</p>
<pre><code>{  <span class="hljs-string">"scripts"</span>: {    <span class="hljs-string">"start"</span>: <span class="hljs-string">"npm run css &amp;&amp; react-scripts start"</span>,    <span class="hljs-string">"build"</span>: <span class="hljs-string">"npm run css &amp;&amp; react-scripts build"</span>,    <span class="hljs-string">"css"</span>: <span class="hljs-string">"npm run tailwind &amp;&amp; npm run purgecss"</span>,    <span class="hljs-string">"purgecss"</span>: <span class="hljs-string">"purgecss -c purgecss.config.js -o src"</span>  }}
</code></pre><ul>
<li>I added a <code>purgecss</code> script that takes my configuration file and outputs the purged stylesheet in <code>src</code>.</li>
<li>I made this script run every time we start or build the project.</li>
</ul>
<p>Tailwind CSS uses special characters, so if you use PurgeCSS out of the box, it may remove necessary selectors. Fortunately, PurgeCSS allows us to use a <a target="_blank" href="https://www.purgecss.com/extractors#creating-an-extractor">custom extractor</a>, which is a function that lists out the selectors used in a file. For Tailwind, I needed to create a <a target="_blank" href="https://tailwindcss.com/docs/controlling-file-size/">custom one</a>:</p>
<pre><code><span class="hljs-built_in">module</span>.exports = {  ...  extractors: [    {      <span class="hljs-attr">extractor</span>: <span class="hljs-class"><span class="hljs-keyword">class</span> </span>{        <span class="hljs-keyword">static</span> extract(content) {          <span class="hljs-keyword">return</span> content.match(<span class="hljs-regexp">/[A-z0-9-:\/]+/g</span>) || []        },        <span class="hljs-attr">extensions</span>: [<span class="hljs-string">'js'</span>]      }    }  ]}
</code></pre><h3 id="heading-whitelisting-runtime-classes">Whitelisting runtime classes</h3>
<p><strong>PurgeCSS can’t detect classes that are generated at runtime</strong>, but it lets you define a whitelist. The classes you whitelist remain in the final file no matter what.</p>
<p>The project uses <a target="_blank" href="https://community.algolia.com/react-instantsearch/">React InstantSearch</a>, which generates components with classes that all start with <code>ais-</code>. Conveniently, PurgeCSS supports patterns in the form of regular expressions.</p>
<pre><code><span class="hljs-built_in">module</span>.exports = {  ...  css: [<span class="hljs-string">'src/tailwind.css'</span>, <span class="hljs-string">'src/App.css'</span>],  <span class="hljs-attr">whitelistPatterns</span>: [<span class="hljs-regexp">/ais-.*/</span>],  ...}
</code></pre><p>Now if I forget to remove a class that I no longer use from <code>App.css</code>, it will be taken out from the final build, but my InstantSearch selectors will remain safe.</p>
<h3 id="heading-new-build-lighter-css">New build, lighter CSS</h3>
<p>With this new configuration, <strong>my final CSS file has gone from 259 KB to…9 KB!</strong> It’s pretty significant in the context of a whole project, especially since many countries still have slow and unstable Internet, and more and more people browse on their phones while on the move.</p>
<p>Accessibility is also about catering for people with low bandwidth connections. It’s not acceptable not to try and help your users with slower Internet, especially if what you’re making them download is dead code.</p>
<p>That’s worth taking a moment to optimize your build. ?</p>
<p><em>Originally published at <a target="_blank" href="https://frontstuff.io/how-i-dropped-250-kb-of-dead-css-weight-with-purgecss">frontstuff.io</a>.</em></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>
