나는 참 Tailwind CSS가 싫어요
개발 이야기나는 테일윈드 CSS를 정말 싫어한다.
나는 코드를 짤 때 한 파일당 줄 수가 150~200줄이 넘어가게 짜지 않고 채썰어서 관심사 분리를 확실하게 하는 편이다. 하지만 테일윈드는 예전에 부트스트랩이 그러했듯, 미리 정해진 클래스명을 나열하여 스타일을 DOM에 섞이게 만든다. 저기다가 JS 끼얹으려면 또 얼마나 머리 빠개질지 현기증이 난다.
<form>
<label class="block">
<span class="block text-sm font-medium text-slate-700">Username</span>
<!— Using form state modifiers, the classes can be identical for every input —>
<input type="text" value="tbone" disabled class="mt-1 block w-full px-3 py-2
bg-white border border-slate-300 rounded-md text-sm shadow-sm placeholder-slate-400
focus:outline-none focus:border-sky-500 focus:ring-1 focus:ring-sky-500 disabled:bg-slate-50
disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none
invalid:border-pink-500 invalid:text-pink-600 focus:invalid:border-pink-500
focus:invalid:ring-pink-500
"/>
</label>
<!— … —>
</form>
위에 내용은 공식문서에서 가져온건데, 인풋 하나를 표현하기 위해 저렇게 긴 클래스명을 적어야한다. 저렇게 될 경우 앞에서 적은 클래스명을 착각해서 뒤에도 적고 오버라이드 되게 하지 않을까 걱정이 자연스럽게 되는데, 혹자는 eslint-tailwind-plugin
을 사용해서 강제로 클래스 이름 순서를 맞춰준다더라.
테일윈드는 필연적으로 저렇게 클래스명 부분이 가로로 길게 늘어나 로직이 보일 부분을 클래스명이 뒤덮게 된다. 그럼 우리는 저 클래스명의 홍수 속에서 input에 onChange를 건다던가 하는 식으로 고생을 해야 한다. 나는 이 점이 참 싫다.
위 내용을 JSX + SCSS로 적으면 아래와 같다.
<form>
<label>
<span>Username</span>
<!— Using form state modifiers, the classes can be identical for every input —>
<input type="text" value="tbone" disabled />
</label>
<!— … —>
</form>
input {
display: block;
width: 100%;
padding: 0.5rem 0.75rem;
margin-top: 0.25rem;
font-size: 0.875rem;
line-height: 1.25rem;
background-color: white;
border: 1px solid slate;
border-radius: 0.375rem;
filter: drop-shadow(0 1px 1px rgb(0 0 0 / 0.05));
&::placeholder {
color: slate;
}
&:focus {
outline: none;
border: 1px solid sky;
box-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
}
&:disabled {
color: slate500;
background-color: slate50;
border-color: slate200;
box-shadow: 0;
}
&:invalid {
color: pink600;
border: 1px solid pink500;
&:focus {
border-color: pink500;
box-shadow: pink200;
}
}
}
일단 DOM과 스타일이 완전히 분리되었다.
SCSS 문법 하에서 focus, disable, invalid 등이 딱딱 분간이 되어보여 나는 눈이 시원하다. 가로본능이라 테일윈드가 더 보기 편하다 여기는 분들이 있을지도 모르겠다. 거기다가 세로로 정렬 되어있으니 보기 또한 편하다. 중복 요소나 순서의 경우 테일윈드를 사용할 때는 eslint-tailwind-plugin
을 사용했지만, SCSS에서는 Stylelint에 stylelint-config-recess-order
을 달아서 사용한다.
보면 테일윈드는 자체적으로 rem 사이즈를 상당히 밀고 있는데, 실무에서 써보면 디자이너가 REM 단위로 시안을 주지 않는다. 예전에 웹2.0 태동하던 시절에 rem이 상당히 트렌디하게 번지던 적이 있었는데, 결국 디자이너들이 rem 단위에 적응하지 못했고, 툴에서도 rem 단위를 딱히 잘 주지 않았으므로 자연스럽게 아주 극소수 테키한 사람들만 쓰는 단위가 되어버렸다.
거기다가 자체적으로 md니 뭐니 하면서 스스로만의 키워드와 디자인 시스템을 밀고 있다. 물론 커스터마이징을 할 수도 있지만... 글쎄... 예를 들어보자구..
아니 이건 또 뭐고..
얘는 rem인데..
얘는 왜 갑자기 픽셀인데?
환장하겠다. index-px는 뭐야.. 차라리 indent-1px가 덜 헷갈리지 않을까? 아 뭐 저건 오타고 indent-2px 하면 text-indent: 2px이야? 그럼 인정.
후.. 실무에서 뻔질나게 쓰는 line-height: 140%나 160%는 어떻게 표현해야함?
난 슬슬 납득이 안가기 시작했어. 순 자기 맘대로잖아.
와 그냥 fw-100, fw-400, fw-600 이런식이 차라리 낫지 않겠어?
not-italic이라니... 뭐 오버라이드 하려고 한것 같은데.. 억지스러움을 지울 수가 없다.
커버리지 엄청 넓은건 알겠어. 꽤 마이너한 CSS 까지 지원해주네.
cursor: url()
은 없네? 그렇다면, view-transition-name이나 mix-blend-mode는?
키야.. mix-blend-mode 까지 지원하시네. 근데 mix-blend-mode: plus-lighter는?
CSS를 하드하게 파다 보면 진짜 별의 별 희한한 속성들이 다 튀어나오고, 심지어 계속해서 추가되고 있다. 테일윈드를 쓴다는 것은 결국 저런 최신 속성들이 나올 때 마다 테일윈드 자체적으로 정한 이름을 찾아다 써야 한다는 말 아닐까. 아니면 예전 처럼 커스텀 클래스 박아서 쓰던가..
이게 승산이 있을까?
animation: 90ms cubic-bezier(0.4, 0, 1, 1) both fadeOut, 300ms cubic-bezier(0.4, 0, 0.2, 1) both slideToRight;
이런거 됨? ㅠㅠ
반응형 웹의 경우 생각보다 무난하게 해두었다. 모바일 > 좀더 큰거 > 더 큰거 > 태블릿 > 데스크탑 > 더 큰거 > 더 큰거 순으로 작업할 경우 훌륭하다. 하지만 회사에 따라 모바일 퍼스트가 아니라 데스크탑 퍼스트로 작업 할 경우엔 힘들 수 있겠다. 다들 아시다시피 @media에는 엄청나게 많은 옵션들이 있다.
앗, 아까 첫번째 코드 다시 볼까?
<form>
<label class="block">
<span class="block text-sm font-medium text-slate-700">Username</span>
<!— Using form state modifiers, the classes can be identical for every input —>
<input type="text" value="tbone" disabled class="mt-1 block w-full px-3 py-2
bg-white border border-slate-300 rounded-md text-sm shadow-sm placeholder-slate-400
focus:outline-none focus:border-sky-500 focus:ring-1 focus:ring-sky-500 disabled:bg-slate-50
disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none
invalid:border-pink-500 invalid:text-pink-600 focus:invalid:border-pink-500
focus:invalid:ring-pink-500
"/>
</label>
<!— … —>
</form>
자 이제부터 위 내용에 반응형 웹을 적용해보자. sm:, md:, lg:, xl:, 2xl: 붙여서 반응형 코드를 완성하자. 너는 할 수 있어!
sm:bg-white md:bg-gray lg:bg-white sm:text-sm lg:text-medium 2xl:text-large
아직 10%도 안적었다.. 뭔가 좀 아니라고 생각되지 않는가? 저어어어어 긴 코드를 2배 3배 4배 해야 할 수도 있다는 말이다. 가독성? 더 우겨보시지? 어디 고쳐야 할지 뻔하다고? 가슴에 손을 얹고 말해보자. 진짜 그래?
어디 백오피스 만들 때 처럼 변화가 거의 없고 단조로운 프로젝트를 만든다면 모를까, B2C 서비스에서 테일윈드를 쓴다는 것은 CSS에서 손을 놓겠다는 말로 들린다. CSS의 세계는 우리 생각보다 훨씬 더 광대하며, 테일윈드는 결국 CSS에서 많이 쓰는 부분만 커버할 뿐 전체를 다 잡아줄 수는 없는 부분이다.
후.. 나는 골수 모듈 SCSS 빠로 남을란다. 내가 꼰대인가 싶어서 테일윈드 공식 문서를 열었는데 결국은 한숨 밖에 나오지 않았다. 저 끔찍한 가독성을 대체 어찌할꼬. 저 클래스명 홍수 속에 원하는 클래스명 찾아서 수정한다라.. 유지보수가 잘 될지도 의문이 든다.