📙 개요
Tailwind를 사용하여 모달을 만드는 도중, 모달 닫기 버튼의 위치가 제대로 적용되지 않았다.
분명 아까까지는 잘 적용됐는데 갑자기 아래로 가있는 닫기 버튼을 보자 당황할 수 밖에 없었다😭
📙 문제 파악 - 현재 컴포넌트 코드 살펴보기
"use client";
import { useRouter } from "next/navigation";
import Icon from "./Icon";
interface Props {
size: number;
right: number;
top: number;
}
export default function CloseButton({ size, right, top }: Props) {
const router = useRouter();
const handleClickClose = () => {
router.back();
};
return (
<button
onClick={handleClickClose}
aria-label="모달 닫기"
className={`absolute right-[${right}px] top-[${top}px] h-[${size}px] w-[${size}px]`}
>
<Icon id="close" size={24} className="m-auto" />
</button>
);
}
CloseButton 컴포넌트를 살펴보면, 동적으로 props에 따라 버튼의 크기와 위치를 조정해주고 있다.
Tailwind CSS는 빌드 시점에 사용하는 모든 클래스를 미리 분석해 최적화된 CSS를 생성하는데, 이떄 주의해야 할 점은 끊어지지 않은 완전한 문자열로 존재하는 클래스만 찾는다는 것이다.
부분 클래스 이름을 사용할 경우 Tailwind는 이를 찾지 못하므로 해당 CSS를 생성하지 않는다.
실제로 개발자 도구로 스타일 시트를 확인해보면, 높이에 대한 값만 적용된 것을 확인할 수 있다.
Tailwind 공식문서에서 답 찾기
답은 가까운 곳에 있다더니 공식문서에 떡하니 있었던 동적 클래스 정의 방법 !!
❌ 클래스 이름을 동적으로 구성하지 말 것
<div class="text-{{ error ? 'red' : 'green' }}-600"></div>
✅ 완전한 클래스 이름을 사용할 것
<div class="{{ error ? 'text-red-600' : 'text-green-600' }}"></div>
❌ props를 사용하여 클래스 이름을 동적으로 작성하지 말 것
function Button({ color, children }) {
return (
<button className={`bg-${color}-600 hover:bg-${color}-500 ...`}>
{children}
</button>
)
}
✅ 빌드 시점에 정적으로 감지할 수 있게 완전한 클래스 이름에 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>
)
}
<button
onClick={handleClickClose}
aria-label="모달 닫기"
className={`absolute right-[${right}px] top-[${top}px] h-[${size}px] w-[${size}px]`}
>
현재 내 컴포넌트에서는 props를 사용하여 클래스 이름이 동적으로 할당되었기 때문에 문제가 발생하고 있음을 알 수 있었다.
🟡 인라인 스타일로 적용하기
<button
onClick={handleClickClose}
aria-label="모달 닫기"
style={{
right: `${right}px`,
top: `${top}px`,
height: `${size}px`,
width: `${size}px`,
}}
className="absolute"
>
<Icon id="close" size={24} className="m-auto" />
</button>
실컷 공식문서 보고 인라인 스타일이라니 ?? 😲
인라인 스타일을 사용하면 Tailwind 유틸리티 클래스는 그대로 사용하고, 동적 스타일도 함께 처리할 수 있다는 장점이 있다. 하지만 반응형 디자인이나 우선순위 문제가 발생할 수 있고, Tailwind의 장점은 CSS 최적화 기능을 사용할 수 없다는 단점이 있다.
함수를 만들어서 케이스에 따라 완전한 Tailwind 클래스를 반환해도 좋지만, position 값의 경우 범위가 매우 넓고 각각의 위치를 설정하려면 여러 개의 함수가 필요하다. 필요한 모든 경우를 추가하여 그에 맞는 함수를 만드는 것도 좋지만, 그보다는 CSS 최적화 기능을 사용할 수 없어도 인라인 스타일을 적용하는게 가장 안정적이고 최선의 방법이라 생각했다😀
해결 완료 ✨
인라인 스타일로 적용할 수 밖에 없다는 사실이 아쉬웠지만, Tailwind를 사용하면서 감수해야할 단점이라면 단점인 부분 같다. 그래도 최대한 사용하지 않는 것이 우선이기 때문에 주의하며 구현해봐야겠다 !
'HTML-CSS-JS' 카테고리의 다른 글
[CSS] 헷갈리는 float, 알고 쓰기! (2) | 2023.03.08 |
---|