React and Tailwind CSS: dynamically generated classes are not being applied

Asger Skov Velling

I am just learning React and Tailwind CSS and had a strange experience with CSS grid using Tailwind classes. I've made the buttons for a calculator, with the last Button spanning two columns:

App.js:

export default function App() {
  return (
    <div className="flex min-h-screen items-center justify-center bg-blue-400">
      <Calculator />
    </div>
  );
}

Calculator.js

import { IoBackspaceOutline } from "react-icons/io5";

export const Calculator = () => {
  return (
    <div className="grid grid-cols-4 grid-rows-5 gap-2">
      <Button>AC</Button>
      <Button>
        <IoBackspaceOutline size={26} />
      </Button>
      <Button>%</Button>
      <Button>÷</Button>
      <Button>7</Button>
      <Button>8</Button>
      <Button>9</Button>
      <Button>x</Button>
      <Button>4</Button>
      <Button>5</Button>
      <Button>6</Button>
      <Button>-</Button>
      <Button>1</Button>
      <Button>2</Button>
      <Button>3</Button>
      <Button>+</Button>
      <Button>0</Button>
      <Button>.</Button>
      <Button colSpan={2}>=</Button>
    </div>
  );
};

const Button = ({ colSpan = 1, rowSpan = 1, children }) => {
  return (
    <div
      className={`col-span-${colSpan} row-span-${rowSpan} bg-white p-3 rounded`}
    >
      <div className="flex items-center justify-center">{children}</div>
    </div>
  );
};

This doesn't work (tested in Chrome): enter image description here

Now here comes the weird part. I replaced the returned JSX from the App component with HTML from a Tailwind tutorial and deleted it again.

<div className="bg-blue-400 text-blue-400 min-h-screen flex items-center justify-center">
  <div className="grid grid-cols-3 gap-2">
    <div className="col-span-2 bg-white p-10 rounded">1</div>
    <div className="bg-white p-10 rounded">2</div>
    <div className="row-span-3 bg-white p-10 rounded">3</div>
    <div className="bg-white p-10 rounded">4</div>
    <div className="bg-white p-10 rounded">5</div>
    <div className="bg-white p-10 rounded">6</div>
    <div className="col-span-2 bg-white p-10 rounded">7</div>
    <div className="bg-white p-10 rounded">8</div>
    <div className="bg-white p-10 rounded">9</div>
  </div>
</div>

After I Ctrl-Z'd a bunch of times, so I had only the previous code, my button suddenly spans two columns as intended:

enter image description here

I checked to make sure that there were no changes in the code:

enter image description here

My friend even cloned my repo, followed the same steps and got the same result. He suspects that it has something to do with the variable classNames in my Button component with regards to Tailwind's JIT compiler, but none of us can pinpoint the error.

Am I using variable CSS classes wrong?

This has been a WTF moment. What could be the reason for this?

Ed Lucas

The CSS file generated by Tailwind will only include classes that it recognizes when it scans your code, which means that dynamically generated classes (e.g. col-span-${colSpan}) will not be included.

If you only need to span 2 columns, you could pass boolean values which will trigger the addition of a full col-span-2 or row-span-2 utility class to be added:

const Button = ({ colSpan = false, rowSpan = false, children }) => {
  return (
    <div
      className={`${colSpan ? 'col-span-2' : ''} ${rowSpan ? 'row-span-2' : ''} bg-white p-3 rounded`}
    >
      <div className="flex items-center justify-center">{children}</div>
    </div>
  );
};

Otherwise, you could pass the values as classes to the Button component:

<Button className='col-span-2 row-span-1'>=</Button>

const Button = ({ className, children }) => {
  return (
    <div
      className={`${className} bg-white p-3 rounded`}
    >
      <div className="flex items-center justify-center">{children}</div>
    </div>
  );
};

More information: https://tailwindcss.com/docs/content-configuration#dynamic-class-names

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related