quasi
quasi

Reputation: 103

Conditionally set background color in React component with Tailwind CSS

I am trying to use a hex color code passed through props to set the background color of a div. These are one-off colors that are generated dynamically, so cannot be added as a theme extension in tailwind.config.

I thought a template literal would be the best way to achieve this, but have not been able to get this to work with arbitrary color values in Tailwind CSS.

interface Props {
  color: string;
}

const ColorSwatch = ({ color }: Props) => {
  return (
    <div className="flex flex-col gap-1 p-2">
      <div
        className={`h-20 w-20 border border-gray-400 shadow-md bg-[${color}]`}
      ></div>
      <p className="text-center">{color}</p>
    </div>
  );
};

export default ColorSwatch;

Pasting the hex color code directly into the className list produces expected results, but trying to use the prop value in a template literal results in a transparent background (no background effect applied).

Looking for advice on how to correct this or different approaches to dynamically setting background color with a hex code passed through props.

Upvotes: 9

Views: 13896

Answers (2)

Jurakin
Jurakin

Reputation: 1084

From tailwind docs:

Dynamic class names

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

Don't construct class names dynamically

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

In the example above, the strings text-red-600 and text-green-600 do not exist, so Tailwind will not generate those classes.

Instead, make sure any class names you’re using exist in full:

Always use complete class names

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

Always map props to static class names

function Button({ color, children }) {   const colorVariants = {
    blue: 'bg-blue-600 hover:bg-blue-500',
    red: 'bg-red-600 hover:bg-red-500',   }

  return (
    <button className={`${colorVariants[color]} ...`}>
      {children}
    </button>   ) }

Upvotes: 2

christiandrey
christiandrey

Reputation: 491

Unfortunately, Tailwind requires the color to be hardcoded into the className prop as it cannot compute arbitrary styles from dynamic className values.

Your best bet would be to set the background color using the style prop as shown below;

interface Props {
  color: string;
}

const ColorSwatch = ({ color }: Props) => {
  return (
    <div className="flex flex-col gap-1 p-2">
      <div
        className="h-20 w-20 border border-gray-400 shadow-md"
        style={{backgroundColor: color}}
      ></div>
      <p className="text-center">{color}</p>
    </div>
  );
};

export default ColorSwatch;

You can look here and here to read more on how Tailwind generates arbitrary styles.

Upvotes: 18

Related Questions