English

Hello! Already using or planning to try Tailwind CSS? You’re in the right place. I’ll share some important things about Tailwind CSS.

It’s not strictly “best practices.” It’s more of coding styles and tips that help me work comfortably with Tailwind CSS.

It’s opinionated, but hopefully you’ll find something useful.


Coding Style

Here are the coding styles I often use for Tailwind CSS classes, split into 3 key points: sorting, splitting, and grouping.

Sorting

Check out this Button component—look how long the class list is 😂

<button
  class="inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150 hover:bg-purple-700 md:rounded-xl dark:bg-purple-600 dark:hover:bg-purple-500"
>
  Button Text
</button>

Since we often deal with lots of classes on a single element, sorting classes is pretty important.

Fortunately, Tailwind CSS provides a Prettier plugin to handle this.

Consistent class ordering makes maintenance easier down the line.

For example, when classes are sorted, it’s easy to change border and border-transparent since they’re next to each other.

Or quickly tweak hover: styles or breakpoints since they usually appear at the end.

Splitting

To keep things tidy, split classes into multiple strings/lines (so they don’t look too long). I typically use clsx.

Here’s a Button component using clsx:

function Button({ children }) {
  return (
    <button
      className={clsx(
        'inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150 hover:bg-purple-700 md:rounded-xl',
        'dark:bg-purple-600 dark:hover:bg-purple-500'
      )}
    >
      {children}
    </button>
  );
}

Grouping

After splitting, we can group them to make it cleaner and more readable.

The pattern I use is usually:

  • group 1: default utilities
  • group 2: breakpoint utilities
  • group 3: dark mode utilities
  • group 4: other variant utilities

Let’s implement it using the Button component above:

function Button({ children }) {
  return (
    <button
      className={clsx(
        // group 1
        'inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150',
        // group 2
        'md:rounded-xl',
        // group 3
        'dark:bg-purple-600 dark:hover:bg-purple-500',
        // group 4
        'hover:bg-purple-700'
      )}
    >
      {children}
    </button>
  );
}

Same idea with a CSS component:

.button {
  /* group 1 */
  @apply inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150;
  /* group 2 */
  @apply md:rounded-xl;
  /* group 3 */
  @apply dark:bg-purple-600 dark:hover:bg-purple-500;
  /* group 4 */
  @apply hover:bg-purple-700;
}

Groups 2, 3, and 4 can be adjusted or improved to fit your needs—just make sure you keep it consistent.


Tips

Use Components

If several elements share the same styles, extract them into a dedicated component—buttons often fall into this case.

Since I use React, I can create a component like this:

function Button({ children }) {
  return (
    <button
      className={clsx(
        'inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150',
        'md:rounded-xl',
        'dark:bg-purple-600 dark:hover:bg-purple-500',
        'hover:bg-purple-700'
      )}
    >
      {children}
    </button>
  );
}

Use Class Component

Similar to components, but this approach optimizes HTML size/output—especially for static sites.

Long Tailwind class lists add weight to your HTML.

Consider this simple example—reusing the same utility set across pagination buttons:

<button
  class="inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150 hover:bg-purple-700 md:rounded-xl dark:bg-purple-600 dark:hover:bg-purple-500"
>
  Previous
</button>
<button
  class="inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150 hover:bg-purple-700 md:rounded-xl dark:bg-purple-600 dark:hover:bg-purple-500"
>
  1
</button>
<button
  class="inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150 hover:bg-purple-700 md:rounded-xl dark:bg-purple-600 dark:hover:bg-purple-500"
>
  2
</button>
<button
  class="inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150 hover:bg-purple-700 md:rounded-xl dark:bg-purple-600 dark:hover:bg-purple-500"
>
  3
</button>
<button
  class="inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150 hover:bg-purple-700 md:rounded-xl dark:bg-purple-600 dark:hover:bg-purple-500"
>
  4
</button>
<button
  class="inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150 hover:bg-purple-700 md:rounded-xl dark:bg-purple-600 dark:hover:bg-purple-500"
>
  Next
</button>

Imagine multiple paginations in a single HTML page—the file size grows quickly!

To reduce HTML size, convert them into a class component. Here’s how it looks:

<button class="pagination-button">Previous</button>
<button class="pagination-button">1</button>
<button class="pagination-button">2</button>
<button class="pagination-button">3</button>
<button class="pagination-button">4</button>
<button class="pagination-button">Next</button>

I’ve covered this here (see “Heavier HTML”).

Using !important

As with regular CSS, avoid using !important as much as possible.

In Tailwind CSS, you can add !important by prefixing utilities with !, e.g., !p-2 !px-3.

Avoid it if you can—once you start, you may overuse it everywhere, making future style changes hard.

Conditional Class

Don't
<div className={`text-black ${dark && 'text-white'}`}>
  Hello, World!
</div>
Do
<div className={dark ? 'text-white' : 'text-black'}>
  Hello, World!
</div>

Let me explain a bit.

Let’s say we use the first approach and dark is true, the resulting classes will be text-black text-white.

In some cases, that might work as intended. But in other cases, it can be problematic!

The text could still appear black even when dark is true.

Why? Let the code speak:

<!-- Some elements within the project. -->

<div class="text-white">White!</div>
<div class="text-black">Black!</div>

<!-- 
  The above elements will generate CSS in the following order:

  .text-white {
    ...
  }
  .text-black {
    ...
  }
-->

<!--
  Imagine that "dark" is set to true, and use a class defined as follows for conditional class:
      class={`text-black ${dark && 'text-white'}`}
-->
<div class="text-black text-white">Still black? CSS Specificity!</div>

<!-- 
  That's because, in this example, both "text-black" and "text-white" have the same CSS properties and specificity.
  
  On the other hand, the last one defined in the CSS file (in the previously generated CSS) will take precedence!
-->

Tailwind Play

0
0
0
0