tailwind 동적 스타일링 적용

JulyK9·2023년 5월 16일
6

tailwind css

목록 보기
2/2

동적 스타일링 적용 규칙

NO : 클래스 이름을 동적으로 구성하지 말 것

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

YES : 완전한 클래스 이름을 사용 할 것

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

문제는 이렇게 되면 상위 컴포넌트에서 props 받아서 동적으로 클래스를 생성하는 데에
어려움이 있으며, 공식문서에서도 이렇게 하지 말라고 명시하고 있음.

NO : 클래스 네임을 동적으로 만들기 위해 props를 이용하지 말 것

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

YES : 대신, 빌드타임에 정적으로 탐지될 수 있는 클래스 이름을 완성하려면 props를 맵핑할 것

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>
  )
}

이를 통해 다음과 같은 여러 클래스 속성을 다른 색상 음영에 매핑할 수 있음

function Button({ color, children }) {
  const colorVariants = {
    blue: 'bg-blue-600 hover:bg-blue-500 text-white',
    red: 'bg-red-500 hover:bg-red-400 text-white',
    yellow: 'bg-yellow-300 hover:bg-yellow-400 text-black',
  }

  return (
    <button className={`${colorVariants[color]} ...`}>
      {children}
    </button>
  )
}

동적 케이스를 변수에 먼저 담았다가 클래스에 적용하기

isTopOfPage는 페이지의 스크롤 상태가 최상단인지 확인하는
boolean 타입의 상태로 props로 넘겨받았다.
isTopOfPage props의 상태값에 따라 스타일에 변화를 주려고 하는데(동적 스타일링)

이때,
위에서 알아본 공식문서 내용처럼
바로 클래스네임 안에서 동적으로 구성하지 않고
먼저 변수에 동적 케이스를 담아주면서 완전한 클래스 이름을 표시하고,
다음으로 해당 태그의 클래스에서 그 변수명을 적용 해준다.

반복되는 공통 클래스 속성 재사용

네비게이션바에서 flex를 사용해서 요소들의 위치를 잡아주다보면
공통적인 클래스 속성이 태그마다 계속 반복되는 경우가 발생한다.

이때 반복해서 사용할 부분을 변수에 담아두고 필요할 때마다 적용하니
코드 가독성면에서도 한결 나아진 것 같다.

type Props = {
  selectedPage: SelectedPage;
  setSelectedPage: (value: SelectedPage) => void;
  isTopOfPage: boolean;
};

const Navbar = ({ selectedPage, setSelectedPage, isTopOfPage }: Props) => {
  const [isMenuToggled, setIsMenuToggled] = useState<boolean>(false);
  
  const flexBetween = "flex justify-between items-center";
  const navbarBackground = isTopOfPage ? "" : "bg-primary-100 drop-shadow";

  return (
    <nav>
      <div
        className={`${flexBetween} ${navbarBackground} fixed top-0 z-30 w-full py-6 `}
      >
        <div className={`${flexBetween} mx-auto w-5/6`}>
          <div className={`${flexBetween} w-full gap-16`}>
            {/* Left Side */}
            <img alt="logo" src={Logo} />

            {/* Right Side */}
            <div className={`${flexBetween} w-full`}>
              <div className={`${flexBetween} gap-8 text-sm`}>
                <Link
                  page="Home"
                  selectedPage={selectedPage}
                  setSelectedPage={setSelectedPage}
                />
				// ...
              </div>
              <div className={`${flexBetween} gap-8`}>
                <p>로그인</p>
                <ActionButton setSelectedPage={setSelectedPage}>
                  회원가입
                </ActionButton>
              </div>
            </div>
          </div>
        </div>
      </div>
    </nav>
  );
};

export default Navbar;

참고

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

profile
느리지만 꾸준하게. 부족하거나 잘못된 부분은 알려주시면 감사하겠습니다.

0개의 댓글