<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Adam Smith</title>
    <description>The latest articles on DEV Community by Adam Smith (@adamjcsmith).</description>
    <link>https://dev.to/adamjcsmith</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F841784%2Fc040e846-4c55-4c5b-a921-a47788dc9acb.jpeg</url>
      <title>DEV Community: Adam Smith</title>
      <link>https://dev.to/adamjcsmith</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adamjcsmith"/>
    <language>en</language>
    <item>
      <title>Supercharge your CSS with Tailwind</title>
      <dc:creator>Adam Smith</dc:creator>
      <pubDate>Mon, 04 Apr 2022 13:40:30 +0000</pubDate>
      <link>https://dev.to/lettheinsideout/supercharge-your-css-with-tailwind-1lo6</link>
      <guid>https://dev.to/lettheinsideout/supercharge-your-css-with-tailwind-1lo6</guid>
      <description>&lt;h1&gt;
  
  
  Supercharge your CSS with Tailwind
&lt;/h1&gt;

&lt;p&gt;Not often in the web development industry do we find tools that truly lead to a paradigm shift for our ways of working. Perhaps you've discovered this when adopting a new language; a few &lt;em&gt;aha&lt;/em&gt; moments later and the purported benefits make sense. Some JavaScript developers have discovered this with TypeScript, for instance. There's a learning curve, but the benefits are suddenly all the more real upon a visit to an older JS-based codebase. The new way of working feels like home&lt;/p&gt;

&lt;p&gt;Today, I'd like to discuss CSS. Innovations with stylesheets in recent years have focused on tooling and compilation, somewhat independently from innovations in other areas of the stack. Whereas most of us no longer write HTML, many do still write CSS. I'd like to cover the reasons why writing your own CSS is unproductive, and champion an alternative approach to styling.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tailwindcss.com"&gt;Tailwind&lt;/a&gt; is a styling framework which provides bitesize classes which allow you to style your HTML entities without having to maintain a separate stylesheet. In this article, I'll discuss how the &lt;a href="https://www.htmlgoodies.com/css/brief-introduction-to-functional-css/"&gt;functional CSS&lt;/a&gt; ideology can improve productivity and consolidate the styling approach across a front-end team.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSS
&lt;/h2&gt;

&lt;p&gt;CSS has been around for a while. With applications nowadays like React Native and Electron, its once-limited reach now stretches far. No matter where we look, we can safely say that Cascading Style Sheets is widely adopted.&lt;/p&gt;

&lt;p&gt;The problem with vanilla CSS, I'll argue, is that it is deceptively simple. It attempts to do too many things. The syntax is undeniably flexible and the way one experienced developer forges their CSS may look almost alien to another experienced developer. You may be able to relate to this on a more personal level if you've had to dig through your own CSS in the past and wondered "&lt;em&gt;just what was I doing there?&lt;/em&gt;".&lt;/p&gt;

&lt;p&gt;Writing your own CSS inherently has many disadvantages, which in general reduce productivity due to repetition and/or a reduction in intelligibility:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Writing your own class names&lt;/strong&gt; - takes lots of time and many selectors will never be reused&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trying to match/replicate the structure of your components in styling code&lt;/strong&gt; - the source of truth should be your components, not your styling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vendor prefixes&lt;/strong&gt; - a cat-and-mouse game of keeping up with browser engines, polluting your codebase at the same time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hacks to get ordinary bits of CSS to work&lt;/strong&gt; - many hacks are required (&lt;a href="https://www.reddit.com/r/programming/comments/n6a5v8/safari_is_the_new_internet_explorer_i_thought/"&gt;especially for Safari&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile breakpoints&lt;/strong&gt; - pollutes your codebase with media queries at many different breakpoints&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Specificity and !important&lt;/strong&gt; - having to order your styling in a certain way, and just one &lt;code&gt;!important&lt;/code&gt; breaks the cascade&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Value repetition&lt;/strong&gt; - lack of native support for variables&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Existing approaches
&lt;/h2&gt;

&lt;p&gt;Over the past twenty years, a number of approaches have been developed to both better organise your CSS and also process styling in a different way. Let's examine the compilation of CSS and a common naming convention (BEM).&lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-processors
&lt;/h3&gt;

&lt;p&gt;Between ten and fifteen years ago, the advent of CSS pre-processors like Sass, Less and Stylus was revolutionary. You could write your styles in a composited way, saving much repetition and scope for error. You could also have variables in CSS, for the first time. &lt;/p&gt;

&lt;p&gt;In the simple case, you could transform this kind of CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;nav&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;lightgray&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;nav&lt;/span&gt; &lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;nav&lt;/span&gt; &lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;lightblue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Into this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nav {
  background-color: lightgray;

  li {
    padding: 2px 5px;

    a {
      color: lightblue;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This compositional format shows the relationship between the selectors more naturally, like you'd see child components returned from a parent component in React.&lt;/p&gt;

&lt;p&gt;With the pre-processors, you can shrink your CSS and increase reuse through variables. In almost all working cases, it will be an improvement above vanilla CSS. There are also implementations now, via &lt;a href="https://postcss.org/"&gt;PostCSS&lt;/a&gt;, that add vendor prefixes for you. The major drawback is, of course, that you have to compile your CSS beforehand; usually done via part of your tooling such as &lt;a href="https://gruntjs.com/"&gt;Grunt&lt;/a&gt; or &lt;a href="https://gulpjs.com/"&gt;Gulp&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And also, your implementation would still suffer from many of the aforementioned core disadvantages of writing your own CSS, such as writing class names, replicating your structure, hacks and mobile breakpoints. &lt;/p&gt;

&lt;h3&gt;
  
  
  BEM
&lt;/h3&gt;

&lt;p&gt;Block Element Modifier is a common naming convention which subscribes to the idea that all CSS rules should be divided into blocks, sub-blocks (called &lt;em&gt;elements&lt;/em&gt;) and variants (called &lt;em&gt;modifiers&lt;/em&gt;). For simple applications, BEM can work rather well when you get used to its philosophy and the class names. &lt;/p&gt;

&lt;p&gt;This is an example of a modifier rule name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.nav__link--selected&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which looks interesting, if you've never seen that syntax before. Quickly, however, you'll find that the names get quite long:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.legal-cookie-banner__accept-or-reject-button--disabled&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll naturally come to points where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;em&gt;element&lt;/em&gt; should be split out to become a &lt;em&gt;block&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Some &lt;em&gt;elements&lt;/em&gt; naturally have their own &lt;em&gt;elements&lt;/em&gt; &lt;/li&gt;
&lt;li&gt;Some &lt;em&gt;modifiers&lt;/em&gt; might naturally have sub &lt;em&gt;modifiers&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And so on. There are actually a plethora of different approaches with BEM. It's arguably more a way of thinking than a watertight specification. &lt;a href="https://css-tricks.com/abem-useful-adaptation-bem/"&gt;Atomic BEM&lt;/a&gt; (ABEM) is one, for instance. The issues boil down to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Names generally become long and unwiedly&lt;/li&gt;
&lt;li&gt;The structure of your HTML is very strongly replicated, making it difficult to change and refactor&lt;/li&gt;
&lt;li&gt;Developer rules and approaches to block-element-element-modifier tend to vary a lot&lt;/li&gt;
&lt;li&gt;Nesting BEM in SASS/Less/Stylus can drastically reduce replication of block/element names but reduce intelligibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;BEM is a fairly old-school approach nowadays, though still common. It still doesn't address many of the core issues of writing your own CSS, and is essentially just a naming convention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tailwind
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://tailwindcss.com/"&gt;Tailwind&lt;/a&gt; is a framework that provides many small bits of CSS which are put together like lego. This approach is referred to as &lt;em&gt;functional CSS&lt;/em&gt;. Instead of writing your own classnames, you are provided with pre-made classes which you can use in your HTML in combination to quickly achieve styling.&lt;/p&gt;

&lt;p&gt;The beauty of the system is that you can mix and match prefixes, which make it easy and standardised to add states like &lt;em&gt;hover&lt;/em&gt;, &lt;em&gt;active&lt;/em&gt; or &lt;em&gt;focus&lt;/em&gt;, mobile styling and the pseudo-selectors &lt;em&gt;before&lt;/em&gt; and &lt;em&gt;after&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Rather than providing off-the-shelf components like Bootstrap and Semantic UI, Tailwind merely provides the small building blocks to assist in building your own components. Much like &lt;a href="https://necolas.github.io/normalize.css/"&gt;Normalize.css&lt;/a&gt;, Tailwind strips out the default styling browsers apply to all elements, such as buttons, input fields and more.&lt;/p&gt;

&lt;p&gt;Let's dive into the major concepts of the framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  Piecemeal
&lt;/h3&gt;

&lt;p&gt;The core concept of Tailwind is the provision of utility classes, which are really like blocks of lego. Here is an example of a simple link with an underline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-underline"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This uses the &lt;code&gt;text-&lt;/code&gt; utility prefix. Remember that Tailwind strips out all default browser styling, so links by default will not have an underline or any colour. The &lt;code&gt;text-&lt;/code&gt; utility prefix here groups together related CSS rules. Let's see another one in action by adding a blue colour to the link:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-underline text-blue-500"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can add colours to most utility prefixes, such as &lt;code&gt;text&lt;/code&gt;, &lt;code&gt;bg&lt;/code&gt;, &lt;code&gt;border&lt;/code&gt; and more. Tailwind supports a number of out-of-the-box colour names, and shades, from 100-900. Let's also add some padding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-underline text-red-500 px-5 py-2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The prefix for padding is simply &lt;code&gt;p-&lt;/code&gt; and the value represents fractions of a &lt;a href="https://tailwindcss.com/docs/padding#add-padding-to-a-single-side"&gt;rem&lt;/a&gt;, e.g. &lt;code&gt;p-1&lt;/code&gt; represents &lt;code&gt;0.25rem&lt;/code&gt; of padding on all sides, equivalent to if you'd written &lt;code&gt;padding: 0.25rem;&lt;/code&gt; in vanilla CSS. Most importantly, you can also use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;px&lt;/code&gt; to indicate padding in the x-dimension (e.g. &lt;code&gt;top&lt;/code&gt; and &lt;code&gt;bottom&lt;/code&gt; in CSS terms)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;py&lt;/code&gt; to indicate padding in the y-dimension (e.g. &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt; in CSS terms)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pt&lt;/code&gt;, &lt;code&gt;pr&lt;/code&gt;, &lt;code&gt;pb&lt;/code&gt; and &lt;code&gt;pl&lt;/code&gt; to indicate padding in the top, right, bottom and left directions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And, you are not just restricted to using Tailwind's rem fractions, you can also use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-px&lt;/code&gt; to add one pixel to the dimension you want, e.g. &lt;code&gt;py-px&lt;/code&gt; to add one pixel of padding to both the &lt;code&gt;top&lt;/code&gt; and &lt;code&gt;bottom&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Square brackets, e.g. &lt;code&gt;p-[5px]&lt;/code&gt; to break out of Tailwind's design system, for those pixel perfect changes (JIT mode only)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, let's add a border to match the colour:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-underline text-red-500 px-5 py-2 border border-current"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-current&lt;/code&gt; suffix is quite useful in Tailwind, and instructs the system here to use the same colour as the text for the border. We can also add rounded corners:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-underline text-red-500 px-5 py-2 border border-current rounded"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if we wanted to make the border corners very rounded, like a pill, we can use one of Tailwind's stock size classes, which are &lt;code&gt;xs&lt;/code&gt;, &lt;code&gt;sm&lt;/code&gt;, &lt;code&gt;md&lt;/code&gt; (default), &lt;code&gt;lg&lt;/code&gt;, &lt;code&gt;xl&lt;/code&gt;, &lt;code&gt;2xl&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-underline text-red-500 px-5 py-2 border border-current rounded-xl"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These stock sizes also work on text sizes as mobile prefixes, as we will see next. And that's a very simple example of how the utility classes work. &lt;/p&gt;

&lt;h3&gt;
  
  
  Mobile styling
&lt;/h3&gt;

&lt;p&gt;You could think of base classes being &lt;a href="https://medium.com/@Vincentxia77/what-is-mobile-first-design-why-its-important-how-to-make-it-7d3cf2e29d00"&gt;mobile-first&lt;/a&gt;. Write your styling representing the smallest screen size, and add Tailwind's stock size classes as prefixes to change the styling at particular breakpoints. For example, if we wanted to have the default text size for a paragraph of text to be &lt;code&gt;text-xs&lt;/code&gt; , but we wanted to bump up the font size to be &lt;code&gt;text-sm&lt;/code&gt; on tablets and larger displays, we can simply write it as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-xs lg:text-sm"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Some lovely text.
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;lg&lt;/code&gt; represents a &lt;a href="https://tailwindcss.com/docs/responsive-design"&gt;breakpoint&lt;/a&gt; for all screen sizes that are &lt;em&gt;at least&lt;/em&gt; "large" size, which by default is &lt;code&gt;1024px&lt;/code&gt;. If we then wanted to make the text even bigger on huge displays (1536px and higher), we can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-xs lg:text-sm 2xl:text-md"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Some lovely text.
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we don't have to worry about polluting our codebase with &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries"&gt;media queries&lt;/a&gt;. We can just quickly indicate when a particular property should change depdending on the screen size, using the same familiar stock sizes we use for text size, border radius and more.&lt;/p&gt;

&lt;h3&gt;
  
  
  Customisability
&lt;/h3&gt;

&lt;p&gt;Not only does Tailwind provide a wealth of off-the-shelf utility classes, the framework allows us to modify the default assumptions it makes for properties such as colours and sizes. For instance, you could create an &lt;code&gt;xxs&lt;/code&gt; size for text, or a &lt;code&gt;4xl&lt;/code&gt; responsive breakpoint, if you wanted to.&lt;/p&gt;

&lt;p&gt;Tailwind implementations usually have a &lt;code&gt;tailwind.config.js&lt;/code&gt; file associated, which allows you to either replace whole properties of a class family (e.g. &lt;code&gt;bg&lt;/code&gt; for backgrounds), or extend them. Importantly, you don't have to write out or deal with lots of boilerplate code just to change one tiny thing.&lt;/p&gt;

&lt;p&gt;One of the most recent additions to Tailwind was "just in time" mode. This allows the PostCSS compiler to "tree shake" the implementation by inspecting the exact classes that are used in your document, drastically reducing compilation time. It also allows you to break out of Tailwind's design system, using square brackets, which you may have noticed earlier. This allows further - pixel-perfect - customisation in a way that is declarative and dependable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adoption
&lt;/h3&gt;

&lt;p&gt;Here at InsideOut, we've found that Tailwind has improved our speed of prototyping and development. We can now quickly produce front-end screens without having to worry about maintaining an unweidly companion stylesheet that doesn't align to our components. Our React components are the source of truth for the shape of the end solution, and Tailwind prevents us from "recreating" any of that shape in styling, promoting component reuse, not classname reuse.&lt;/p&gt;

&lt;p&gt;Despite Tailwind's wealth of utility classes, there have been rare occasions where we have had to create a few of our own custom classnames. In our base css, for instance, we had to create one at the start to define a custom height for our pages that takes into account the height of our nav bar. We also have another one to make a nice-looking link. For our production-ready internal dashboard, this is the totality of our custom SCSS so far:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.custom-h-full {
    height: calc(100% - 3rem);
}

.custom-explicit-link {
    @apply underline;
    @apply text-blue-500;

    &amp;amp;:hover {
        @apply text-blue-600;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it. We adopted a convention of using the prefix &lt;code&gt;custom-&lt;/code&gt; to make it obvious when reading the classnames on a component that there's a bit of styling that is ours in there. &lt;/p&gt;

&lt;p&gt;The other convention we found useful quite quickly, in the context of our React components, was grouping Tailwind's utilities into related classes, as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;
            &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`
                absolute top-0 left-0
                flex items-center justify-center
                rounded
                w-full
                h-full
                bg-yellow-100
                opacity-90
            `&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we can see that on different lines we've grouped:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Positioning&lt;/li&gt;
&lt;li&gt;Display (and flex properties)&lt;/li&gt;
&lt;li&gt;Borders/rounding&lt;/li&gt;
&lt;li&gt;Width&lt;/li&gt;
&lt;li&gt;Height&lt;/li&gt;
&lt;li&gt;Background&lt;/li&gt;
&lt;li&gt;Opacity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we wanted to add a border here, it would be placed neatly on the third line. This makes it clearer to read than this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"absolute top-0 left-0 flex items-center justify-center rounded w-full h-full bg-yellow-100 opacity-90"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When it's hard to know what's going on. Especially if a future developer comes in and adds more classes at the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Obviously, Tailwind doesn't aim to translate CSS rules into classes directly, because that would be quite verbose, and wouldn't solve some of the core issues in CSS I outlined at the start of this article, like mobile styling. Tailwind also doesn't aim to solve everything with providing off-the-shelf components. It merely provides a shorthand way to quickly style your components without having to remake the component structure every time in CSS code.&lt;/p&gt;

&lt;p&gt;One of the main hurdles here at CSS was learning the Tailwind lingo. A lot of the utility classes provided are remarkably simple and intuitive, such as &lt;code&gt;p&lt;/code&gt; for padding, &lt;code&gt;m&lt;/code&gt; for margin, &lt;code&gt;bg&lt;/code&gt; for background, and so on. There are occasions where the naming is slightly different, e.g.  &lt;code&gt;align-items: center&lt;/code&gt; becomes &lt;code&gt;items-center&lt;/code&gt;. But these have not been a big issue at all. The naming feels faithful to the original paradigms in CSS, which made learning Tailwind fairly straightforward. It differs, of course, from other approaches like &lt;a href="https://semantic-ui.com/"&gt;Semantic UI&lt;/a&gt; where the classes read like an english sentence, but feel farther away from actual CSS.&lt;/p&gt;

&lt;p&gt;At times the team has felt as if Tailwind is still very much a work in progress. Support for JIT was added in version 2.0, and we adopted it during that major release cycle, with a variant of Tailwind which was compatible with our version of &lt;a href="https://reactjs.org/docs/create-a-new-react-app.html"&gt;Create React App&lt;/a&gt;. JIT required PostCSS 8.0, which CRA has only begun supporting recently. As such, beforehand, there were some extra hoops for integration. We've tried to upgrade to version 3.0 recently but had to roll back due to some impassable webpack issues.&lt;/p&gt;

&lt;p&gt;Overall, we do feel that Tailwind has made a positive impact on our front-end development, and will continue to use it for future projects. We're confident that it's a production-ready framework, and are glad to say that it's made responsive development a breeze. We don't have to care any more about specificity, media queries, writing our own class names or browser hacks. The barrier to entry has been fairly low and the productivity boost has been quite high. Tailwind has been a boon to our development stack, and we're looking forward to developing with it in our next project.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>tailwindcss</category>
      <category>css</category>
    </item>
  </channel>
</rss>
