MUI와 Tailwind CSS를 같이 사용할 때 TextField의 아웃라인 문제

MUI와 Tailwind CSS를 같이 사용할 때 TextField의 아웃라인 문제

MUI, Tailwind CSS

MUITailwind CSS도 UI 스타일을 간편하게 작성할 수 있도록 도와주는 좋은 라이브러리들이다. MUI는 구글의 Material Design을 리액트 기반 프론트엔드에서 손쉽게 적용할 수 있도록 도와주고, Tailwind CSS는 flex, p-auto 등 미리 정의된1 클래스들을 가지고 순식간에 여러 컴포넌트들을 유연하게 작성할 수 있게 도와준다.

하나씩 쓰면 문제가 없는데

각각 모두 굉장히 유용한 라이브러리이다. 쓰는 것과 쓰지 않는 것의 개발 속도 차이가 어마어마하게 날 정도로 말이다. 문제는, 이것도 유용하고 저것도 유용해서 둘 다 한번에 쓰려고 할 때 생겼다.

MUI의 TextField 컴포넌트

우선 말하자면, 방금 전까지 이게 두 라이브러리를 동시에 사용해서 생긴 문제라는 사실 자체를 인지하지 못했다. 그 문제는 다음과 같다.

일단, 어느 순간부터 MUI의 TextField 컴포넌트의 outlined variant가 :focus되었을 때 크롬의 기본 유저 에이전트 스타일인 파란색 아웃라인이 보이기 시작했다. 처음 이 증상이 생겼을 때는 UI가 문제가 아니라 일단 전체적인 로직 흐름이 더 중요해서 무시했는데 이제는 앱의 윤곽이 잡혀과는 단계라 눈에 밟히게 되었다.

다행히도, 지금까지 이것 저것 리액트 기반 라이브러리들을 사용해오면서 스치듯 지나친 여러 문서들 중에 MUI와 Tailwind CSS를 동시에 쓰면 문제가 생긴다는 글을 본 기억이 얼핏 나게 되었다. 해당 글은 한국 문서였고, 어떤 사람은 MUI를 프로젝트에서 빼서 해결했다 하고, 어떤 사람은 Tailwind CSS를 프로젝트에서 빼서 해결했다고 했다.

하지만 난 도대체가 이해가 안 됐다. 두 라이브러리는 이미 유명해질대로 유명해진 라이브러리들이고, 나온지도 오래 되었는데 절대로 호환성이 없을 리가 없다고 느꼈기 때문이다.

아무튼 이런 의문을 가진 채 일단 Tailwind CSS를 빼보니 정상적으로 TextField 컴포넌트의 Label이 제대로 outline과 겹치지 않게 표시되고, 기본 유저 에이전트 스타일의 파란색 2px outline도 보이지 않는 것을 확인했다.

공식 문서. 또 공식 문서.

문제는 나는 둘 중 어느것도 제외하고 사용하고 싶지 않았다. 그래서 스택오버플로우, 깃헙 등 온갖 곳을 돌아다니는 지랄을 하다가 최근 유독 깨달아 가고 있던 공식 문서의 중요성을 떠올리고, MUI 홈페이지에서 Tailwind를 검색했더니 이런 문서가 나왔다.

해결. 그러나 문서를 꼼꼼히 읽자.

해당 문서대로 시도하니 해결되는 것처럼 극히 일부 MUI 컴포넌트를 사용하지 않은 컴포넌트를 제외하고 UI가 정상적으로 렌더링되긴 하였으나, 여전히 TextField의 아웃라인 문제는 그대로였다.

예전 같았으면 또 자만심에 사로잡혀 성급히 공식 문서가 잘못되었거나 업데이트가 안 되었다는 생각을 하고 이미 수십 분동안 했던 검색을 또 하는 삽질을 했겠지만 이젠 나도 성장했기에 공식 문서를 더 꼼꼼히 읽어봤더니 다음과 같은 단계가 있었다.2

Remove Tailwind CSS’s preflight style so it can use the Material UI’s preflight instead (CssBaseline).
Add the important option, using the id of your app wrapper. For example, #__next for Next.js and "#root" for CRA:

즉 Tailwind CSS의 preflight를 비활성화하고 MUI의 CssBaseline을 사용하라는 부분인데, 문제는 preflight를 제거했다고 끝이 아니라는 것이다. preflight를 제거하는 이유가 무엇이겠는가? Tailwind CSS의 CSS reset과 겹치는 부분이 있기 때문일 것이다. 하지만 플러그인을 제거한다고 다 끝난 게 아니었으니,

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

위 부분을 다음과 같이 바꿔야만 제대로 작동한다.

@tailwind components;  
@tailwind utilities;

하지만 이는 아무리 생각해도 말이 안 된다. 일단, @tailwind base;는 Tailwind CSS 자체의 베이스 스타일 뿐 아니라 등록된 모든 플러그인의 베이스 스타일 역시 초기화한다. 즉, 이를 없앤다는 것은 이런 것들을 모두 사용하지 않겠다는 말이나 다름이 없다. 또한, 공식 예제 코드 역시 멀쩡히 해당 디렉티브를 사용하고 있다. 즉 내가 뭔가 잘못했다는 것.

문제는 @tailwindcss/forms 플러그인이었다.

아무리 봐도 공식 문서와 내 코드의 차이점은 플러그인 뿐이었다. @tailwindcss/typogrpahy@tailwindcss/forms를 사용 중이었는데, 심지어 필요해서 넣어놓은 것도 아니었다. 예제 코드를 따라서 쓰다가 들어간 것.

따라서 둘 다 비활성화 해보니 아주 멀쩡히 TextField 컴포넌트가 렌더링 되는 것을 확인할 수 있었다. 파란색 테두리도 없고, 레이블 영역과 겹치는 아웃라인도 없다.

하지만 플러그인 모두가 문제가 될 리는 없으므로, 하나씩 번갈아가며 확인해 본 결과 @tailwindcss/forms 플러그인이 원인이었다.

공식 문서, 또 공식 문서…

일단 비활성화하고 쓰려고 했으나 가만 생각해보니 언젠가 이 플러그인과 MUI를 같이 써야 하는 날이 올지도 모른다는 생각이 들었다. TailwindCSS 공식 문서를 보니 별다른 언급이 없었다. 그렇다면? 플러그인 자체의 공식 문서를 보면 된다.

// tailwind.config.js
plugins: [
  require("@tailwindcss/forms")({
    strategy: 'base', // only generate global styles
    strategy: 'class', // only generate classes
  }),
],

위에서 보듯 플러그인을 등록할 때 strategy"class"로 초기화하면 글로벌 스타일 변경 없이 필요할 때 클래스만 뽑아 쓸 수 있다.

이로써 문제 해결 끝.


  1. 사용자가 커스터마이징 할 수도 있다. ↩︎

  2. 심지어 당연히, 이미 내가 따른 단계였다. 단지 제대로 꼼꼼히 읽지 않았을 뿐. ↩︎

댓글

이 블로그의 인기 게시물

C# 남아도는 메모리에도 불구하고 OutOfMemoryException이 발생한다면?

MySQL 데이터 타입과 Java 데이터 타입 비교/매칭

테일즈위버 OST 전곡 모음