[Portfolio] TailwindCSS의 @apply, Dynamic class names

도현수·2023년 3월 31일
0

Portfolio

목록 보기
3/3

포트폴리오를 만들었는데, 브라우저 크기에 따른 너비 효과를 주고 싶어졌다. 하지만 이걸 여러번 계속 속성으로 지정해주기는 넘 번거롭고... 뭐 좋은 기능 없나 공식문서를 보던 차에 @apply 에 대해 알게 되었다

@apply

@apply 를 사용해 기존의 유틸리티 클래스를 사용자 정의 CSS에 인라인으로 작성합니다.

사용자 정의 css를 작성해야할 때 유용하게 쓸 수 있다. @apply 를 작성해주고 그 뒤에 내가 사용하고 싶은 유틸리티 클래스를 인라인으로 작성해준다.

.test-div {
  @apply rounded-b-lg shadow-md;
}

이런식으로 작성하고 난 뒤에, 저 클래스 네임들을 유틸리티 클래스처럼 사용할 수 있다.

<div className='test-div' > 테스트임 </div>

div태그에는 rounded-b-lg shadow-md 가 적용됨..

@apply는 global.css에도 사용할 수 있다.

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  h1 {
    @apply text-2xl;
  }
  h2 {
    @apply text-xl;
  }
}

@layer components {
  .btn-blue {
    @apply bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded;
  }
}

...근데 결론적으로 실제 적용하지는 않게 되었다... 요소마다 너비가 다 달라서 크게 의미가 있나 싶었음...

Dynamic class names

size라는 props를 전달받아서 동적으로 스타일링을 해주고 싶었다. 역시나 공식문서에 Dynamic..까지 치니까 바로 나왔다. 공식문서 짱짱.
근데 '이렇게 쓰지 않을까?' 라고 생각했던 방식이, 공식문서에서 사용하지 말라는 방법으로 설명되어 있었다....왕

클래스 네임을 동적으로 짓지 마세요.

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

오잉...당연히 이 방법일줄 알았는데... 이런식으로 하면 Tailwind가 해당 CSS를 찾을 수가 없단다.. 문자열 보간(${} 얘)랑 클래스 네임을 같이 연결해놓으면 안된다..호....대신 이렇게 작성하자

완전한 클레스 네임을 사용하세요.

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

props를 이용한 동적 클래스 네임

또한 props를 동적으로 클레스 네임을 만드는데 사용하지 말란다.

props를 클래스 네임을 동적으로 짓는 데에 사용하지 마세요.

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

대신, 빌드시간에 정적으로 검색할 수 있는 클래스 이름을 완성하도록 props를 매핑(map) 할 것.

언제나 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>
  )
}

이 방법을 이용하면 다른 props 값을 다른 클래스 네임에 매핑할 수 있다. 즉, 확장성이 넘나 좋아진다.

내가 사용한 방법

export default function DescriptionCard({
	children,
	size,
}: DescriptionCardProps) {
	const sizeVariants: { [key in DescriptionCardProps['size']]: string } = {
		contactChannel: 'w-[385px] h-[234px] py-6',
	}
	return (
		<article
			className={`${sizeVariants[size]} bg-white rounded-[20px] drop-shadow-cardShadow flex flex-col justify-between items-center`}
			{children}
		</article>
	)
}

sizeVariants 의 프로퍼티가 하나밖에 없지만...나중에 이 DescriptionCard를 여러 곳에서 사용할 예정이다. 고러면은 그때 추가가 되겠지.

참고:
https://tailwindcss.com/docs/content-configuration#dynamic-class-names
https://tailwindcss.com/docs/functions-and-directives#apply

0개의 댓글