Home > Mobile >  tailwindcss dynamic border-color using template string doesn't work
tailwindcss dynamic border-color using template string doesn't work

Time:01-03

I'm using react 18, nextjs 13 with tailwindcss, postcss, autoprefixer

expect: clicking the button to toggle border-color and other styles behavior: all styles toggle except border-color

question: why doesn't border-color behave the same way as the other styles?

broken code:

import Head from 'next/head'
import { useState } from 'react'

export default function Home() {
  const [dark, darkSet] = useState(true)
  function handleClick() {
    darkSet((prev) => !prev)
  }

  const bgColor = 'bg-'   (dark ? 'black' : 'white')
  const textColor = 'text-'   (dark ? 'white' : 'black')
  const borderColor = 'border-'   (dark ? 'white' : 'black')
  const borderStyle = 'border-'   (dark ? 'solid' : 'dashed')

  return (
    <>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
      </Head>
      <main>
        <div className={`flex min-h-screen min-w-screen `}>
          <div
            className={`${bgColor} ${textColor} border-8 ${borderStyle} ${borderColor}`}
          >
            Get started by editing
          </div>
          <button onClick={handleClick} className="h-8 bg-red-500">
            theme
          </button>
        </div>
      </main>
    </>
  )
}

CodePudding user response:

Change

 const bgColor = 'bg-'   (dark ? 'black' : 'white')
  const textColor = 'text-'   (dark ? 'white' : 'black')
  const borderColor = 'border-'   (dark ? 'white' : 'black')
  const borderStyle = 'border-'   (dark ? 'solid' : 'dashed')

to

 const bgColor = dark ? 'bg-black' : 'bg-white'
  const textColor = dark ? 'text-white' : 'text-black'
  const borderColor = dark ? 'border-white' : 'border-black'
  const borderStyle = dark ? 'border-solid' : 'border-dashed'

Explanation:

Is it recommended to use dynamic class in tailwind ?

No

Using dynamic classes in tailwind-css is usually not recommended because tailwind uses tree-shaking i.e any class that wasn't declared in your source files, won't be generated in the output file.

Hence it is always recommended to use full class names

According to [Docs][1]

If you use string interpolation or concatenate partial class names together, Tailwind will not find them and therefore will not generate the corresponding CSS

Isn't there work around ?

Yes

As a last resort, Tailwind offers [Safelisting classes][2].

Safelisting is a last-resort, and should only be used in situations where it’s impossible to scan certain content for class names. These situations are rare, and you should almost never need this feature.

You can use [regular expressions][3] to include all the colors you want using pattern

Note: You can force Tailwind to create variants as well:

In tailwind.config.js

module.exports = {
  content: [
    './pages/**/*.{html,js}',
    './components/**/*.{html,js}',
  ],
  safelist: [
    {
      pattern: /bg-(red|green|blue|orange)/, // You can display all the colors that you need
      variants: ['lg', 'hover', 'focus', 'lg:hover'],      // Optional
    },
  ],
  // ...
}

CodePudding user response:

update: this still doesn't work for colors other than black/white, what is going on here?

solution: as per tailwindcss docs

Don't construct class names dynamically

Always use complete class names

https://tailwindcss.com/docs/content-configuration#dynamic-class-names

working code:

// ...
  const bgColor = dark ? 'bg-black' : 'bg-white'
  const textColor = dark ? 'text-white' : 'text-black'
  const borderColor = dark ? 'border-white' : 'border-black'
  const borderStyle = dark ? 'border-solid' : 'border-dashed'
// ...

the difference is that the entire utility class is conditionally constructed then inserted into the template string literal in the jsx className attribute.

question: I still want to know why this border-color case is different as I've run into a few cases like this when conditionally constructing the utility classes.

  • Related