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.