ReactNextCentral

함수와 지시어

Published on
Tailwind가 CSS에 제공하는 사용자 정의 함수와 지시어에 대한 참고 자료입니다.
Table of Contents

Tailwind는 CSS에 적용할 수 있는 다양한 사용자 정의 함수와 지시어를 제공하여 프로젝트의 스타일을 보다 세밀하게 조정할 수 있도록 돕습니다.


지시어

지시어는 Tailwind CSS 프로젝트에 특별한 기능을 제공하는 사용자 정의 Tailwind 전용 at-rule입니다.

@tailwind

@tailwind 지시어를 사용하여 Tailwind의 base, components, utilities, 그리고 variants 스타일을 CSS에 삽입합니다.

/**
 * 이것은 Tailwind의 기본 스타일과 플러그인에 의해 등록된 기본 스타일을 삽입합니다.
 */
@tailwind base;

/**
 * 이것은 Tailwind의 컴포넌트 클래스와 플러그인에 의해 등록된 컴포넌트 클래스를 삽입합니다.
 */
@tailwind components;

/**
 * 이것은 Tailwind의 유틸리티 클래스와 플러그인에 의해 등록된 유틸리티 클래스를 삽입합니다.
 */
@tailwind utilities;

/**
 * 이 지시어는 Tailwind가 호버, 포커스, 반응형, 다크 모드 등 각 클래스의 변형을
 * 삽입하는 위치를 제어하는 데 사용됩니다.
 *
 * 생략하면 Tailwind는 기본적으로 스타일시트의 맨 끝에 이 클래스들을 추가합니다.
 */
@tailwind variants;

@layer

@layer 지시어를 사용하여 Tailwind에 어떤 "범주"에 사용자 정의 스타일이 속하는지 알립니다. 유효한 레이어는 base, components, 그리고 utilities입니다.

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  h1 {
    @apply text-2xl;
  }
  h2 {
    @apply text-xl;
  }
}

@layer components {
  .btn-blue {
    @apply bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded;
  }
}

@layer utilities {
  .filter-none {
    filter: none;
  }
  .filter-grayscale {
    filter: grayscale(100%);
  }
}

Tailwind는 @layer 지시어 내의 CSS를 해당하는 @tailwind 규칙과 같은 위치로 자동으로 이동시켜, 특정 순서에 따라 CSS를 작성하여 우선 순위 문제를 피할 필요가 없습니다.

레이어에 추가된 사용자 정의 CSS는 HTML에서 실제로 사용될 때만 최종 빌드에 포함되며, 이는 Tailwind에 기본적으로 포함된 모든 클래스와 마찬가지입니다.

@layer를 사용하여 사용자 정의 CSS를 감싸면 hover:focus:와 같은 수정자를 사용하거나 md:, lg:와 같은 반응형 수정자를 사용할 수 있습니다.


@apply 사용하기

@apply를 사용하여 기존 유틸리티 클래스들을 여러분의 커스텀 CSS로 인라인하여 적용할 수 있습니다. 이 방법은 타사 라이브러리의 스타일을 오버라이드 해야 할 때나 여러분의 디자인 토큰을 사용하며 익숙한 HTML 문법을 사용하고 싶을 때 유용합니다.

.select2-dropdown {
  @apply rounded-b-lg shadow-md;
}
.select2-search {
  @apply border border-gray-300 rounded;
}
.select2-results__group {
  @apply text-lg font-bold text-gray-900;
}

@apply로 인라인된 규칙들은 기본적으로 !important가 제거되어 특이점 문제를 피할 수 있습니다.

/* 입력 */
.foo {
  color: blue !important;
}

.bar {
  @apply foo;
}

/* 출력 */
.foo {
  color: blue !important;
}

.bar {
  color: blue;
}

기존 클래스에 !important를 적용하고 싶다면 선언의 끝에 !important를 추가하면 됩니다.

/* 입력 */
.btn {
  @apply font-bold py-2 px-4 rounded !important;
}

/* 출력 */
.btn {
  font-weight: 700 !important;
  padding-top: .5rem !important;
  padding-bottom: .5rem !important;
  padding-right: 1rem !important;
  padding-left: 1rem !important;
  border-radius: .25rem !important;
}

Sass/SCSS를 사용하는 경우 Sass의 보간 기능을 사용해야 합니다.

.btn {
  @apply font-bold py-2 px-4 rounded #{!important};
}

컴포넌트별 CSS에서 @apply 사용하기

Vue와 Svelte와 같은 컴포넌트 프레임워크는 각 컴포넌트 파일 내에 <style> 블록을 통해 컴포넌트별 스타일을 추가할 수 있게 지원합니다.

전역 CSS에 정의된 커스텀 클래스를 이러한 컴포넌트별 <style> 블록에서 @apply로 적용하려고 하면 클래스가 존재하지 않는다는 오류가 발생합니다.

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
  .card {
    background-color: theme('colors.white');
    border-radius: theme('borderRadius.lg');
    padding: theme('spacing.6');
    box-shadow: theme('boxShadow.xl');
  }
}
<div>
  <slot></slot>
</div>

<style>
  div {
    /* main.css와 별도로 처리되기 때문에 작동하지 않음 */
    @apply card;
  }
</style>

Vue와 Svelte 같은 프레임워크는 내부적으로 각 <style> 블록을 독립적으로 처리하며, PostCSS 플러그인 체인을 각각에 대해 실행합니다.

이는 <style> 블록이 있는 10개의 컴포넌트가 있다면, Tailwind가 10번 별도로 실행되며, 각 실행은 다른 실행과 관련 정보를 공유하지 않는다는 것을 의미합니다. 따라서 Card.svelte에서 @apply card를 시도하면 Tailwind는 card 클래스가 존재하는지 알지 못하고 실패합니다. 왜냐하면 Svelte가 Card.sveltemain.css를 서로 독립적으로 처리했기 때문입니다.

이 문제의 해결책은 원하는 커스텀 스타일을 컴포넌트에서 @apply하기 위해 플러그인 시스템을 사용하여 정의하는 것입니다.

const plugin = require('tailwindcss/plugin')

module.exports = {
  // ...
  plugins: [
    plugin(function ({ addComponents, theme }) {
      addComponents({
        '.card': {
          backgroundColor: theme('colors.white'),
          borderRadius: theme('borderRadius.lg'),
          padding: theme('spacing.6'),
          boxShadow: theme('boxShadow.xl'),
        }
      })
    })
  ]
}

이 방법을 사용하면 이 설정 파일을 사용하는 Tailwind가 처리하는 모든 파일이 이 스타일에 접근할 수 있습니다.

솔직히 가장 좋은 해결책은 이런 이상한 방식을 전혀 사용하지 않는 것입니다. Tailwind의 유틸리티를 의도된 대로 마크업에서 직접 사용하고, @apply 기능을 남용하여 이런 일을 하지 않으면 훨씬 나은 경험을 할 수 있습니다.

@config 지시어 사용하기

@config 지시어는 Tailwind가 해당 CSS 파일을 컴파일할 때 사용할 설정 파일을 지정합니다. 이는 다른 CSS 진입점에 대해 서로 다른 구성 파일을 사용해야 하는 프로젝트에 유용합니다.

@config "./tailwind.site.config.js";

@tailwind base;
@tailwind components;
@tailwind utilities;
@config "./tailwind.admin.config.js";

@tailwind base;
@tailwind components;
@tailwind utilities;

@config 지시어에 제공된 경로는 해당 CSS 파일에 상대적이며, PostCSS 설정이나 Tailwind CLI에서 정의된 경로보다 우선합니다.

postcss-import를 사용하는 경우, 정상적으로 작동하려면 @import 구문을 @config보다 앞에 배치해야 합니다. postcss-import는 CSS 규격을 엄격히 따르며, 파일 내의 다른 규칙보다 @import 구문이 앞서야 합니다.

@import 구문 앞에 @config를 배치하지 마세요

@config "./tailwind.admin.config.js";

@import "tailwindcss/base";
@import "./custom-base.css";
@import "tailwindcss/components";
@import "./custom-components.css";
@import "tailwindcss/utilities";

@import 구문을 @config 지시어보다 앞에 배치하세요다.

@import "tailwindcss/base";
@import "./custom-base.css";
@import "tailwindcss/components";
@import "./custom-components.css";
@import "tailwindcss/utilities";

@config "./tailwind.admin.config.js";


함수

Tailwind는 Tailwind 특정 값에 접근할 수 있는 몇 가지 사용자 정의 함수를 제공합니다. 이 함수들은 빌드 시에 평가되며 최종 CSS에서는 정적 값으로 대체됩니다.

theme()

theme() 함수를 사용하여 점 표기법을 사용해 Tailwind 구성 값에 접근하세요.

.content-area {
  height: calc(100vh - theme(spacing.12));
}

점이 포함된 값(예: 간격 스케일의 2.5 값)에 접근해야 할 경우, 대괄호 표기법을 사용할 수 있습니다:

.content-area {
  height: calc(100vh - theme(spacing[2.5]));
}

Tailwind는 기본 색상 팔레트를 정의하기 위해 중첩 객체 문법을 사용하기 때문에 중첩된 색상에 접근할 때는 점 표기법을 사용하세요.

중첩된 색상 값에 접근할 때 대시 문법을 사용하지 마세요

.btn-blue {
  background-color: theme(colors.blue-500);
}

중첩된 색상 값에 접근할 때 점 표기법을 사용하세요.

.btn-blue {
  background-color: theme(colors.blue.500);
}

theme으로 검색한 색상의 불투명도를 조정하려면, 원하는 불투명도 값을 지정하는 슬래시를 사용하세요:

.btn-blue {
  background-color: theme(colors.blue.500 / 75%);
}

screen()

screen 함수를 사용하면 이름으로 미디어 쿼리를 생성하여 브레이크포인트를 참조할 수 있습니다. 이는 자신의 CSS에 그 값을 중복해서 사용하는 것을 방지합니다.

@media screen(sm) {
  /* ... */
}

이는 빌드 시에 기본 화면 값으로 해석되어 지정된 브레이크포인트와 일치하는 일반 미디어 쿼리를 생성합니다:

@media (min-width: 640px) {
  /* ... */
}