A fullstack solution for structuring TailwindCSS classnames
Published: 2023-08-30 15:12:29

After a neither long nor short time for developing Next.js + TailwindCSS app, it is so annoyed at writing TailwindCSS classnames more and more big.

A React example:

```tsx
export const Demo = () => (
  <div className='flex flex-col items-start justify-start md:mt-24 md:flex-row md:items-center md:justify-center md:space-x-6'>
    <div className='space-x-2 pb-8 pt-6 md:space-y-5'>
      <h1 className='text-6xl font-extrabold leading-9 tracking-tight text-gray-900 dark:text-gray-100 md:border-r-2 md:px-6 md:text-8xl md:leading-14'>
        404
      </h1>
    </div>
    <div className='max-w-md'>
      <p className='mb-4 text-xl font-bold leading-normal md:text-2xl'>
        {`Sorry we couldn't find this page.`}
      </p>
      <p className='mb-8'>
        {`But don't worry, you can find plenty of other things on our homepage.`}
      </p>
    </div>
  </div>
)

```

**Question:** How to make the code looks more nicer?

**Answer:** After use the new born package [tagged-classnames-free](https://github.com/yunsii/tagged-classnames-free):

```tsx
import { cls } from 'tagged-classnames-free'

export const Demo = () => (
  <div
    className={cls`
      flex flex-col items-start justify-start 
      md:mt-24 md:flex-row md:items-center md:justify-center md:space-x-6
    `}
  >
    <div className='space-x-2 pb-8 pt-6 md:space-y-5'>
      <h1
        className={cls`
          text-6xl font-extrabold leading-9 tracking-tight text-gray-900
          dark:text-gray-100 
          md:border-r-2 md:px-6 md:text-8xl md:leading-14 
        `}
      >
        404
      </h1>
    </div>
    <div className='max-w-md'>
      <p
        className={cls`
          mb-4 text-xl font-bold leading-normal 
          md:text-2xl
        `}
      >
        {`Sorry we couldn't find this page.`}
      </p>
      <p className='mb-8'>
        {`But don't worry, you can find plenty of other things on our homepage.`}
      </p>
    </div>
  </div>
)
```

`cls` tag based on [clsx](https://github.com/lukeed/clsx), and `tw` tag integrated [tailwind-merge](https://github.com/dcastil/tailwind-merge) already.

**Question:** How to auto indent/dedent strings in tagged template if I want to wrap/unwrap tagged classnames by functions or html tags?

**Answer:** [ESLint](https://eslint.org/) is a awesome tool, [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) has a [template-indent](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/template-indent.md) rule for us to auto indent/dedent.

It is also compatiable with [prettier-plugin-tailwindcss](https://github.com/tailwindlabs/prettier-plugin-tailwindcss) even if write classnames by multiple lines.

**Question:** What is the impact on runtime performance, especially for what could have been wrote by pure strings?

**Answer:** There is also a new born [unplugin-polish-tagged-templates](https://github.com/yunsii/unplugin-polish-tagged-templates) for this, It can transform tagged templates without expressions into pure strings at compile time.

*Try overall features on [Gitpod](https://gitpod.io/#https://github.com/yunsii/tagged-classnames-free).*