이번에 사이드 프로젝트에서 TailwindCSS를 사용하게 되었습니다. 그래서 학습할겸 TailwindCSS의 Core Concepts에 대해 정리해보고자 합니다.
TailwindCSS란?
TailwindCSS란 최근에 각광받고 있는 CSS 라이브러리입니다. TailwindCSS는 미리 정의된 여러가지 유틸성 클래스들을 결합하여 스타일을 정의하는데요, 이 때문에 TailwindCSS는 스스로를 utility-first CSS Framework라고 지칭합니다. 이러한 방식은 각 엘리멘트에 적합한 의미론적인 클래스 명을 부여하는 기존 CSS의 Semantic class names의 스타일과는 사뭇 다릅니다. 그럼 이러한 방식이 어떠한 장점이 있는지에 대해서 알아보겠습니다.
Utility First Fundamentals
전통적으로 CSS를 사용할 때 보통 엘리먼트에 의미론적인 클래스 명을 붙이고, 해당 클래스에 css 스타일을 적용합니다.
<div class="modal">
<h1 class="modal-title"> Title </h1>
<span class="modal-description"> Description </span>
</div>
<style>
.modal {
display: flex;
width: 100px;
}
.modal-title {
color: red;
}
.modal-description {
color: blue;
font-size: 12px;
}
</style>
그러나 Tailwind에서는 하나의 유틸에 대해 하나의 클래스가 존재하여, 이러한 클래스들을 결합하여 스타일을 적용합니다.
<div class="flex w-100">
<h1 class="text-red"> Title </h1>
<span class="text-blue text-xs"> Description </span>
</div>
왜 Utility-first인가?
이러한 방식은 언뜻 보면 스타일이 복잡해질수록 클래스가 길어지고 보기 어려울 수 있습니다. 그러나 이는 다음과 같은 장점들이 있습니다.
- 클래스명을 생각해내기 위해 시간을 낭비할 필요가 없다.
- 새로운 기능을 추가해도 CSS 파일이 더 커지지 않는다.
- 스타일을 수정해도 다른 코드에 영향을 끼치지 않는다는 것을 보장한다.
Inline Style과의 차이점은?
이러한 방식은 언뜻 보면 인라인 스타일과 유사해 보입니다. 그러나 인라인 스타일과 비교해봐도 다음과 같은 장점들이 있습니다.
- 인라인 방식에서 모든 값은 매직 넘버이지만, 유틸 클래스에서는 미리 정의된 디자인 시스템을 따르기 때문에 저 일관된 UI를 유지합니다.
- Tailwind의 반응형 유틸리티는 미디어 쿼리를 통해 반응형 디자인을 가능케합니다.
- hover, focus 등 상태에 대한 스타일링도 가능합니다.
유지보수에 대해
이러한 방식은 공통적이고 반복되는 유틸리티 조합을 재사용하기 어렵다는 문제가 있습니다. 이는 흔히 프론트엔드 프레임워크(React, Vue.js)에서 사용하는 컴포넌트 추출, 그리고 에디터의 동시 수정 기능을 사용하여 해결할 수 있습니다.
Hover, Focus 등 상태 다루기
Tailwind의 모든 유틸리티 클래스들은 앞에 modifier를 추가하여 이러한 상태를 다룰 수 있습니다. 예를 들어 'bg-sky-700' 앞에 hover를 붙여 'hover:bg-sky-700' 클래스를 사용할 수 있습니다. modifier의 종류는 Pseudo-classes, Pseudo-elements, 미디어 쿼리, 속성 선택자가 있습니다. 이에 대해선 아래에서 더 자세히 다뤄보겠습니다.
또한 modifier들은 겹쳐서 사용할 수도 있습니다. 예를 들어 다크모드이고 medium breakpoint에서 hover시 배경색을 'fuchsia-600'으로 지정하고 싶다면 'dark:md:hover:bg-fuchsia-600'로 작성합니다.
Pseudo-classes
'hover', 'focus', 'active' 등의 modifier뿐만 아니라, 'visited', 'focus-within', 'focus-visible'등의 interactive states에 대한 modifier도 제공합니다.
Form states
Form에서는 추가적으로 'required', 'invalid', 'disabled' 등의 modifier도 제공합니다.
부모의 state에 따른 스타일링
부모의 상태에 대해서 자식의 스타일을 변경하고자 한다면 부모에게 'group' 클래스를 추가하고, 자식에서 'groudp-{modifier}'를 사용하여 스타일을 적용할 수 있습니다. 만약 여러 그룹이 있다면 'group/{name}' 클래스를 통해 그룹에 이름을 지정하고 자식에서 'group-{modifier}/{name}'의 방식으로 자식에 스타일을 적용할 수 있습니다.
이 외에도 여러가지 State 관련된 기능들이 있지만 너무 길어서 생략하겠습니다. 궁금하시다면 해당 링크를 방문해서 직접 확인해 보시길 바랍니다.
반응형 디자인
Tailwind는 반응형 modifier를 제공하기에, 이를 활용해서 반응형 디자인을 적용할 수 있습니다.

mobile-first
Tailwind는 기본적으로 'mobile-first' breakpoint 시스템을 사용합니다. 따라서 modifier가 붙지 않은 유틸리티 클래스는 모든 스크린에 적용되지만 md가 붙은 유틸리티 클래스는 md이상의 스크린에 적용됩니다.
다크 모드
다크 모드는 이제 필수적인 기능이라고 해도 과언이 아닐정도로 여러 사이트에서 많이 사용되고 있습니다. TailwindCSS는 'dark' modifier를 제공하여 다크 모드를 쉽게 스타일할 수 있도록 해줍니다.
'dark' modifier를 적용하면 CSS 미디어 쿼리인 'prefers-color-scheme'을 통해 운영체제 설정에서 지정된 모드를 가져와서 적용합니다.
수동으로 다크 모드 토글하기
만약 수동으로 다크 모드를 토글하고 싶다면 tailwind.config.js에서 darkMode 값을 'class'로 지정해주면 됩니다. 이렇께 되면 'dark:{class}'는 'prefers-color-scheme'이 아니라, 'dark'라는 클래스가 HTML tree 상위 어딘가에 지정된 경우에 적용됩니다.
마치며
내용이 길어져서 2편으로 나눴습니다. 다음 편에서는 커스텀 스탕일을 추가하는 법, Functions 그리고 Directives에 대해서 알아보겠습니다.
참고
'CSS' 카테고리의 다른 글
| CSS 특정성 (Specificity) (0) | 2023.02.16 |
|---|---|
| CSS 적용 규칙(Cascade)에 대해서 (0) | 2023.02.16 |