106

I am currently building a component library for my next project with Tailwind CSS, I just ran into a small issue when working on the Button component.

I'm passing in a prop like 'primary' or 'secondary' that matches a color I've specified in the tailwind.config.js then I want to assign that to the button component using Template literals like so: bg-${color}-500

<button
  className={`
    w-40 rounded-lg p-3 m-2 font-bold transition-all duration-100 border-2 active:scale-[0.98]
    bg-${color}-500
  `}
  onClick={onClick}
  type="button"
  tabIndex={0}
>
  {children}
</button>

The class name comes through in the browser just fine, it shows bg-primary-500 in the DOM, but not in the applied styles tab.

enter image description here

The theming is configured like so:

/** @type {import('tailwindcss').Config} */
export default {
  theme: {
    extend: {
      colors: {
        primary: {
          500: '#B76B3F',
        },
        secondary: {
          500: '#344055',
        },
      },
    },
  },
}

But it doesn't apply any styling. If I just add bg-primary-500 manually it works fine.

I'm honestly just wondering if this is because of the JIT compiler not picking dynamic class names up or if I'm doing something wrong (or this is just NOT the way to work with Tailwind CSS).

5

20 Answers 20

51

So after finding out that this way of working is not recommended and that JIT doesn't support it (Thanks to the generous commenters). I have changed the approach to a more 'config' based approach.

Basically I define a const with the basic configuration for the different props and apply those to the component. It's a bit more maintenance work but it does the job.

Here is the example of a config. (Currently without typing) and up for some better refactoring but you'll get the idea.

const buttonConfig = {
  // Colors
  primary: {
    bgColor: 'bg-primary-500',
    color: 'text-white',
    outline:
      'border-primary-500 text-primary-500 bg-opacity-0 hover:bg-opacity-10',
  },
  secondary: {
    bgColor: 'bg-secondary-500',
    color: 'text-white',
    outline:
      'border-secondary-500 text-secondary-500 bg-opacity-0 hover:bg-opacity-10',
  },

  // Sizes
  small: 'px-3 py-2',
  medium: 'px-4 py-2',
  large: 'px-5 py-2',
};

Then I just apply the styling like so:

  <motion.button
    whileTap={{ scale: 0.98 }}
    className={`
    rounded-lg font-bold transition-all duration-100 border-2 focus:outline-none
    ${buttonConfig[size]}
    ${outlined && buttonConfig[color].outline}
    ${buttonConfig[color].bgColor} ${buttonConfig[color].color}`}
    onClick={onClick}
    type="button"
    tabIndex={0}
  >
    {children}
  </motion.button>
Sign up to request clarification or add additional context in comments.

5 Comments

It's even possible to just add the tailwind classes (you want to have included for dynamic usage) as comments somewhere in your code. Allows using bg-${color}-100 text-${color}-500 as long as u mention bg-accent-100 text-accent-500 in a comment somewhere for every color that you want to include.
@morganney This was for a small personal project, I like to educate myself on all the front-end frameworks in how they work and what the caveats are. I still think you can build really flexible and scalable front-ends with TailWind, it's just how you set it up and decide to use it. And as statet below, this isn't really an issue anymore since the latest updates.
@morganney This is hardly a significant problem
@forresthopkinsa It is a significant problem if you try to generate lots of dynamic class strings. Your bundle size will be massive, because you will end up safelisting a large proportion of all tailwindcss classes.
@WesleyJanse I was just doing some more asking around and experimenting with this. It appears, if you are in an SSR context, you can run postcss with the tailwind plugin on rendered HTML. And, the performance hit doesn't appeared to be significant (< 100ms). This allows you to use dynamic classnames, so long as (1) you're using a proper SSR framework like Nuxt and (1.1) Javascript which changes the classnames at browser runtime aren't included in the bundle.
43

this might be a bit late, but for the people bumping this thread.

the simplest explaination for this is;

Dynamic Class Name does not work unless you configured Safelisting for the Dynamic class name,

BUT, Dynamic Class works fine so long as its a full tailwind class name.

its stated here

this will not work

<div class="text-{{ error ? 'red' : 'green' }}-600"></div>

but this one works

<div class="{{ error ? 'text-red-600' : 'text-green-600' }}"></div>

its states;

As long as you always use complete class names in your code, Tailwind will generate all of your CSS perfectly every time.

the longer explanation;

Tailwind will scan all the files specified in module.exports.content inside tailwind.config.js and look for tailwind classes, it does not even have to be in a class attribute and can even be added in commented lines, so long as the full class name is present in that file and class name is not dynamically constructed; Tailwind will pull the styling for that class,

so in your case, all you have to do is put in the full class name inside that file for all the possible values of your dynamic class something like this

<button className={ color === 'primary' ? 'bg-primary-500' : 'bg-secondary-500'}>
    {children}
</button>

or the method I would prefer

<!-- bg-primary-500 bg-secondary-500 -->
<button className={`bg-${color}-500 `}>
    {children}
</button>

here's another example, although its Vue, the idea would be the same for any JS framework

<template>
    <div :class="`bg-${color}-100 border-${color}-500 text-${color}-700 border-l-4 p-4`" role="alert">
        test
    </div>
</template>
<script>
    /* all supported classes for color props 
    bg-red-100 border-red-500 text-red-700
    bg-orange-100 border-orange-500 text-orange-700
    bg-green-100 border-green-500 text-green-700
    bg-blue-100 border-blue-500 text-blue-700
    */
    export default {
        name: 'Alert',
        props: {
            color: {type: String, default: 'red'}
        }
    }
</script>

and the result would be this

<Alert color="red"></Alert> <!-- this will have color related styling-->
<Alert color="orange"></Alert> <!-- this will have color related styling-->
<Alert color="green"></Alert> <!-- this will have color related styling-->
<Alert color="blue"></Alert> <!-- this will have color related styling-->
<Alert color="purple"></Alert> <!-- this will NOT have color related styling as the generated classes are not pre-specified inside the file -->

Comments

31

this way of writing Tailwind CSS classes is not recommended. Even JIT mode doesn't support it, to quote Tailwind CSS docs: "Tailwind doesn’t include any sort of client-side runtime, so class names need to be statically extractable at build-time, and can’t depend on any sort of arbitrary dynamic values that change on the client"

Comments

14

EDIT: Better implementation 2022 - https://stackoverflow.com/a/73057959/11614995

Tailwind CSS does not support dynamic class names (see here). However, there's still a way to accomplish this. I needed to use dynamically build class names in my Vue3 application. See the code example below.

Upon build tailwind scanes your application for classes that are in use and automatically purges all other classes (see here). There is however a savelist feature that you can use to exclude classes from purging - aka they will always make it to production.

I have created a sample code below, that I use in my production. It combines each color and each color shade (colorValues array).

This array of class names is passed into the safelist. Please note, that by implementing this feature you ship more css data to production as well as ship css classes you may never use.

const colors = require('./node_modules/tailwindcss/colors');
const colorSaveList = [];
const extendedColors = {};
const colorValues = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900];

for (const key in colors) {
  

  // To avoid tailWind "Color deprecated" warning
  if (!['lightBlue', 'warmGray', 'trueGray', 'coolGray',  'blueGray'].includes(key))
  {
    extendedColors[key] = colors[key];
    for(const colorValue in colorValues) {
       colorSaveList.push(`text-${key}-${colorValue}`);
       colorSaveList.push(`bg-${key}-${colorValue}`);
    }
  }
}


module.exports = {
  content: [
    "./index.html",
    "./src/**/*.{vue,js,ts,jsx,tsx}"
  ],
  safelist: colorSaveList,
  theme: {
   extend: {
      colors: extendedColors
   }
  },
  plugins: [
    require('tailwind-scrollbar'),
  ]

}

4 Comments

I wonder if safelist is a better alternative then auto-generating all the possible combinations in a helper function and then simply call that function to dynamically look up the classnames. I wrote this gist regarding the topic: gist.github.com/tahesse/345830247456980d1c8ac6e53a2dd879
@tahesse I like your solution. It could be used as an external script or "plugin" for other devs. My code is more like a hotfix or a quickfix. As you mention in the gist you have to call into account the classes you might not use. But still, you can modify my solution to only use classes that you want and safeList them. I find my solution quite easy as you take advantage of a feature already included in TailWindCSS. So to answer your question. I think it's "cleaner" to use my solution insted of writing CSS classes directly to the file via node fs. But still, it's just my opinion.
this is no longer working in 2022 I believe. Added an updated version in a post below
It's still working in 2022. We use it in our production codebase. I have added a link to your implementation to my original anwer as I find it better. Thanks for tweaking my code. :)
9

If someone comes across in 2022 - I took A. Mrózek's answer and made a couple of tweaks to avoid deprecated warnings and an issue with iterating non-object pallettes.

const tailwindColors = require("./node_modules/tailwindcss/colors")
const colorSafeList = []

// Skip these to avoid a load of deprecated warnings when tailwind starts up
const deprecated = ["lightBlue", "warmGray", "trueGray", "coolGray", "blueGray"]

for (const colorName in tailwindColors) {
  if (deprecated.includes(colorName)) {
    continue
  }

  const shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900]

  const pallette = tailwindColors[colorName]

  if (typeof pallette === "object") {
    shades.forEach((shade) => {
      if (shade in pallette) {
        colorSafeList.push(`text-${colorName}-${shade}`)
        colorSafeList.push(`bg-${colorName}-${shade}`)
      }
    })
  }
}

// tailwind.config.js
module.exports = {
  safelist: colorSafeList,
  content: ["{pages,app}/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {
      colors: tailwindColors,
    },
  },
  plugins: [],
}

Comments

8

For tailwind JIT mode or v3 that uses JIT, you have to ensure that the file where you export the object styles is included in the content option in tailwind.config.js, e.g.

 content: ["./src/styles/**/*.{html,js}"], 

3 Comments

I had the same problem and this is actually what I was missing out : I had my utility classes imported from a local data object stored in a custom folder, so that Tailwind couldn't reference them. I just had to complete the "content" array with my file.
Thanks for letting me know, haven't looked into Tailwind V3. So I don't know what's the better approach right now
It's not about tailwind v3 only, it's just the JIT mode.
7

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 Tailwind-css docs

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.

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.

In your example,you want to have 100 500 700 shades of colors. You can use regular expressions to include all the colors you want using pattern and specify the shades accordingly .

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)-(100|500|700)/, // You can display all the colors that you need
      variants: ['lg', 'hover', 'focus', 'lg:hover'],      // Optional
    },
  ],
  // ...
}
EXTRA: How to automate to have all tailwind colors in the safelist
const tailwindColors = require("./node_modules/tailwindcss/colors")
const colorSafeList = []

// Skip these to avoid a load of deprecated warnings when tailwind starts up
const deprecated = ["lightBlue", "warmGray", "trueGray", "coolGray", "blueGray"]

for (const colorName in tailwindColors) {
  if (deprecated.includes(colorName)) {
    continue
  }

  // Define all of your desired shades
  const shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900]

  const pallette = tailwindColors[colorName]

  if (typeof pallette === "object") {
    shades.forEach((shade) => {
      if (shade in pallette) {
       // colorSafeList.push(`text-${colorName}-${shade}`)  <-- You can add different colored text as well 
        colorSafeList.push(`bg-${colorName}-${shade}`)
      }
    })
  }
}

// tailwind.config.js
module.exports = {
  safelist: colorSafeList,                      // <-- add the safelist here
  content: ["{pages,app}/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {
      colors: tailwindColors,
    },
  },
  plugins: [],
}

Note: I have tried to summarize the answer in all possible ways, In the combination of all possible answers.Hope it helps

1 Comment

This should be the correct answer for this question
5

2023 Update

The TailwindUI library (created by Tailwind) uses a handy little helper function which you can define in your app (no dependencies required):

export function classNames(...classes) {
  return classes.filter(Boolean).join(' ')
}

Then in any file you can simply add together strings of classes:

className={
  classNames(
    // This could be a string representing classes passed into the component
    "flex flex-col",
    primary ? "bg-teal-600" : "bg-white",
    active ? 'bg-slate-100' : '',
  )
}

Comments

4

In Nextjs 13.4+ with tailwind you can use combination of both clsx & twMerge

clsx: For Object based className

const [pending, setPending] = useState(false);
<button className={ 
    "px-4", 
    {
       "bg-blue-500":pending, // if pending is true apply blue background
    }
  }
/>

twMerge: For effectively merging tailwind classes,

<button className={twMerge(
    "bg-blue-500 px-4",
    "bg-black"
   )}
/>

Utility Function /lib/utils.ts

import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
 
export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

Use it as page.tsx


import { cn } from "@/lib/utils";
export default function Component(){
   return <div className={cn(
              "bg-black font-sans",
              "bg-white h-full", 
               {
                 "px-5":pending, // if pending is true apply padding
               }
           )}
         />
}

For further refer: cn() - Every Tailwind Coder Needs It (clsx + twMerge)

Comments

2

In v3 as Blessing said you can change the content array to support that.

I had this

const PokemonTypeMap = {
  ghost: {
    classes: "bg-purple-900 text-white",
    text: "fantasma",
  },
  normal: {
    classes: "bg-gray-500 text-white",
    text: "normal",
  },
  dark: {
    classes: "bg-black text-white",
    text: "siniestro",
  },
  psychic: {
    classes: "bg-[#fc46aa] text-white",
    text: "psíquico",
  },
};

function PokemonType(props) {
  const pokemonType = PokemonTypeMap[props.type];

  return (
    <span
      className={pokemonType.classes + " p-1 px-3 rounded-3xl leading-6 lowercase text-sm font-['Open_Sans'] italic"}
    >
      {pokemonType.text}
    </span>
  );
}

export default PokemonType;

something similar to your approach, then I moved the array to a JSON file, it thought was working fine, but was browser caché... so following Blessing's response, you can add .json like this

content: ["./src/**/*.{js,jsx,ts,tsx,json}"],

Finally I have this code, it's better in my view.

import PokemonTypeMap from "./pokemonTypeMap.json";

function PokemonType(props) {
  const pokemonType = PokemonTypeMap[props.type];
    
  return (
    <span className={pokemonType.classes + " p-1 px-3 rounded-3xl leading-6 lowercase text-sm font-['Open_Sans']"}>
      {pokemonType.text}
    </span>
  );
}
    
export default PokemonType;

Comments

2

Now could use safeListing

and tailwind-safelist-generator package to "pregenerate" our dynamics styles.

With tailwind-safelist-generator, you can generate a safelist.txt file for your theme based on a set of patterns.

Tailwind's JIT mode scans your codebase for class names, and generates CSS based on what it finds. If a class name is not listed explicitly, like text-${error ? 'red' : 'green'}-500, Tailwind won't discover it. To ensure these utilities are generated, you can maintain a file that lists them explicitly, like a safelist.txt file in the root of your project.

Comments

2

I was able to dynamically use the classes that weren't included in my code while compiling by safe-listing them in tailwind config:

const colors = {
  red: ['red-500', 'red-700', 'red-900'],
  blue: ['blue-500', 'blue-700', 'blue-900'],
};

// Construct the safelist using these constants
const safelistClasses = [
  ...colors.red.map(color => `bg-${color}`),
  ...colors.blue.map(color => `text-${color}`),
];

module.exports = {
  content: [
    './pages/**/*.js',
    './components/**/*.js'
  ],
  safelist: safelistClasses
  // other config options...
}

Comments

2

I had faced a similar issue while implementing custom/generic classnames/styles to components dynamically You could use safe list parameter in the tailwindcss config file and add the custom or generic classnames that you want to apply. Safe list basically ensures that the classes mentioned in it are not removed during the purge process. since tailwind uses a purging process to remove unused styles from the final CSS file, which helps to keep the file size small and performance optimal. However, sometimes you might have classes that are dynamically generated or conditionally applied and are not present in your source files at build time. These classes could be mistakenly purged if not explicitly safelisted.

Here is how you can declare safelist in your tailwind config file:

module.exports = {
  content: [
    './src/**/*.{js,jsx,ts,tsx}', // Defines where the styles of tailwind are to be applied
  ],
  safelist: [
    'bg-red-500',
    'text-center',
    'hover:bg-blue-500',
    'md:grid-cols-4',
    // Add any other classes you need to safelist
  ],
  // Other Tailwind configurations...
};

if you have defined classes that follow some sort of patterns, you can use regular expressions as well to safelist those:

safelist: [
  'bg-red-500',
  'text-center',
  'hover:bg-blue-500',
  'md:grid-cols-4',
  {
    pattern: /bg-(red|green|blue|yellow)-500/,
    variants: ['hover', 'focus'],
  },
  // Add any other classes you need to safelist
],

if you want to safelist the general classes of tailwindcss, you could safelist those using the regular expression syntax

safelist: [
  {
    pattern: /bg-(red|blue|green|yellow)-500/,
    variants: ['hover'],
  },
],

1 Comment

THIS should be the right answer: no hacks, just using the configuration. Thanks a lot!
1

You can do it like this in Astro

https://tailwindcss.com/docs/adding-custom-styles#resolving-ambiguities

<style is:global define:vars={{themeColor: render_value(siteinfo, 'theme_color')}}>
</style>

<div class="bg-[var(--themeColor)]">
  <!-- ... -->
</div>

1 Comment

This is such a clever hack! You "just" have to reactively render your color palette into global CSS vars and can keep using Tailwind without having to resort back to inline styles
1

Most answers related to TailwindCSS v3 apply to this question, but the guideline has not changed: Do not use dynamically class names!

You can find the official explanation in the documentation. I won't repeat the v3 examples here, as the following answers are already good references for that.

In v4, however, the possibilities have expanded and safelisting has changed. That's what I'd like to explain in detail.

Safelist

Specifically, the patterns in them answer can be written like this in v4:

@import "tailwindcss";

@source inline "text-{red,green,blue}-700";
@source inline "bg-{red,green,blue}-300";

And by combining bg, text and hover: variant from 50 to 950, the example would look like this:

@import "tailwindcss";

@source inline "{hover:,}{text,bg}-{red,green,blue}-{50,{100..900..100},950}";

Static theme variables

In addition to all this, a so-called static theme declaration option has been introduced. It doesn't generate the utilities themselves but places the corresponding variables into the generated CSS, making it easier to use those variables more dynamically even without utilities:

@import "tailwindcss";

@theme static {
  --color-primary: var(--color-red-500);
  --color-secondary: var(--color-blue-500);
}

Now, if you haven't used the primary color in any form - for example, neither bg-primary nor text-primary nor in any other way - then originally var(--color-primary) would not be included in the generated CSS by @theme { ... }. However, due to the @theme static { ... } static import, it still gets included.

import React from "react";

type ExampleProps = {
  type: "primary" | "secondary";
};

export default function Example({ type }: ExampleProps) {
  return (
    <p style={{ color: `var(--color-${type})` }}>
      This text uses {type} color
    </p>
  );
}
<Example type="primary" />
<Example type="secondary" />

Important: text-${type} class name is still invalid! Keep in mind that the examples use CSS variables, which work independently of TailwindCSS.

And extending the previous example full of variables, I'll move on to using TailwindCSS classes that don't take a direct value, but instead reference a variable name. This way, the variable name itself is static and never changes, while the value carried by the variable can still be manipulated with JS.

For example, instead of bg-sky-500 you can use bg-(--color-sky-500). Or you can declare your own variable like bg-(--currentcolor) and then set the actual value of the --currentcolor variable via the style attribute: --currentcolor: var(--color-primary); (which I marked earlier as static).

Example

Here's an incorrect example (DO NOT USE):

{/* IMPORTANT: DO NOT USE IT, this is just an example of incorrect usage */}
<div
  class={"
    col-start-${colStart} col-end-${colEnd}
    row-start-${rowStart} row-end-${rowEnd}
    ...
  "}
>...</div>

What the correct approach could look like.

You can avoid using Tailwind utilities - it's not wrong to solve something with native CSS, and this way the value can be dynamic.

<div
  class={"..."}
  style={{
    gridColumnStart: colStart,
    gridColumnEnd: colEnd,
    gridRowStart: rowStart,
    gridRowEnd: rowEnd
  }}
>...</div>

Or give the utilities a reference to a CSS variable. Then, in the style, declare the appropriate variables instead of using property.

<div
  class={"
    col-start-(--col-start) col-end-(--col-end)
    row-start-(--row-start) row-end-(--row-end)
    ...
  "}
  style={{
    '--col-start': colStart,
    '--col-end': colEnd,
    '--row-start': rowStart,
    '--row-end': rowEnd
  }}
>...</div>

2 Comments

Or use pre-declared enums: stackoverflow.com/a/78979537/15167500
0

I had a similar issue, instead of passing all the possible configs, I just pass the data to the style property of the HTML. This is far more efficient!

or

Pass a class name as a prop and let the user of the package write the styles to that class.

const CustomComp = ({
  keyColGap = 0,
  keyRowGap = 0,
  className = '',
}: Props) => {
  const classNameToRender = (): string => {
    return `m-1 flex flex-col ${className}`.trim();
  };

  const rowStylesToRender = (): React.CSSProperties | undefined => {
    const styles: React.CSSProperties | undefined = { gap: `${keyRowGap}rem` };

    return styles;
  };

  const colStylesToRender = (): React.CSSProperties | undefined => {
    const styles: React.CSSProperties | undefined = { gap: `${keyColGap}rem` };

    return styles;
  };

return (
  <div className={classNameToRender()} style={rowStylesToRender()}>
    {layout.map((row) => {
    return (
      <div
        className={`flex justify-around`}
        style={colStylesToRender()}
        key={row}
      >
        /* Some Code */
      </div>
    );
  })}
  </div>
}

Comments

0

I might be a bit late to the party, but here are my two cents. Now, here's the definition of the Button component.

import clsx from 'clsx';

const baseStyles = 'rounded border p-2';

const variantStyles = {
  primary: 'bg-primary-500', // References your theme configuration
  secondary: 'bg-secondary-500',
};

type ButtonProps = (
  | {
      variant?: 'primary';
    }
  | {
      variant: 'secondary';
    }
) &
  React.ComponentPropsWithoutRef<'button'>;

export default function Button({ children, className, variant }: ButtonProps) {
  return (
    <button
      className={clsx(
        baseStyles,
        variant ? variantStyles[variant] : undefined,
        className
      )}
    >
      {children}
    </button>
  );
}

There are situations where you'd apply multiple styles based on certain criteria. I'll organize these styles into what I'll call a variant. The button properties will extend the standard HTML attributes along with our custom variants. You can now use the component like this:

import Button from '../components/Button';

export default function Home() {
  return (
    <div className="flex flex-col gap-4">
      <Button variant="primary" className="hover:opacity-90">
        Primary Button
      </Button>
      <Button variant="secondary" className="hover:opacity-90">
        Secondary Button
      </Button>
    </div>
  );
}

The clsx utility lets you conditionally apply styles using JavaScript. Additionally, the Button component includes a className prop, allowing you to further extend its base styles. I gave it a run, and it worked the way it should.

Interested in trying out the interactive coding environment? Check this out!

Dynamic Styles with Tailwindcss

Comments

0

Simplest - just add comment with all possible dynamic styles in any component file:

// HACK to make dynamic styles work:
// bg-habr bg-github !bg-instagram !bg-linkedin

Comments

0

Tailwind classes with JS template literals

enter image description here

When colors ( styles ) are driven from the config (JS).

The below pattern didn't work ❌ ( Refer to top Cards in the image with no background colors )

const cardsWithNoColors = [
  {
    id: '1',
    title: 'Card 1',
    value: 'Body 1',
    cardBg: 'yellow',
  },
  {
    id: '2',
    title: 'Card 2',
    value: 'Body 2',
    cardBg: 'orange',
  },
  {
    id: '3',
    title: 'Card 3',
    value: 'Body 3',
    cardBg: 'indigo',
  },
];

<div className={`bg-[${cardBg}]`}>

Fix here

Change ( Refer to Bottom Cards in the image with background colors )

cardBg: 'yellow' 👉 cardBg: 'bg-[yellow]'
<div className={`bg-[${cardBg}]`}>  👉 <div className={`${cardBg}`}>

tailwind dynamic colors

Comments

0

While this is a thread is a bit older I still had this issue in 2024. I found a simple work around for a dynamic class to create a constructor function. In my case I needed to set the image width dynamically based on the screen size and value saved in my database.

function tailwindClassConstructorWidth(width: string) {
  return `w-[${width}]`;
}

---
const tailWindWidth = tailwindClassConstructorWidth(dataWidth);

const widthClass = dataWidth ? `sm:${tailWindWidth} w-full` : 'w-full';

return (
  <div className="mx-auto flex max-w-[672px]">
    <div
      className={`relative h-auto ${widthClass} ${alignClass}`}
    >
      <Image
        src={src}
        alt={alt || 'image'}
        width={0}
        height={0}
        sizes="100vw"
        className="h-auto w-full"
        style={{
          borderRadius: borderRadius || '0px'
        }}
      />
    </div>
  </div>
)

note i pass the width to my constructor function as a string like '40%'

Hope this helps if anyone comes across this issue.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.