DEV Community

Sina Ghadimi
Sina Ghadimi

Posted on

Override TailwindCSS classes in ReactJs

The Main Issue

I was just working on Building Button Component to use in my project and faced a problem with tailwindcss. so I am writing this article that could help others also facing this problem.

let's see what we want to build first

function Button({
  children,
  primary,
  secondary,
  success,
  warning,
  danger,
  outline,
  rounded
}) {
  const classes = classNames('flex items-center px-3 py-1.5 border', {
    'border-blue-500 bg-blue-500 text-white': primary,
    'border-gray-900 bg-gray-900 text-white': secondary,
    'border-green-500 bg-green-500 text-white': success,
    'border-yellow-400 bg-yellow-400 text-white': warning,
    'border-red-500 bg-red-500 text-white': danger

  });

  return (
    <button {...rest} className={classes}>
      {children}
    </button>
  );
}
Enter fullscreen mode Exit fullscreen mode

Imagine that you have a button with different button variation(primary,secondary,...) like image below

Image description

and you want to add more styles(outline,rounded). but in this situation we will face conflict in tailwindcss

let's see code first then result

function Button({
  children,
  primary,
  secondary,
  success,
  warning,
  danger,
  outline,
  rounded
}) {
  const classes = classNames('flex items-center px-3 py-1.5 border', {
    'border-blue-500 bg-blue-500 text-white': primary,
    'border-gray-900 bg-gray-900 text-white': secondary,
    'border-green-500 bg-green-500 text-white': success,
    'border-yellow-400 bg-yellow-400 text-white': warning,
    'border-red-500 bg-red-500 text-white': danger,
    'rounded-full': rounded,
    'bg-white': outline
  });

  return (
    <button className={classes}>
      {children}
    </button>
  );
}
Enter fullscreen mode Exit fullscreen mode

Image description

In this case background color of outline will override the previous styles so we need to add more styles to resolve conflict like code below

function Button({
  children,
  primary,
  secondary,
  success,
  warning,
  danger,
  outline,
  rounded
}) {
  const classes = classNames('flex items-center px-3 py-1.5 border', {
    'border-blue-500 bg-blue-500 text-white': primary,
    'border-gray-900 bg-gray-900 text-white': secondary,
    'border-green-500 bg-green-500 text-white': success,
    'border-yellow-400 bg-yellow-400 text-white': warning,
    'border-red-500 bg-red-500 text-white': danger,
    'rounded-full': rounded,
    'bg-white': outline,
    'text-blue-500': outline && primary,
    'text-gray-900': outline && secondary,
    'text-green-500': outline && success,
    'text-yellow-400': outline && warning,
    'text-red-500': outline && danger,
  });

  return (
    <button className={classes}>
      {children}
    </button>
  );
}
Enter fullscreen mode Exit fullscreen mode

So let's see the result

Image description

As you see Although we set background color for both outline and variation but background color of outline overrides previous styles

So what is the solution?

In this situation the solution is tailwind-merge package. in this situation we wrap code with tailwind merge package and it solves the issue for us like code below.

function Button({
  children,
  primary,
  secondary,
  success,
  warning,
  danger,
  outline,
  rounded,
  ...rest
}) {
  const classes = twMerge(classNames(rest.className,'flex items-center px-3 py-1.5 border', {
    'border-blue-500 bg-blue-500 text-white': primary,
    'border-gray-900 bg-gray-900 text-white': secondary,
    'border-green-500 bg-green-500 text-white': success,
    'border-yellow-400 bg-yellow-400 text-white': warning,
    'border-red-500 bg-red-500 text-white': danger,
    'rounded-full': rounded,
    'bg-white': outline,
    'text-blue-500': outline && primary,
    'text-gray-900': outline && secondary,
    'text-green-500': outline && success,
    'text-yellow-400': outline && warning,
    'text-red-500': outline && danger,
  }));

  return (
    <button {...rest} className={classes}>
      {children}
    </button>
  );
}
Enter fullscreen mode Exit fullscreen mode

as you see the problem is solved

Image description

Top comments (0)