Search code examples
cssreactjstailwind-cssvite

Issues with Tailwind Dynamic Class Values Compilation in React


I'm currently facing issues while trying to create a grid based on a dynamically generated grid size variable in Tailwind CSS. When I use the variable to set grid-template-rows and grid-template-columns, the class names don't get compiled as expected. Instead, I'm getting class names with the generated values enclosed in square brackets.

Here's a snippet of the code:

const App = () => {
  const gridSize = getGridSize();
  const players = getPlayers();
  // const numberOfPlayers = players.length;
  const activePlayer = getActivePlayer();

  const gridItems = Array(gridSize * gridSize)
    .fill(null)
    .map((_, index) => (
      <div
        key={index}
        className="bg-orange-300 rounded-lg w-16 h-16 cursor-pointer"
      ></div>
    ));

  return (
    <div
      className={`bg-[${players[activePlayer]}] w-[60vw] h-[100vh] mx-[20vw] flex justify-center items-center`}
    >
      <div className={`grid grid-rows-${gridSize} grid-cols-${gridSize} gap-2`}>
        {gridItems}
      </div>
    </div>
  );
};

export default App;

The problem is visible in the resulting class names with square brackets, as shown in this screenshot:

enter image description here

In contrast, when static values are used, the class names are applied correctly, as seen in this screenshot:

enter image description here

Please help me understand why these dynamic class values with Tailwind CSS variables aren't getting compiled as expected.


Solution

  • As per the documentation:

    The most important implication of how Tailwind extracts class names is that it will only find classes that exist as complete unbroken strings in your source files.

    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>
    

    You could look at using the style attribute instead like:

    const App = () => {
      // …
    
      return (
        <div
          className="w-[60vw] h-[100vh] mx-[20vw] flex justify-center items-center"
          style={{ backgroundColor: players[activePlayer] }}
        >
          <div
            className="grid gap-2"
            style={{
              gridTemplateRows: `repeat(${gridSize}, 1fr)`,
              gridTemplateColumns: `repeat(${gridSize}, 1fr)`,
            }}
          >
            {gridItems}
          </div>
        </div>
      );