CSS 작성하기가 참 어렵죠. 말 그대로입니다. 제가 이해해요 – 자신의 아이디어나 디자인 팀으로부터 받은 디자인을 실현하는 일이 답답할 수 있습니다.

여러분 중 많은 이들이 개발 경력에서 적어도 몇 번쯤은 같은 고통을 겪어본 적이 있으리라 생각합니다.

하지만 이제 그런 고민은 더 이상하지 않아도 됩니다. 우리의 부담을 많이 줄여주는 흥미로운 도구를 배울 때가 왔거든요. 그리고 그것은 부트스트랩이 아니라 Tailwind CSS라는 이름의 것입니다.

잠깐 Tailwind가 이미 한동안 존재해왔지만, 아직 접해보지 못했을 수 있습니다. 아마도 소식을 듣지 못했거나, CSS에 관련된 새로운 기술을 배우는 것이 실제로 작업을 간소화해줄지 확신할 수 없는 탓일 수 있죠.

물론 CSS를 작성하는 방법은 많습니다 – 바닐라 CSS3부터 시작해 LESS, SCSS, 부트스트랩, styled-components, Windi CSS 등등… 목록을 나열하기도 숨가쁘죠?

이 짧은 가이드가 여러분이 Tailwind CSS와 그 이점을 이해하는 데 도움이 될 수 있기를 바랍니다. 그래서 “이거야. 바로 이게 내가 찾던 것” 이라고 말할 수 있을 정도로요.

잡담은 이쯤하고, 바로 본론으로 들어가볼까요?

Atomic CSS란 무엇인가요?

Tailwind CSS에 앞서 Atomic CSS가 무엇인지 이해해봅시다. CSS Tricks에 따르면

“Atomic CSS는 시각적 기능에 기초한 이름을 가진 작고 단일 목적의 클래스를 선호하는 CSS 구조 접근법입니다.”

간단히 말해 단일 목적을 달성하기 위한 클래스를 만드는 것과 비슷합니다. 예를 들어 다음 CSS를 포함하는 bg-blue 클래스를 만들어봅시다:

.bg-blue {
  background-color: rgb(81, 191, 255);
}

이제 이 클래스를 태그에 추가하면, 위 코드에서 볼 수 있듯이 rgb(81, 191, 255) 색상의 파란 배경을 얻게 됩니다.

여기 HTML이 있습니다:

<div>
  <h1 class="bg-blue">Hello world!</h1>
</div>

그러면 HTML은 다음과 같은 결과를 만들어냅니다:

이제 직접 작성한 단일 목적 CSS 규칙들을 전역 CSS 파일에 모아보세요. 한 번의 투자일 뿐이지만 이렇게 생각해보세요 – 이제 어디서든 이 단일 목적 헬퍼 클래스를 사용할 수 있습니다.

HTML 파일이 전역 CSS 파일을 사용하기만 하면 됩니다. 그리고 HTML 태그 하나 안에서 이 헬퍼 클래스의 조합을 사용할 수도 있죠.

다른 예를 볼까요?

다음 규칙을 가진 CSS 파일을 만듭시다:

.bg-blue {
  background-color: rgb(81, 191, 255);
}
.bg-green {
  background-color: rgb(81, 255, 90);
}
.text-underline {
  text-decoration: underline;
}
.text-center {
  text-align: center;
}
.font-weight-400 {
  font-weight: 400;
}

그리고 다음과 같이 우리의 HTML 파일에서 이를 사용합시다:

<div>
  <h1 class="bg-blue">Hello world 1</h1>
</div>
<div>
  <h1 class="text-underline">Hello world 2</h1>
</div>
<div class="text-center">
  <h1 class="bg-green font-weight-400 text-underline">Hello world 3</h1>
</div>

이제 여기에는 다음과 같은 결과가 생성됩니다:

  • 여러 헬퍼 클래스 결합: 14번째 줄의 태그에서 여러 헬퍼 클래스를 결합한 것을 보세요, 즉 bg-green, font-weight-400, text-underline 입니다. Hello world 3 텍스트에 모두 적용되었죠.
  • 헬퍼 클래스의 재사용성: 위 예시에서 text-underline 헬퍼 클래스가 12행과 14행에서 여러 번 사용되는 것을 보세요.

HTML 페이지를 벗어나지 않고도 다양한 스타일을 추가할 수 있었습니다. 그렇다고 해서 “헬퍼 또는 유틸리티 클래스를 전역 CSS 파일에 작성해야 하는 것은 어쨌든가요?”라고 물으실 수 있겠죠. 맞습니다. 그것은 분명 시작하기 위한 초기 투자가 필요하죠.

그리고 Atomic CSS 아키텍처를 따르려면 우리가 얼마나 많은 단일 목적 헬퍼 또는 유틸리티 클래스를 만들어야 하는지 누가 알겠습니까.

그리고 여기서 Tailwind CSS가 등장합니다. Atomic CSS의 개념은 새로운 것이 아니지만, Tailwind CSS는 그것을 다른 수준으로 끌어올립니다.

Tailwind CSS – 유틸리티 우선 CSS 프레임워크

Tailwind CSS는 자신들의 웹사이트에 따르면 “유틸리티 우선 CSS 프레임워크”로, 요소 디자인을 위해서 마크업 내부에서 직접 사용할 수 있는 다양한 이론적인, 단일 목적 유틸리티 클래스를 제공합니다.

최근에 자주 사용하게 된 몇 가지 유틸리티 클래스는 다음과 같습니다:

  • flex: <div> 에 Flexbox를 적용합니다
  • items-center: <div> 에 CSS 속성 align-items: center;를 적용합니다
  • rounded-full: 이미지를 원형으로 만듭니다 등등

진심으로, 이 모든 유틸리티 클래스를 나열하는 것은 불가능합니다 왜냐하면 그렇게 많기 때문입니다. 그러나 제일 좋은 점은, 우리가 이 유틸리티 클래스들을 직접 작성하고 어떤 전역 CSS 파일에 넣어두지 않고도 Tailwind로부터 바로 받을 수 있다는 것입니다. 

Tailwind가 제공하는 모든 유틸리티 클래스 목록은 문서 페이지에서 확인할 수 있습니다. 또한 VS Code에서 작업을 한다면 Tailwind CSS IntelliSense라는 확장 프로그램을 설치하여 유틸리티 클래스를 입력하면서 자동으로 제안을 받을 수 있습니다, 아래 이미지에서처럼요.

Tailwind CSS 설정 방법

프로젝트에 Tailwind CSS를 설정하는 방법은 여러 가지가 있으며, 모두 문서에서 언급되어 있습니다.

Tailwind CSS는 Next, React, Angular 등과 같은 수많은 프레임워크와 심지어 오리지널 HTML과도 원활하게 작동합니다.

아래 실전 데모를 위해서는 Next 애플리케이션에서 Tailwind CSS를 사용하고 있습니다. Tailwind CSS를 사용하여 직접 Next 앱을 설정하려면 다음 명령어를 사용하세요:

npx create-next-app --example with-tailwindcss with-tailwindcss-app
yarn create next-app --example with-tailwindcss with-tailwindcss-app

프로젝트가 설정되면, 기본 카드 컴포넌트를 만드는 다음 단계로 넘어갈 수 있습니다.

실전 데모

Next 프로젝트에서 카드 컴포넌트를 만들어봅시다.

// Card.js file
// to be rendered in index.js

import React from "react";

const Card = () => {
  return (
    <div className="relative w-96 m-3 cursor-pointer border-2 shadow-lg rounded-xl items-center">
      {/* Image */}
      <div className="flex h-28 bg-blue-700 rounded-xl items-center justify-center">
        <h1 className="absolute mx-auto text-center right text-2xl text-white">
          Image goes here
        </h1>
      </div>

      {/* Description */}
      <div className="p-2 border-b-2">
        <h6>
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Facilis
          beatae nulla, atque et sunt ad voluptatum quidem impedit numquam quia?
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Facilis
          beatae nulla, atque et sunt ad voluptatum quidem impedit numquam quia?
        </h6>
      </div>

      {/* Tech stack used */}
      <div className="flex flex-wrap items-center m-2">
        <span className=" border border-blue-300 rounded-2xl px-2 my-1 mx-1">
          #React
        </span>
        <span className=" border border-blue-300 rounded-2xl px-2 my-1 mx-1">
          #Redux
        </span>
        <span className=" border border-blue-300 rounded-2xl px-2 my-1 mx-1">
          #Javascript
        </span>
      </div>

      {/* Links */}
      <div className="flex flex-wrap items-center rounded-b-xl border-t-2 bg-white">
        <button className="border rounded-2xl bg-blue-600 text-white shadow-sm p-1 px-2 m-2">
          Go to Project
        </button>
        <button className="border-2 border-blue-600 rounded-2xl text-blue-600 shadow-sm p-1 px-2 m-2">
          Github
        </button>
      </div>
    </div>
  );
};

export default Card;

이 결과는 UI에 다음과 같은 카드를 렌더링합니다:

Card.js 파일을 벗어나지 않고도 카드 컴포넌트를 얼마나 쉽게 스타일링할 수 있는지 보세요. 추가적인 CSS 파일을 작성할 필요가 없습니다.

<div>에서 flex를 사용하면 그게 바로 display: flex; CSS 규칙을 적용하는 겁니다.

<div>에 position: relative;를 추가하고 싶다면 className에 relative를 추가하기만 하면 됩니다.

hover, active, focus 등과 같은 다양한 수정자를 추가하여 유틸리티 클래스를 조건적으로 렌더링할 수도 있습니다. 다음과 같이 복잡한 CSS 규칙을 적용할 수 있습니다:

.some-class-name {
          --tw-space-x-reverse: 0;
          margin-right: calc(0.5rem * var(--tw-space-x-reverse));
          margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
}

그리고 이러한 스타일을 전역 CSS 파일에서 명시적으로 언급해야 할까요? 전혀 그럴 필요가 없습니다! Tailwind가 자동으로 해결해줍니다. 그게 바로 Tailwind의 아름다움입니다. 하지만… 아직 끝난 것이 아닙니다. 지금부터 다른 장점들을 살펴보겠습니다.

Tailwind CSS의 장점

초고속 빌드 시간을 제공하는 Just-In-Time (JIT) 모드
Tailwind v3 이전까지, 빌드를 최소한의 크기로 유지하기 위해 사용되지 않는 스타일을 모두 제거했습니다.

Tailwind에 따르면, 생산 환경에서의 빌드는 5-10kB 사이였습니다. 그러나 그것은 생산 환경에서의 이야기였고, 개발 환경에서는 CSS가 특히 많은 개인 설정을 사용하는 경우 정말 커질 수 있습니다.

v3 이상에서, Tailwind는 Just-in-Time 컴파일러라는 새로운 기능을 출시했습니다. JIT 컴파일러는 upfront에서 전체 CSS를 컴파일하는 것을 피하고 필요할 때마다 CSS를 컴파일합니다.

이는 모든 환경에서 초고속 빌드 시간을 초래합니다. 그리고 우리가 필요로 할 때마다 스타일이 생성되기 때문에 사용되지 않는 스타일을 제거할 필요가 없습니다. 이는 모든 환경에서 CSS가 동일하다는 것을 의미하며, 생산 환경에서 중요한 CSS가 제거될까 봐 걱정하는 일을 없앨 수 있습니다.

옵션이 풍부하고 동시에 유연합니다

Tailwind CSS는 옵션이 풍부합니다. 스타일링과 관련하여 일부 제약을 명시하고, 저로서는 이것이 좋다고 생각합니다. 왜냐하면 실제로 이해하는 사람들에게 디자인 부분을 유지하도록 도와주기 때문입니다.

<div>에 박스 쉐도우를 추가하기 위한 유틸리티 클래스 중 하나를 보세요

보시다시피, Tailwind는 수직 및 수평 오프셋, 흐림, 확산, 색상 및 불투명도에 대한 사전 설정된 값을 제공하는 그림자의 8가지 변형만을 제공합니다. 이것이 Tailwind가 의견을 제시하는 방식입니다.

거의 모든 스타일링 속성에 대해 선택할 수 있는 속성 값에 대한 의견을 제시하려고 시도하고, 신뢰하세요, 박스 쉐도우(그림자)의 이 8가지 변형이 일반적인 경우에도 훌륭한 UI를 만들기에 충분하다고 생각합니다.

UI의 다른 영역에서 특정 유틸리티 클래스의 동일한 변형을 사용하면 전체 응용 프로그램에 걸쳐 일관성을 유지하고, 이로 인해 더 나은 사용자 경험(UX)을 얻을 수 있습니다.

하지만 특정 스타일에 매우 맞춤화된 값을 필요로 하는 경우라면, tailwind.config.js에 사용자 지정 테마를 추가함으로써 그 값을 얻을 수 있습니다. 예를 들어 Tailwind가 기본적으로 제공하지 않는 shadow-3xl을 얻고자 한다면, tailwind.config.js의 module.exports에 다음과 같은 줄을 추가하면 됩니다.

module.exports = {
  theme: {
    extend: {
      boxShadow: {
        '3xl': '0 35px 60px -15px rgba(0, 0, 0, 0.3)',
      }
    }
  }
}

그리고 JIT의 등장으로 이제 괄호([]) 안에 임의의 값을 사용할 수 있게 되었습니다. 예를 들면 아래와 같죠:

<div class="shadow-[0_35px_60px_-15px_rgba(0,0,0,0.3)]">
  // Rest of your code goes here
</div>

특정 스타일이 소수의 장소에서만 필요할 때 임의의 값의 사용이 유용할 수 있습니다. 이 경우에는 tailwind.config.js에 테마를 만드는 것이 불필요할 수도 있습니다.

결론

저는 정말로 여러분이 Tailwind CSS가 무엇인지, 또 여러분이 그것을 활용하여 무엇을 할 수 있는지에 대해 이해할 수 있게 도왔으면 합니다.

Tailwind는 우리가 마크업이나 .js/.jsx/.ts/.tsx 파일 안에서 웹 페이지들을 디자인하는 데 도움이 되는 단일 목적의 유틸리티 클래스들을 제공하는 CSS 프레임워크입니다.

제 생각에 Tailwind는 단순하고 이해하기 쉽습니다. 모든 유틸리티 클래스 이름에 익숙해지는 데는 약간의 시간이 걸릴 수 있습니다만, 걱정 마세요 – 막혔을 때는 언제든지 그들의 문서를 참조할 수 있습니다.

https://tailwindcss.com/