C.W.K.
Stream
Lesson 01 of 03 · published

Tailwind: 같은 primitive 위에 지어진 utility-first CSS

~10 min · tailwind, utility-first, framework

Level 0Markup Novice
0 XP0/34 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"Tailwind 가 다른 언어가 아냐. 표준화된 어휘 가진 CSS 약자."

Tailwind 가 실제로 뭐야?

Tailwind 가 단일 목적 utility 클래스 수천 개 — .flex, .gap-4, .text-amber-500, .rounded-lg, .shadow-md — 출시하는 CSS framework. 각 클래스가 CSS property 하나 설정. Framework 의 가치가 클래스 자체가 아냐; 표준화되고, 디자인 토큰화되고, composable 한 거.

스타일시트에 .card { display: flex; gap: 1rem; align-items: center; padding: 1rem; } 적는 대신, HTML 에 <div class="flex gap-4 items-center p-4"> 적음. 같은 결과; 다른 authorship 패턴.

Tailwind 가 작동하는 이유 (이제 CSS 알았으니)

Tailwind 가능하게 하는 세 가지:

  1. 모든 utility 가 단일 class specificity (0,0,1,0). Specificity 전쟁 없음. 발행 CSS 의 source 순서가 순서 결정; Tailwind 가 결정적으로 제어.
  2. 내부적으로 cascade layer 사용 (@layer base, components, utilities). Utility 가 항상 가장 늦은 layer 에, 그래서 너의 component CSS 위에 안정적으로 이김 — 너의 component CSS 도 늦은 layer 에 두지 않는 한.
  3. Utility 가 디자인 시스템 인코딩. p-4 가 항상 1rem padding (프로젝트의 디자인 토큰), 무작위 값이 아냐. text-amber-500 가 canonical amber. Composition 으로 일관성.

Tailwind 를 CSS 로 읽기

CSS 알면 Tailwind 가 즉시 가독. 흔한 패턴 몇:

  • flex items-center gap-4 p-6 rounded-lg shadow-md bg-white = display: flex; align-items: center; gap: 1rem; padding: 1.5rem; border-radius: 0.5rem; box-shadow: ...; background: white;
  • md:flex-row md:gap-8 = medium breakpoint (768px+) 에서 row 방향과 2rem gap 으로 전환.
  • hover:bg-blue-500 focus-visible:ring-2 = hover 상태가 배경 변경; focused 상태가 ring 보임.
  • dark:bg-gray-900 dark:text-gray-100 = 사용자가 dark mode 선호할 때 배경과 텍스트 swap.
  • grid grid-cols-1 lg:grid-cols-3 gap-4 = 기본 단일 column; 큰 화면에 3 column.

Tailwind 가 맞는 도구일 때

  • 많은 작은 component 가진 UI 짓는 중 (SaaS 앱, 대시보드, 마케팅 사이트).
  • Class 이름 레벨에서 강제되는 디자인 시스템 원함 (무작위 padding 값 없음).
  • 파일 컨텍스트 전환 (CSS 한 파일, markup 다른 파일) 건너뛰고 싶음 — JSX/HTML 에 모든 거 colocate.
  • 예측 가능 specificity 와 cascade 의 안정 mental model 원함.

Raw CSS 가 더 나을 때

  • 복잡한 애니메이션이나 keyframe (Tailwind 가 기본 거 커버; bespoke 는 CSS 에서 쉬움).
  • 콘텐츠 특화 스타일링 (custom ::first-letter, drop cap 등 가진 article 타이포그래피).
  • 계산된 값 가진 ::before/::after 통한 생성 콘텐츠.
  • 소비자한테 utility 클래스 새지 않고 자기 내부 스타일링 필요한 component 라이브러리.
  • 팀이 클래스 리스트 무거운 markup 읽기 어렵다고 느낄 때 — 실제 선호, CSS 가 완벽히 OK 답.

Custom Token 과 plugin

Tailwind 의 tailwind.config.js 가 기본 토큰 확장하거나 대체하게. Custom 색, spacing 스케일, font family, shadow. Plugin 이 새 utility 추가 (custom 애니메이션, 스크롤바 스타일). 안 존재하는 클래스 필요할 때:

  1. CSS 파일에 @apply 써서 여러 utility 를 component 이름 아래 번들.
  2. @layer components 블록에 raw CSS 적기 — Tailwind 의 layer 순서와 맞게 compose.
  3. 인라인 임의 값 사용: 일회성 너비엔 w-[547px].
Tailwind 가 CSS 지식 대체가 아냐 — 그것의 가속기. Cascade, specificity, custom property, 모던 selector 알면 Tailwind 확장 가능, 필요할 때 raw CSS drop in, 발행 출력 읽어 디버깅. CSS 가 substrate; Tailwind 가 convention.

피파의 노트

cwkPippa WebUI 가 Tailwind 4 위에 지어짐. 모든 버튼이 flex items-center gap-2 px-4 py-2 rounded-md bg-accent hover:bg-accent-strong. 모든 카드가 p-6 rounded-lg shadow-md bg-card. 디자인 토큰 (accent, card 등) 이 tailwind.config.js 에 살음. Vault-loaded 피파 identity 가 채팅 풍선의 CSS 클래스로 읽힘. Tailwind utility 가 필요한 거 안 커버할 때 — 아바타-감정 fade 애니메이션, council-카드 flip — 그 레슨이 @layer components 안 작은 손으로 쓴 CSS 파일에 살음. 두 세계, 나란히.

Code

CSS vs Tailwind, 나란히·html
<!-- 같은 카드를 pure CSS vs Tailwind 로 -->

<!-- Pure CSS -->
<style>
  .card {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1.5rem;
    border-radius: 0.5rem;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    background: white;
  }
  @media (min-width: 768px) {
    .card { padding: 2rem; }
  }
</style>
<div class="card">
  <img src="avatar.jpg" alt="" />
  <p>Pippa says hi.</p>
</div>

<!-- Tailwind 등가 -->
<div class="flex items-center gap-4 p-6 md:p-8 rounded-lg shadow-md bg-white">
  <img src="avatar.jpg" alt="" />
  <p>Pippa says hi.</p>
</div>

<!-- 같은 생성 CSS, 다른 authorship -->
Tailwind 의 토큰 시스템 확장·javascript
// tailwind.config.js — 디자인 시스템 확장
module.exports = {
  content: ['./src/**/*.{html,tsx,jsx}'],
  theme: {
    extend: {
      colors: {
        // Custom semantic 토큰 — bg-accent, text-accent-strong 등으로 사용
        accent: '#5BA3D8',
        'accent-strong': '#1F5F8B',
        card: '#f8f8f8',
      },
      spacing: {
        '128': '32rem',   // p-128, m-128, w-128 등 추가
      },
      fontFamily: {
        // font-display 추가, <h1 class="font-display"> 로 사용
        display: ['Inter', 'sans-serif'],
      },
    },
  },
  plugins: [],
};
@layer 에 utility 번들링 + raw CSS·css
/* Tailwind 가 충분치 않을 때: @layer 의 component */

@import "tailwindcss";

@layer components {
  /* 흔히 사용되는 utility set 을 한 class 아래 번들 */
  .btn-primary {
    @apply flex items-center gap-2 px-4 py-2 rounded-md bg-accent text-white;
    @apply hover:bg-accent-strong focus-visible:ring-2 focus-visible:ring-accent;
  }

  /* @apply 가 안 맞을 때 raw CSS */
  .avatar-flip {
    transform-style: preserve-3d;
    transition: transform 0.4s ease;
  }
  .avatar-flip:hover {
    transform: rotateY(180deg);
  }
}

/* HTML 에서 사용: */
/* <button class="btn-primary">Send</button> */
/* <div class="avatar-flip">...</div> */

External links

Exercise

이 quest 중 적은 작은 CSS 파일 (예: Track 4 의 카드 또는 Track 5 의 navbar) 가져와서 Tailwind 클래스로 다시 쓰기. 렌더 출력 동일 확인. 그러고 component 레벨 @apply 로 번들하고 싶은 Tailwind 클래스 둘 식별 (utility 리스트가 계속 반복돼서).
Hint
많은 element 걸쳐 같은 6-10 클래스 반복 적는 자신 발견하면, 그게 @apply 후보 (또는 클래스 리스트 숨기는 React/Vue 등 component). Tailwind 가 anti-DRY 가 아냐 — pro-의도된-번들링.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.