<?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: maiconsanson</title>
    <description>The latest articles on DEV Community by maiconsanson (@maiconsanson).</description>
    <link>https://dev.to/maiconsanson</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%2F1194070%2Fee309a0b-7c54-436e-9c84-e50f201319cf.jpeg</url>
      <title>DEV Community: maiconsanson</title>
      <link>https://dev.to/maiconsanson</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maiconsanson"/>
    <language>en</language>
    <item>
      <title>Using Tailwind for four months</title>
      <dc:creator>maiconsanson</dc:creator>
      <pubDate>Fri, 01 Mar 2024 14:26:32 +0000</pubDate>
      <link>https://dev.to/maiconsanson/4-months-using-tailwind-2ofn</link>
      <guid>https://dev.to/maiconsanson/4-months-using-tailwind-2ofn</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmb4zsjg1xd8yup0ffs5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmb4zsjg1xd8yup0ffs5.png" alt="Ship floating in the sky" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/maiconsanson/4-meses-usando-tailwind-4k2l"&gt;Versão em Português&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post was written in October 2023; some data provided here may have been changed.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Personal projects are great; you can choose the entire &lt;a href="https://en.wikipedia.org/wiki/Solution_stack"&gt;application stack&lt;/a&gt;: database, environments, deployment, testing, back end, front end, how to organize tasks, and more. In these projects, you can achieve a level of learning in a company that you would hardly have. So, take advantage, 'play' startup in your free time, and bear the consequences of your decisions.&lt;/p&gt;

&lt;p&gt;My focus is on the front end, but I dabble in the back end a bit because it's a great feeling to be able to, on my own, bring a crazy idea to life and put it into practice.&lt;/p&gt;

&lt;p&gt;I'm a bit of an old-timer (+40) and was already working in development before the advent of &lt;a href="https://coderwall.com/p/cekryw/history-of-jquery"&gt;JQuery&lt;/a&gt; and &lt;a href="http://prototypejs.org/2007/01/18/prototype-documentation-is-here/"&gt;Prototype&lt;/a&gt;. I never went to college for this field, but I graduated from a public university in Music and Fine Arts... go figure.&lt;/p&gt;

&lt;p&gt;Anyway, I want to say that I've seen a lot out there. Concepts and ideas that come and go, old problems with new names, and old solutions with a new look.&lt;/p&gt;

&lt;p&gt;But I have to focus, and I am here to talk about styles in a web application.&lt;/p&gt;

&lt;p&gt;In recent years, working as a senior developer in companies of various sizes, I have increasingly distanced myself from CSS, which, modesty aside, I know very well and have always found fun and therapeutic. I've never complained about it, but it's common to use a pre-designed Design System, and you just 'program' the blocks (sometimes applying Atomic Design, which would already lead to another article when it makes sense) without worrying too much about the style of the components.&lt;/p&gt;

&lt;p&gt;It is common for a project out there to use a &lt;a href="https://en.wikipedia.org/wiki/CSS-in-JS"&gt;CSS-in-JS&lt;/a&gt; solution like &lt;a href="https://styled-components.com/"&gt;Styled Components&lt;/a&gt;, &lt;a href="https://emotion.sh/docs/introduction"&gt;Emotion&lt;/a&gt;, &lt;a href="https://stitches.dev/"&gt;Stitches&lt;/a&gt;, &lt;a href="https://linaria.dev/"&gt;Linaria&lt;/a&gt;, and others when adjustments are needed. They are great; I've used them for a long time and love using them when it makes sense.&lt;/p&gt;

&lt;p&gt;Once, I used &lt;a href="https://sass-lang.com/"&gt;Sass&lt;/a&gt; with &lt;a href="https://github.com/css-modules/css-modules"&gt;CSS Modules&lt;/a&gt; to style a practical front-end test for a position at a medium-sized company. During the interview, one of the 'senior developers' asked me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why use &lt;em&gt;Sass&lt;/em&gt;? It's somewhat uncommon these days. Why didn't you choose &lt;em&gt;CSS-in-JS&lt;/em&gt;? Don't you think it's a bad practice to go back to using &lt;em&gt;CSS&lt;/em&gt; or &lt;em&gt;Sass&lt;/em&gt;?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I just smiled. However, over time, I've seen more and more front-end developers who knew very little about &lt;em&gt;CSS&lt;/em&gt;, &lt;em&gt;Modules&lt;/em&gt;, &lt;em&gt;Custom Properties&lt;/em&gt;, the power of the cascade effect, and its countless possibilities. Professionals who enter the market only use &lt;em&gt;JS/TS&lt;/em&gt; as the default for writing styles and see &lt;em&gt;CSS&lt;/em&gt; as outdated. What a crazy situation!&lt;/p&gt;

&lt;p&gt;Returning to my case, in this fresh new project, I decided to use &lt;a href="https://react.dev/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components"&gt;Server Components&lt;/a&gt; along with &lt;a href="https://nextjs.org/"&gt;NextJs&lt;/a&gt; and give a chance to the much-discussed &lt;a href="https://tailwindcss.com/"&gt;TailWind Css&lt;/a&gt;. It's a relatively complex project with a strong focus on the user experience, featuring a simple interface but with details of unique interactions and multiple themes.&lt;/p&gt;

&lt;p&gt;With that said, here are my conclusions after four months of daily use.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Tailwind CSS?
&lt;/h2&gt;

&lt;p&gt;For those who landed here by chance, in summary, &lt;em&gt;Tailwind CSS&lt;/em&gt; is a &lt;em&gt;CSS&lt;/em&gt; framework similar to the old &lt;a href="https://getbootstrap.com/"&gt;Bootstrap&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The main difference is that &lt;strong&gt;each class in &lt;em&gt;Tailwind&lt;/em&gt; corresponds to a CSS property&lt;/strong&gt; (or pseudo-class/element) but with a slightly different name. The so-called &lt;a href="https://heydonworks.com/article/what-is-utility-first-css/"&gt;Utility-first&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The class &lt;code&gt;z-0&lt;/code&gt; translates to the property &lt;code&gt;z-index: 0;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The class &lt;code&gt;overflow-hidden&lt;/code&gt; translates to the property &lt;code&gt;overflow: hidden;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The class &lt;code&gt;hover:underline&lt;/code&gt; translates to the pseudo-class &lt;code&gt;:hover { text-decoration: underline; }&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Controversial Aesthetics
&lt;/h2&gt;

&lt;p&gt;In the examples we come across, including in the &lt;a href="https://tailwindcss.com/docs/installation"&gt;documentation&lt;/a&gt; itself, we find this type of markup structure:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;div class="w-9 h-9 rounded-lg flex items-center justify-center text-slate-700 peer-checked:font-semibold peer-checked:bg-slate-900 peer-checked:text-white"&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I care a lot about the functional aesthetics of code (beauty + readability), clean code with good sense, and organization.&lt;/p&gt;

&lt;p&gt;When reading the above code, it bothers me. I find it difficult to understand what is happening, and I lose focus with all these classes cluttering my markup.&lt;/p&gt;

&lt;p&gt;Markup and style should be isolated as much as possible, in my opinion. I don't need to know that an element has a &lt;code&gt;flex&lt;/code&gt; position if I don't want to know that at the time.&lt;/p&gt;

&lt;p&gt;My thought was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Alright, these are just examples, and I can work around it. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'll create a function to handle this.&lt;/p&gt;

&lt;p&gt;And I resolved it this way:&lt;/p&gt;

&lt;p&gt;For each component that contained styled elements, I created a &lt;code&gt;styles.js&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cleanClasses&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@helpers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;classNames&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;hasSomeProp&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;cleanClasses&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`
      &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;hasSomeProp&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;border-green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;border-black&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
      border
      flex
      h-9
      items-center
      justify-center
      peer-checked:bg-slate-900
      peer-checked:font-semibold
      peer-checked:text-white
      rounded-lg
      text-slate-700
      w-9
    `&lt;/span&gt;&lt;span class="p"&gt;),&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;&lt;em&gt;Note: I always sort my properties in alphabetical order.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And inside my component, I imported that file and applied it to the element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;classNames&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./styles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hasSomeProp&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;classNames&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;hasSomeProp&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Solved, I thought!&lt;br&gt;
I isolate all the classes and keep my components clean! 🤘&lt;/p&gt;

&lt;p&gt;But notice that in &lt;code&gt;styles.js&lt;/code&gt;, there's a function called &lt;code&gt;cleanClasses()&lt;/code&gt;. I had to create it because the indentation using &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals"&gt;template literals&lt;/a&gt; was messing up the final &lt;a href="https://en.wikipedia.org/wiki/Minification_(programming)"&gt;minification&lt;/a&gt; of the HTML.&lt;/p&gt;

&lt;p&gt;To solve &lt;strong&gt;and keep my indentation the way I think makes sense&lt;/strong&gt;, I created a function to remove unnecessary characters that could interfere with minification in the final build.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;isString&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@helpers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cleanClasses&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;removeFalsyValues&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\b(?:&lt;/span&gt;&lt;span class="sr"&gt;undefined|null|false|NaN|''&lt;/span&gt;&lt;span class="se"&gt;)\b&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;removeExtraSpaces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;removeFalsyValues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cleanedClasses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;removeExtraSpaces&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cleanedClasses&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I liked the solution, and it served me well, but I started to have a nagging feeling...&lt;/p&gt;

&lt;p&gt;I enjoy programming, but I'm lazy; the less I have to code, the more I like coding. 😂&lt;/p&gt;

&lt;h2&gt;
  
  
  Unnecessary Abstractions
&lt;/h2&gt;

&lt;p&gt;The &lt;em&gt;Tailwind&lt;/em&gt; documentation became a part of my daily work routine. &lt;br&gt;
To ensure that a particular class represented the property I wanted, There was always a tab open for me to refer to.&lt;/p&gt;

&lt;p&gt;And it's normal; I have to learn the framework. But this reliance on memorizing classes that are essentially property names (that I already knew by heart in &lt;em&gt;CSS&lt;/em&gt;) started to irritate me, and I found the abstractions unnecessary.&lt;/p&gt;

&lt;p&gt;In a way, I dare say, I was 'unlearning' the properties of plain &lt;em&gt;CSS&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I used this term on purpose because after a few months using TW, and having already migrated the project to CSS Modules, I found myself adding Tailwind classes instead of CSS properties. As they are similar names, my brain ended up substituting these values.&lt;/p&gt;

&lt;p&gt;For example, do you know which property the Tailwind class &lt;code&gt;justify-center&lt;/code&gt; corresponds to?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔘 &lt;code&gt;justify-content: center;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🔘 &lt;code&gt;justify-items: center;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🔘 &lt;code&gt;justify-self: center;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🔘 &lt;code&gt;justify-tracks: center;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hint: &lt;code&gt;justify-tracks&lt;/code&gt; is still experimental and doesn't even exist in Tailwind.&lt;/p&gt;

&lt;p&gt;You'll have to go to the &lt;a href="https://tailwindcss.com/docs/justify-content"&gt;documentation&lt;/a&gt; If you're in doubt. 🤡&lt;/p&gt;
&lt;h2&gt;
  
  
  Handling more complex selectors
&lt;/h2&gt;

&lt;p&gt;One aspect I didn't find productive was using more complex selectors. While styling a single element is okay, things get awkward when you need something more complex that involves other elements.&lt;/p&gt;

&lt;p&gt;For example, let's say that I don't have access to an items list, but I need to modify them.&lt;br&gt;
&lt;em&gt;Note: This is far from complex.&lt;/em&gt;&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;ul&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="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Item 1&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Item 2&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Item 3&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&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;With Tailwind, I would have to add something like:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cleanClasses&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@helpers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;classNames&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;cleanClasses&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`
      [&amp;amp;_li]:rounded-full
      [&amp;amp;_li]:border
      [&amp;amp;_li]:border-black
      [&amp;amp;_li]:bg-white
      [&amp;amp;_li]:px-2
      [&amp;amp;_li]:py-0.5
    `&lt;/span&gt;&lt;span class="p"&gt;),&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;It is very wordy to say that each property is an item in the list with [&amp;amp;_li] and have to inform that repeatedly in each TW class. Not to mention that I can't use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties"&gt;shorthand properties&lt;/a&gt;. There's a plugin, but I don't want to clutter my application with packages.&lt;/p&gt;

&lt;p&gt;With CSS I just declare it like:&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;.&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt; &lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;color__white&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;border&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;radius__full&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt; &lt;span class="nx"&gt;solid&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;color__black&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="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;size__0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;size__2&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;And I won't even go into detail about sibling selectors](&lt;a href="https://tailwindcss.com/docs/hover-focus-and-other-states#styling-based-on-sibling-state"&gt;https://tailwindcss.com/docs/hover-focus-and-other-states#styling-based-on-sibling-state&lt;/a&gt;) and other selectors that are trivial with native CSS. I feel like I'm reinventing the wheel, but this wheel isn't very round.&lt;/p&gt;

&lt;h2&gt;
  
  
  Themes
&lt;/h2&gt;

&lt;p&gt;Another thing I didn't like was the way of adding multiple themes and their various &lt;a href="https://thedesignsystem.guide/design-tokens"&gt;design tokens&lt;/a&gt; using &lt;em&gt;TW&lt;/em&gt;. I thought it would handle that natively, but it doesn't.&lt;/p&gt;

&lt;p&gt;One option is to install an additional dependency like &lt;a href="https://github.com/L-Blondy/tw-colors"&gt;tw-colors&lt;/a&gt;, as we don't have that natively in the framework (we can only change the tokens of the current theme). It's nice and works well.&lt;/p&gt;

&lt;p&gt;Another option is to use native CSS variables and inform Tailwind how to use them. But wait, I don't want that since I chose the framework to handle the styles. I only want to use Tailwind and its gang.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where is the cascade effect?
&lt;/h2&gt;

&lt;p&gt;Quickly, I learned that TW removes one of the most important aspects of CSS (which, incidentally, is the meaning of the first letter of its acronym: &lt;strong&gt;Cascade&lt;/strong&gt; Style Sheets).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: The version used was &lt;code&gt;3.3.3&lt;/code&gt;. They'll probably address this in the future.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For instance, there are situations where you need to override some style to customize existing components. Suppose you have a component used in various places, but in a specific location, you need it to have something different, and you only need to override a CSS property. Adding a new prop to the component to only use for this wouldn't be a good idea.&lt;/p&gt;

&lt;p&gt;In the code below, due to the cascade effect, it's expected that the value &lt;code&gt;white&lt;/code&gt; should replaced by &lt;code&gt;black&lt;/code&gt; in the &lt;code&gt;background&lt;/code&gt; property of &lt;code&gt;ChildComponent&lt;/code&gt;. When we call this component, we add another background that should override the default.&lt;/p&gt;

&lt;p&gt;In other words, everything declared later with the same &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity"&gt;specificity&lt;/a&gt; has a higher priority than the previous property.&lt;/p&gt;

&lt;p&gt;The rendering of the div below would be &lt;code&gt;&amp;lt;div class="bgWhite bgBlack" /&amp;gt;&lt;/code&gt;.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ChildComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./styles.module.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="c1"&gt;// .bgBlack { background: black; }&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ParentComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ChildComponent&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="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bgBlack&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./styles.module.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="c1"&gt;// .bgWhite { background: white; }&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ChildComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bgStyles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;white&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&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="nx"&gt;bgStyles&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Some Text
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&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;In Tailwind, if the rendering of your component is &lt;code&gt;&amp;lt;div class="bg-white bg-black" /&amp;gt;&lt;/code&gt;, the &lt;code&gt;bg-black&lt;/code&gt; won't necessarily override the &lt;code&gt;bg-white&lt;/code&gt;, as it depends on the internal order of classes in &lt;em&gt;TW&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In other words, there is no guarantee of the cascade effect. Well, but that's what I pay CSS for! 😅&lt;/p&gt;

&lt;p&gt;You can solve this, but guess what; you'll need to add another dependency to your project using &lt;a href="https://github.com/dcastil/tailwind-merge"&gt;tailwind-merge&lt;/a&gt;, which will remove the unwanted classes since the cascade effect doesn't work. Or use &lt;strong&gt;!important&lt;/strong&gt;. 😒&lt;/p&gt;

&lt;h2&gt;
  
  
  Decision after Analysis
&lt;/h2&gt;

&lt;p&gt;Finally, as previously mentioned, I have concluded that, for my case, the ideal would be to remove everything related to &lt;em&gt;Tailwind&lt;/em&gt; (&lt;code&gt;tailwindcss&lt;/code&gt;, &lt;code&gt;postcss&lt;/code&gt;, &lt;code&gt;tw-colors&lt;/code&gt;, and &lt;code&gt;tailwind-merge&lt;/code&gt;) and use only CSS Modules (already provided by &lt;em&gt;NextJs&lt;/em&gt; as the default).&lt;/p&gt;

&lt;p&gt;I found the experience of using Tailwind juicy, but it didn't convince me 100%. I had to create many extra solutions and install packages to make my experience the way I think it works.&lt;/p&gt;

&lt;p&gt;Using it for prototyping projects, MVPs, or even if the team consists only of backend developers (who don't want to learn CSS) it can work. &lt;/p&gt;

&lt;p&gt;But if I were to create a new product, I would already rule out the use of Tailwind. To me, having well-organized design tokens with CSS variables and using CSS Modules is the most natural and efficient choice. I wouldn't even go for Sass. Doing the basics well is the trend for the coming years; it never stopped.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgnfafcguzge2pb759slo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgnfafcguzge2pb759slo.png" alt="Print de um pull request do Github" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>css</category>
      <category>frontend</category>
    </item>
    <item>
      <title>4 meses usando Tailwind</title>
      <dc:creator>maiconsanson</dc:creator>
      <pubDate>Tue, 20 Feb 2024 14:55:48 +0000</pubDate>
      <link>https://dev.to/maiconsanson/4-meses-usando-tailwind-4k2l</link>
      <guid>https://dev.to/maiconsanson/4-meses-usando-tailwind-4k2l</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmb4zsjg1xd8yup0ffs5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmb4zsjg1xd8yup0ffs5.png" alt="Navio flutuando no céu" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/maiconsanson/4-months-using-tailwind-2ofn"&gt;English version&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Este post foi escrito em outubro de 2023, alguns dados fornecidos aqui podem ter sido alterados.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Projeto pessoal é uma maravilha, você é livre para escolher toda a &lt;a href="https://pt.wikipedia.org/wiki/Conjunto_de_solu%C3%A7%C3%B5es_(computa%C3%A7%C3%A3o)"&gt;stack da aplicação&lt;/a&gt;: database, ambientes, deploy, testes, back end, front end, como organizar as tasks e etc. Nesses projetos você consegue ter um nível de aprendizado que dificilmente teria em uma empresa. Então aproveite, "brinque" de startup nas horas vagas e arque com suas decisões.&lt;/p&gt;

&lt;p&gt;Meu foco é o front end mas navego um pouco no back end porque é uma sensação ótima conseguir, sozinho, tirar uma ideia maluca do papel e colocá-la em prática.&lt;/p&gt;

&lt;p&gt;Sou um cara das antigas (+40) e que já trabalhava com desenvolvimento antes do início do &lt;a href="https://coderwall.com/p/cekryw/history-of-jquery"&gt;Jquery&lt;/a&gt; e &lt;a href="http://prototypejs.org/2007/01/18/prototype-documentation-is-here/"&gt;Prototype&lt;/a&gt;. Nunca fiz faculdade na área, mas sou formado em faculdade pública de Música e Belas Artes... pois é.&lt;/p&gt;

&lt;p&gt;Enfim, só pra dizer que já vi muita coisa por aí. Conceitos e ideias que vão em e vem, problemas antigos com novos nomes e soluções velhas com nova roupagem.&lt;/p&gt;

&lt;p&gt;Mas o que quero focar aqui é sobre estilos numa aplicação WEB.&lt;/p&gt;

&lt;p&gt;Nos últimos anos, trabalhando como desenvolvedor sênior em empresas de vários tamanhos, cada vez mais fui me afastando do CSS que, modéstias a parte, conheço muito bem e sempre achei divertido e terapêutico. Nunca reclamei disso, é mais que comum utilizar algum Design System já projetado e você "só" vai programando os blocos (às vezes aplicando Atomic Design, que já renderia outro artigo, quando faz sentido) e sem se preocupar muito com o estilo dos componentes.&lt;/p&gt;

&lt;p&gt;Quando precisa ajustar algo, geralmente o projeto utiliza algum &lt;a href="https://en.wikipedia.org/wiki/CSS-in-JS"&gt;CSS-in-JS&lt;/a&gt; como &lt;a href="https://styled-components.com/"&gt;Styled Components&lt;/a&gt;, &lt;a href="https://emotion.sh/docs/introduction"&gt;Emotion&lt;/a&gt;, &lt;a href="https://stitches.dev/"&gt;Stitches&lt;/a&gt;, &lt;a href="https://linaria.dev/"&gt;Linaria&lt;/a&gt; e etc. Eles são ótimos, usei por muito tempo e adoro usá-los quando faz sentido.&lt;/p&gt;

&lt;p&gt;Certa vez eu utilizei &lt;a href="https://sass-lang.com/"&gt;Sass&lt;/a&gt; com &lt;a href="https://github.com/css-modules/css-modules"&gt;CSS Modules&lt;/a&gt; para estilizar um teste prático de front end para uma vaga numa empresa de médio porte e um dos "programadores sêniors" me perguntou na entrevista:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Qual o motivo de usar &lt;em&gt;Sass&lt;/em&gt;? É algo incomum hoje em dia. Por que você não escolheu &lt;em&gt;CSS in JS&lt;/em&gt;? Não acha uma má prática voltar a usar &lt;em&gt;CSS&lt;/em&gt; ou &lt;em&gt;Sass&lt;/em&gt;?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Apenas sorri. Mas, ao longo do tempo, vi cada vez mais programadores front-end que não sabiam quase nada de &lt;em&gt;CSS&lt;/em&gt;, &lt;em&gt;Modules&lt;/em&gt;, &lt;em&gt;Custom Properties&lt;/em&gt;, o poder do efeito em cascata e suas inúmeras possibilidades. Profissionais que já entram no mercado apenas utilizando &lt;em&gt;JS/TS&lt;/em&gt; como padrão para escrever os estilos e veem &lt;em&gt;CSS&lt;/em&gt; como algo obsoleto, fora de moda. Que loucura!&lt;/p&gt;

&lt;p&gt;Voltando ao meu caso. Nesse projeto zero em folha, decidi usar &lt;a href="https://react.dev/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components"&gt;Server Components&lt;/a&gt; junto com o &lt;a href="https://nextjs.org/"&gt;NextJs&lt;/a&gt; e dar uma chance ao tão comentado &lt;a href="https://tailwindcss.com/"&gt;TailWind Css&lt;/a&gt;. É um projeto relativamente complexo, com grande foco na experiência do usuário, com interface simples mas com detalhes de interações diferenciadas e múltiplos temas.&lt;/p&gt;

&lt;p&gt;Posto isso, eis minhas conclusões após 4 meses de uso diário.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é o Tailwind CSS?
&lt;/h2&gt;

&lt;p&gt;Em resumo, para quem caiu aqui de paraquedas, o &lt;em&gt;Tailwind CSS&lt;/em&gt; é um framework de &lt;em&gt;CSS&lt;/em&gt; como o antigo &lt;a href="https://getbootstrap.com/"&gt;Bootstrap&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A diferença principal é que &lt;strong&gt;cada classe no &lt;em&gt;Tailwind&lt;/em&gt; equivale a uma propriedade do &lt;em&gt;CSS&lt;/em&gt;&lt;/strong&gt; (ou pseudo classe/elemento) mas com o nome ligeiramente diferente. O chamado &lt;a href="https://heydonworks.com/article/what-is-utility-first-css/"&gt;Utility-first&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Por exemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A classe &lt;code&gt;z-0&lt;/code&gt; resulta na propriedade &lt;code&gt;z-index: 0;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A classe &lt;code&gt;overflow-hidden&lt;/code&gt; resulta na propriedade &lt;code&gt;overflow: hidden;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A classe &lt;code&gt;hover:underline&lt;/code&gt; resulta na pseudo classe &lt;code&gt;:hover { text-decoration: underline; }&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Estética controversa
&lt;/h2&gt;

&lt;p&gt;Nos exemplos que lemos por aí, inclusive na própria &lt;a href="https://tailwindcss.com/docs/installation"&gt;documentação&lt;/a&gt;, encontramos este tipo de estrutura de marcação:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;div class="w-9 h-9 rounded-lg flex items-center justify-center text-slate-700 peer-checked:font-semibold peer-checked:bg-slate-900 peer-checked:text-white"&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Eu ligo muito para estética funcional do código (beleza + facilidade de ler), &lt;em&gt;clean code&lt;/em&gt; com bom senso e organização. &lt;/p&gt;

&lt;p&gt;Ao ler o código acima, isso me causa incômodo. Acho difícil compreender rapidamente o que está acontecendo e perco o foco com todas essas classes que estão poluindo minha marcação.&lt;/p&gt;

&lt;p&gt;Na minha opinião, marcação e estilo devem ser isolados o máximo possível. Eu não preciso saber que um elemento tem posição &lt;code&gt;flex&lt;/code&gt; se não quero saber disso naquele momento.&lt;/p&gt;

&lt;p&gt;Meu pensamento foi: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tudo bem, são apenas exemplos, dá pra contornar. Vou criar uma função para lidar com isso.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;E resolvi assim:&lt;/p&gt;

&lt;p&gt;Cada componente, que continha algo estilizado, eu criei um &lt;code&gt;styles.js&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cleanClasses&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@helpers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;classNames&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;hasSomeProp&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;cleanClasses&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`
      &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;hasSomeProp&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;border-green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;border-black&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
      border
      flex
      h-9
      items-center
      justify-center
      peer-checked:bg-slate-900
      peer-checked:font-semibold
      peer-checked:text-white
      rounded-lg
      text-slate-700
      w-9
    `&lt;/span&gt;&lt;span class="p"&gt;),&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;&lt;em&gt;obs.: Sempre ordeno minhas propriedades em ordem alfabética&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;E, dentro do meu componente, importei esse arquivo e apliquei ao elemento.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;classNames&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./styles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hasSomeProp&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;classNames&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;hasSomeProp&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Resolvido, pensei eu!&lt;br&gt;
Isolo todas as classes e deixo meu componente limpo! 🤘&lt;/p&gt;

&lt;p&gt;Mas repare que no &lt;code&gt;styles.js&lt;/code&gt; tem uma função chamada &lt;code&gt;cleanClasses()&lt;/code&gt;. Eu tive que criá-la por conta da identação usando o &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals"&gt;template literals&lt;/a&gt; que estava zoando a &lt;a href="https://en.wikipedia.org/wiki/Minification_(programming)"&gt;minificação&lt;/a&gt; final do html.&lt;/p&gt;

&lt;p&gt;Para resolver, &lt;strong&gt;e manter minha identação do jeito que acho que faz sentido&lt;/strong&gt;, criei uma função para remover caracteres desnecessários que atrapalham a minificação no final do build.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;isString&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@helpers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cleanClasses&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;removeFalsyValues&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\b(?:&lt;/span&gt;&lt;span class="sr"&gt;undefined|null|false|NaN|''&lt;/span&gt;&lt;span class="se"&gt;)\b&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;removeExtraSpaces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;removeFalsyValues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cleanedClasses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;removeExtraSpaces&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cleanedClasses&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gostei da solução e me atendeu bem, mas já comecei a ficar com uma pulga atrás da orelha...&lt;/p&gt;

&lt;p&gt;Eu gosto de programar mas sou preguiçoso, quanto menos eu programo mais eu gosto de programar. 😂&lt;/p&gt;

&lt;h2&gt;
  
  
  Abstrações desnecessárias
&lt;/h2&gt;

&lt;p&gt;A documentação do &lt;em&gt;Tailwind&lt;/em&gt; começou a ser parte do meu dia a dia de trabalho. Sempre havia uma aba aberta para eu consultar e ter certeza de que tal classe era a propriedade que eu queria. &lt;/p&gt;

&lt;p&gt;E é normal, eu tenho que aprender o framework. Mas essa dependência em decorar classes, que são nomeações das propriedades (que eu já sabia &lt;em&gt;de cór&lt;/em&gt; no &lt;em&gt;CSS&lt;/em&gt;), começou a me irritar e achar as abstrações desnecessárias.&lt;/p&gt;

&lt;p&gt;De certa forma, me atrevo a dizer, estava "desdecorando" as propriedades de CSS puro.&lt;/p&gt;

&lt;p&gt;Usei esse termo de propósito pois depois de poucos meses usando &lt;em&gt;TW&lt;/em&gt;, e já migrado o projeto para CSS Modules, eu me vi adicionando classes do Tailwind ao invés das propriedades de CSS. Como são nomes parecidos, meu cérebro simplesmente acabou substituindo esses valores.&lt;/p&gt;

&lt;p&gt;Por exemplo, você sabe a qual propriedade a classe do Tailwind &lt;code&gt;justify-center&lt;/code&gt; se refere?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔘 &lt;code&gt;justify-content: center;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🔘 &lt;code&gt;justify-items: center;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🔘 &lt;code&gt;justify-self: center;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🔘 &lt;code&gt;justify-tracks: center;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dica, &lt;code&gt;justify-tracks&lt;/code&gt; ainda é experimental e nem existe no Tailwind.&lt;/p&gt;

&lt;p&gt;Se você ficou na dúvida, vai ter que ir na &lt;a href="https://tailwindcss.com/docs/justify-content"&gt;documentação&lt;/a&gt;. 🤡&lt;/p&gt;

&lt;h2&gt;
  
  
  Lidando com seletores mais complexos
&lt;/h2&gt;

&lt;p&gt;Um aspecto que não achei produtivo foi utilizar seletores mais complexos. Enquanto você estiliza apenas um único elemento é OK, mas quando precisa de algo mais complexo e que envolve outros elementos a coisa fica esquisita.&lt;/p&gt;

&lt;p&gt;Por exemplo, digamos que eu precise modificar os itens, que não tenho acesso e não posso modificá-los, de uma lista.&lt;br&gt;
&lt;em&gt;obs.: Isso está longe de ser complexo.&lt;/em&gt;&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;ul&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="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Item 1&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Item 2&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Item 3&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&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;Com Tailwind eu teria que adicionar algo como:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cleanClasses&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@helpers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;classNames&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;cleanClasses&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`
      [&amp;amp;_li]:rounded-full
      [&amp;amp;_li]:border
      [&amp;amp;_li]:border-black
      [&amp;amp;_li]:bg-white
      [&amp;amp;_li]:px-2
      [&amp;amp;_li]:py-0.5
    `&lt;/span&gt;&lt;span class="p"&gt;),&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;É muito verboso dizer que cada propriedade é um item da lista com &lt;code&gt;[&amp;amp;_li]&lt;/code&gt; e ter que informar isso, repetidas vezes, em cada classe do &lt;em&gt;TW&lt;/em&gt;. Sem falar que não consigo usar &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties"&gt;shorthand properties&lt;/a&gt;. Tem plugin pra isso, mas não quero entupir minha aplicação com pacotes.&lt;/p&gt;

&lt;p&gt;Com CSS eu apenas declaro como:&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;.ul&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;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--color__white&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--radius__full&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--color__black&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="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--size__0-5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--size__2&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;E nem vou entrar em detalhe de &lt;a href="https://tailwindcss.com/docs/hover-focus-and-other-states#styling-based-on-sibling-state"&gt;sibling selectors&lt;/a&gt; e outros seletores que são triviais com CSS nativo. Sinto-me reinventando a roda mas essa roda não é lá muito redonda. 😂&lt;/p&gt;

&lt;h2&gt;
  
  
  Temas
&lt;/h2&gt;

&lt;p&gt;Outra coisa que não gostei foi a forma de adicionar múltiplos temas e seus diversos &lt;a href="https://thedesignsystem.guide/design-tokens"&gt;design tokens&lt;/a&gt; usando o &lt;em&gt;TW&lt;/em&gt;. Pensei que ele lidaria com isso de forma nativa, mas não.&lt;/p&gt;

&lt;p&gt;Uma possibilidade é instalar mais uma dependência como a &lt;a href="https://github.com/L-Blondy/tw-colors"&gt;tw-colors&lt;/a&gt;, já que não temos isso nativamente no framework (só podemos alterar os tokens do tema atual). Ela é muito boa e funciona bem.&lt;/p&gt;

&lt;p&gt;Outra possibilidade é usar as variáveis de CSS nativas e informar ao Tailwind como usá-las... mas pera aí, eu não quero isso já que escolhi o framework para lidar com os estilos. Quero apenas usar o Tailwind e sua turminha.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cadê o efeito em cascata?
&lt;/h2&gt;

&lt;p&gt;Rapidamente aprendi que o &lt;em&gt;TW&lt;/em&gt; remove uma das coisas mais importantes do CSS (que, inclusive, é o significado da primeira letra do seu acrônimo: &lt;strong&gt;Cascade&lt;/strong&gt; Style Sheets.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;obs.: A versão usada foi a &lt;code&gt;3.3.3&lt;/code&gt;, provavelmente vão resolver isso no futuro.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Por exemplo, há situações em que você precisa sobrescrever algum estilo para customizar componentes já existentes.&lt;br&gt;
Vamos supor que você tenha um componente que é usado em vários lugares, mas, num único lugar específico, você precisa que ele tenha algo diferente e só precisa sobrescrever uma propriedade de CSS. Adicionar uma nova prop ao componente, que só vai ser usada ali, não seria uma boa ideia.&lt;/p&gt;

&lt;p&gt;No código abaixo, em função do efeito em cascata, espera-se que o valor &lt;code&gt;white&lt;/code&gt; seja substituído pelo &lt;code&gt;black&lt;/code&gt; na propriedade &lt;code&gt;background&lt;/code&gt; do &lt;code&gt;ChildComponent&lt;/code&gt;. Porque quando chamamos esse componente adicionamos um outro background que deve sobrescrever o default.&lt;/p&gt;

&lt;p&gt;Ou seja, tudo o que está declarado depois e com a mesma &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity"&gt;especificidade&lt;/a&gt;, tem uma ordem de importância maior que a propriedade anterior.&lt;/p&gt;

&lt;p&gt;A renderização da &lt;code&gt;div&lt;/code&gt; abaixo seria &lt;code&gt;&amp;lt;div class="bgWhite bgBlack" /&amp;gt;&lt;/code&gt;&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ChildComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./styles.module.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="c1"&gt;// .bgBlack { background: black; }&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ParentComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ChildComponent&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="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bgBlack&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./styles.module.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="c1"&gt;// .bgWhite { background: white; }&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ChildComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bgStyles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;white&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&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="nx"&gt;bgStyles&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Some Text
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&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;Já no Tailwind, se a renderização do seu componente for &lt;code&gt;&amp;lt;div class="bg-white bg-black" /&amp;gt;&lt;/code&gt; o &lt;code&gt;bg-black&lt;/code&gt; não necessariamente sobrescreverá o &lt;code&gt;bg-white&lt;/code&gt;, porque isso vai depender da ordem interna de classes do &lt;em&gt;TW&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Ou seja, não há garantia que o efeito cascata seja aplicado! Poxa, mas é para isso que pago o CSS! 😅&lt;/p&gt;

&lt;p&gt;Você consegue resolver isso, mas, adivinha, vai precisar acoplar mais uma dependência ao seu projeto usando o &lt;a href="https://github.com/dcastil/tailwind-merge"&gt;tailwind-merge&lt;/a&gt; que irá remover as classes indesejadas já que o efeito em cascata não funciona. Ou usar o &lt;strong&gt;!important&lt;/strong&gt;. 😒&lt;/p&gt;

&lt;h2&gt;
  
  
  Decisão após análise
&lt;/h2&gt;

&lt;p&gt;E, finalmente, como já foi dito, cheguei a conclusão que, para o meu caso, o ideal seria remover tudo relacionado ao &lt;em&gt;Tailwind&lt;/em&gt; (&lt;code&gt;tailwindcss&lt;/code&gt;, &lt;code&gt;postcss&lt;/code&gt;, &lt;code&gt;tw-colors&lt;/code&gt; e &lt;code&gt;tailwind-merge&lt;/code&gt;) e usar apenas &lt;em&gt;CSS Modules&lt;/em&gt; (já fornecido pelo &lt;em&gt;NextJs&lt;/em&gt; como padrão).&lt;/p&gt;

&lt;p&gt;Achei interessante a experiência de usar o Tailwind mas não me convenceu 100%. Tive que criar muitas soluções extras e instalações de pacotes para deixar minha experiência do jeito que acho que funciona.&lt;/p&gt;

&lt;p&gt;Para projetos de prototipação, MVPs, ou até mesmo se a equipe seja apenas de devs back-end (que não querem aprender CSS), pode ser. &lt;/p&gt;

&lt;p&gt;Mas se eu for criar um novo produto eu já descarto o uso do Tailwind. Ter um design tokens organizado com variáveis em CSS e usar CSS Modules é a escolha mais natural e eficiente pra mim. Nem de Sass eu iria. O básico bem feito é a tendência para os próximos anos, na verdade nunca deixou de ser.&lt;/p&gt;

&lt;p&gt;Enfim, voltei a ter prazer em escrever e ler CSS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgnfafcguzge2pb759slo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgnfafcguzge2pb759slo.png" alt="Print de um pull request do Github" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

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