TailwindCSS Dynamic class names

고서영·2024년 12월 7일

TailwindCSS

목록 보기
1/1
post-thumbnail

개발하다 발견한 CSS 오류!

<div className="h-screen bg-gradient-to-b from-[#EDFBFF] via-[#C6F2FF] via-65% via-[#FFC3F9]/[0.4] via-83% to-[#BDBFC0]">
      <LoadingPopUp
        className={absolute top-[38%] left-[36%] transform -translate-x-1/2 -translate-y-1/2}
      />
      <LoadingPopUp
        className={absolute top-[40%] left-[38%] transform -translate-x-1/2 -translate-y-1/2 }
      />
      <LoadingPopUp
        className={absolute top-[42%] left-[40%] transform -translate-x-1/2 -translate-y-1/2 }
      />
      <PopUp
        className={absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 }
      />
    </div>
  );
}

이 코드의 tailwindCSS 중복이 많아 동적으로 숫자를 넘겨주기 위해 리팩터링 하였다.

    const positions = [
      { top: "38%", left: "36%" },
      { top: "40%", left: "38%" },
      { top: "42%", left: "40%" },
      { top: "50%", left: "50%" }
    ];

    return (
      <PopUpComponent
        key={index}
        className={`absolute top-[${positions[index].top}] left-[${positions[index].left}] transform -translate-x-1/2 -translate-y-1/2 t`}
      />
    );

마지막 컴포넌트가 화면의 정중앙에 와야하는데 오지 않게 되었다.

이렇게 전체의 절반이 잘리게 된다.
퍼센트를 조절해봤는데 42%까지는 작동이 되다가 42를 넘는순간 위로 잘려버린다. ㅋㅋ

리팩터링 전이랑 뭐가 다를까 고민하다가 전에는 1/2라고 써서 1/2를 살리기 위해 꼼수를 사용했다. 동적 클래스 이름이 작동하지 않는다고 판단하였기 때문이다..

top-[${positions[index].top}] left-[${positions[index].left}]

여기서 대괄호를 제외하고,

const positions = [
      { top: "38%", left: "36%" },
      { top: "40%", left: "38%" },
      { top: "42%", left: "40%" },
      { top: "50%", left: "50%" }
    ];

이 값에 직접 대괄호를 넣어주면 절반에 50%가 아닌 1/2를 쓸 수 있다.. ㅋ

결과

const positions = [
      { top: "[38%]", left: "[36%]" },
      { top: "[40%]", left: "[38%]" },
      { top: "[42%]", left: "[40%]" },
      { top: "1/2", left: "1/2" },
    ];

    const PopUpComponent = index === 3 ? PopUp : LoadingPopUp;
    return (
      <PopUpComponent
        key={index}
        className={`absolute top-${positions[index].top} left-${positions[index].left} transform -translate-x-1/2 -translate-y-1/2`}
      />
    );
  };


해결했지만 해결했다고 할 수 없는 이 찜찜함.... 도대체 뭐니..

😇 왜냐하면 해결이 안됐기 때문이다. 프로젝트를 재실행 해보니 동적 클래스가 전부 작동하지 않았다.

tailwindcss에는 top-[24%] 이런식으로 사용자 정의를 할 수 있다. 그리고 위에서 되던 꼼수인 1/2 동적 클래스도 작동이 안되고 있기 때문에 top과 left를 나누어 숫자를 넣지 말고 top-[24%] 자체를 넘겨주기로 했다.

const positions = [
      "top-[38%] left-[36%]",
      "top-[40%] left-[38%]",
      "top-[42%] left-[40%]",
      "top-1/2 left-1/2",
    ];

    return (
      <PopUpComponent
        key={index}
        className={`absolute ${positions[index]} transform -translate-x-1/2 -translate-y-1/2`}
      />
    );

이렇게 전체 속성을 넘겨주니 잘 동작한다.

TailwindCSS Dynamic class names

동적 클래스에 대한 규칙이 있는건가 해서 공식문서를 찾아봤다. 완전 당연하게도 규칙이 있었다.

❌ 1. Don’t construct class names dynamically

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

내가 한 것처럼 class name의 구조를 동적으로 사용하면 안 된다.

⭕️ 2. Always use complete class names

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

동적으로 사용하고 싶은 경우에는 항상 전체 class name을 사용해야 한다.

❌ 3. Don’t use props to build class names dynamically

function Button({ color, children }) {
  return (
    <button className={`bg-${color}-600 hover:bg-${color}-500 ...`}>
      {children}
    </button>
  )
}

props 로 넘겨줄 때도 마찬가지로 일부 숫자나 색상코드만 넘겨주는 것은 안 된다.

⭕️ 4. 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>
  )
}

전체 속성의 이름을 넘겨주어야 한다.

내가 한 실수가 전부 명세서에 나와있었다. 안 될 이유가 없다고 생각했는데 ... 생각해보면 tailwind는 잘못 한 게 없다 👍

profile
흘러가는 대로 삽니다.

0개의 댓글