부스트캠프 학습 스프린트 과정 중 계속 뒤로 미루고 있던 Tailwind CSS를 써볼 만한 좋은 기회가 생겨, 바닐라 JS 환경에서 한 번, 그리고 부스트캠프가 끝난 뒤 리액트 환경에서 한 번씩 써본 후 개인적으로 느낀 점들을 정리해 보았다.
💡 Tailwind CSS란? - Utility-First를 지향하는 CSS 프레임워크. 기존 CSS는 개별 요소들을 기준으로 스타일을 부여했다면, Tailwind는 미리 정의된 스타일 조각들을 요소의
class
속성에 하나씩 넣어 조립하는 방식으로 스타일링한다.
Tailwind CSS를 직접 써보면서, 다른 스타일링 방법과 비교하여 느낀 장단점을 요약하면 이렇다.
환경에 따른 상세 세팅 방법은 공식 문서에 잘 나와있다.
tailwind.config.js
파일을 생성하고 다음과 같이 설정하는 것부터 시작한다./** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{html,js}'], // Tailwind CSS를 사용할 위치
theme: {
extend: {} // 추가 사용자 테마는 여기에 넣는다
},
plugins: [],
}
@tailwind base;
@tailwind components;
@tailwind utilities;
npx tailwindcss -i [변환 대상 파일명].css -o [변환 후 파일명].css --watch
prettier-plugin-tailwindcss
패키지를 설치하면 유틸리티 클래스 간의 순서도 일관적으로 배치되도록 할 수 있다.유틸리티 클래스는 Tailwind CSS의 핵심이다.
Tailwind CSS에서는 컴포넌트별로 스타일 명세를 매번 정의할 필요 없이 class
속성에 미리 만들어진 스타일 조각(= 유틸리티 클래스)들을 곧장 삽입하여 스타일을 부여할 수 있다.
유틸리티 클래스의 값은 기존 CSS 속성명과 비슷하면서도 훨씬 짧게 단축되어 있는 형태다. 공식 문서에서 각 CSS 속성에 대응되는 유틸리티 클래스 목록을 찾을 수 있다.
padding-left: 0.25rem
→ class="p-1"
<div class="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-lg flex items-center space-x-4">
<div class="shrink-0">
<img class="h-12 w-12" src="/img/logo.svg" alt="ChitChat Logo">
</div>
<div>
<div class="text-xl font-medium text-black">ChitChat</div>
<p class="text-slate-500">You have a new message!</p>
</div>
</div>
class
이지만, 리액트의 className
과 같은 속성도 똑같이 지원한다. (= class-like)일단은 타 스타일링 방식과 비교했을 때 개발 속도가 유의미하게 빨라지는 것을 느낄 수 있었다!
클래스 작명도 생략할 수 있고, 유틸리티 클래스도 적응만 되면 원래 CSS 속성에 비해 훨씬 짧고 간결한 형태이므로 빠른 타이핑이 가능하고, CSS 파일을 따로 만들어서 또 선택자를 정의할 필요 없이 class 속성에 바로 인라인처럼 툭툭 적어나가면 되니 시간이 상당히 절약되었다.
유틸리티 클래스들은 미리 잘 설계된, 일관성을 가진 속성들로 구성되어 있다. 예를 들면 요소의 크기나 간격을 지정하는 속성의 경우 1px 단위가 아니라 특정 단위만큼의 간격을 두고 정의되어 있고, 색상의 경우도 따로 디자인 시스템을 구축할 필요 없이 꽤 괜찮은 기본 색상 팔레트를 제공하고 있다.
따라서 컴포넌트 하나를 만들 때 패딩은 정확히 몇 px으로 주어야 할지, 색상은 또 정확히 무슨 hex 값으로 주어야 할지 등에 관한 고민이 많이 줄어든다.
그리고 다소 낯선 개념과 사용 방식에 빠르게 적응할 수 있었던 것은 역시 친절하게 잘 작성된 공식 문서의 덕이 컸던 것 같다.
Stack Overflow나 다른 블로그 등을 찾아가지 않고 오직 공식 문서만 참고하면서 개발이 가능할 정도로 설치 방법, 유틸리티 클래스 명세, 설정 파일 관리, 기타 문제 해결 등에 대한 정보가 상세하게 나와있다. UI도 깔끔해서 더 보기 편한 부분도 있었다.
또한 자체적으로 프로젝트 빌드 시 실제로 HTML에 적용되는 유틸리티 클래스만 최종 CSS 파일에 남겨두는 식으로 번들 크기를 줄인다고 한다. 직접 사용하면서도 확실히 가벼운 느낌을 받긴 했다.
물론 유틸리티 클래스가 기존 CSS 속성명에 비해 짧게 단축된 형태인만큼, 학습 초기에는 속성 하나가 필요할 때마다 공식 문서를 매번 참고하며 익숙해지는 과정이 필요하다.
또한 속성명 자체는 어느 정도 익히더라도, 위의 '일관적인 디자인'을 위해 모든 간격별로 단위 값이 정의되지 않으므로 정확히 사용 가능한 값을 찾기 위해 여전히 공식 문서나 자동 완성 목록을 참고해야 한다.
m-15
를 썼는데 작동하지 않는다! 왜냐하면 m-14
다음 값은 m-16
만 정의되어 있기 때문에...클래스 이름을 고민하고 선택자를 선언할 필요가 없어진 건 물론 좋지만, class
속성에 모든 스타일을 몰아넣는 만큼 HTML/JSX 부분의 크기가 매우 커지고 가독성도 많이 떨어진다.
심지어 공식 문서에서도 Tailwind 방식으로 작성한 코드가 못생겼다는 것을 인정한다. 나도 Tailwind를 사용해 보면서 계속 이게 좋은 방법인지 의심이 들었던 이유이다. 레이아웃과 스타일 코드의 관심사 분리도 이루어지지 않는다.
특히 동적 스타일링이 필요한 경우, 템플릿 리터럴 코드가 복잡해지면서 이 단점이 더 부각된다. props
형태로 상태값을 받아 간단히 스타일 분기 처리를 할 수 있었던 styled-components 등의 라이브러리와 비교되는 점이다.
또한 동일한 스타일을 여러 요소에 동시에 적용해야 하는 경우(ex. <ul>
하위의 <li>
)에도 고민이 됐었는데, 공식 문서에 따르면 IDE의 다중 커서 편집 기능을 이용할 것을 권장하고 있다.
즉, 그냥 중복해서 작성하는 것이 가장 낫다는 것... 물론 다른 우회 방법도 존재하지만 공식 문서에서는 'Tailwind를 가장 Tailwind 답게 사용하려면' 그냥 중복을 그대로 두는 것이 좋다고 한다.
중복 코드가 무조건 나쁜 건 아닐 수도 있다. 중복을 줄이기 위해 여러 곳의 스타일을 하나로 묶는다는 것은 그만큼 사이드 이펙트가 발생할 확률이 높아진다는 것이기도 하니까...
그리고 간혹 rotateX
, translateZ
처럼 사용 빈도가 비교적 낮은 속성들이 필요한 경우, 대응되는 유틸리티 클래스가 없기 때문에 직접 CSS 파일을 만들어 기존 스타일링 방식 대로 작성해야 했다.
규모가 크지 않은 가벼운 프로젝트거나, 빠른 개발 속도가 필요한 상황에서는 무척 유용하게 쓸 수 있는 최고의 스타일링 라이브러리라고 생각한다.
하지만 그만큼 가독성 및 코드 중복 문제를 어느 정도 감수해야 하고, 또 동적 스타일링이 자주 필요한 서비스에는 잘 어울리지 않는다는 느낌을 받기도 했다.
결론적으로는 상황에 따라 유용하게 사용할 수 있는 기술을 하나 더 습득한 느낌이라 매우 만족스럽다! 다음 프로젝트를 시작할 때 다시 한 번 제대로 공부하면서 써봐야겠다.