Skip to content
Advertisement

Design system: styles override using TailwindCSS

I am trying to create a Design System using ReactJS and TailwindCSS.

I created a default Button component with basic styling as follow:

import React from "react";
import classNames from "classnames";

const Button = React.forwardRef(
  ({ children, className = "", onClick }, ref) => {
    const buttonClasses = classNames(
      className,
      "w-24 py-3 bg-red-500 text-white font-bold rounded-full"
    );

    const commonProps = {
      className: buttonClasses,
      onClick,
      ref
    };

    return React.createElement(
      "button",
      { ...commonProps, type: "button" },
      children
    );
  }
);

export default Button;

I then use the Button in my page like:

import Button from "../src/components/Button";

export default function IndexPage() {
  return (
    <div>
      <Button onClick={() => console.log("TODO")}>Vanilla Button</Button>
      <div className="h-2" />
      <Button
        className="w-6 py-2 bg-blue-500 rounded-sm"
        onClick={() => console.log("TODO")}
      >
        Custom Button
      </Button>
    </div>
  );
}

This is what is displayed:

preview

Some attributes are overridden like the background-color but some aren’t (the rest).

The reason is the classes provided by TailwindCSS are written in an order where bg-blue-500 is placed after bg-red-500, therefore overriding it. On the other hand, the other classes provided in the custom button are written before the classes on the base button, therefore not overriding the styles.

This behavior is happening with TailwindCSS but might occurs with any other styling approach as far as the class order can produce this scenario.

Do you have any workaround / solution to enable this kind of customisation?

Here is a full CodeSanbox if needed.

Advertisement

Answer

One approach is to extract classes from your component using Tailwind’s @apply in your components layer.

/* main.css */

@layer components {
    .base-button {
        @apply w-24 py-3 bg-red-500 text-white font-bold rounded-full;
    }
}
// Button.js

const Button = React.forwardRef(({ children, className = "", onClick }, ref) => {
    const buttonClasses = classNames("base-button", className);

    // ...
);

This will extract the styles into the new base-button class, meaning they can easily be overwritten by the utility classes you pass to the Button component.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement