Tailwind CSS 기초
Next.js 개발자를 위한 Tailwind CSS 기초
Next.js 개발자를 위한 TailwindCSS 기초
Tailwind는 유틸리티 클래스(utility classes) 모음(혹은 집합)이며, CSS 파일을 생성하는 도구입니다. Tailwind에서 제공하는 유틸리티 클래스를 다양하게 조합하는 방법(
@apply지시문) 등과 같은 고급 기능을 활용하기 위해선,도구(tool chain)을 설치해야 합니다. 하지만 본 노트는, 초급자가Next.js프로젝트에서 별다른 설정없이 곧바로 CSS를 활용할 수 있도록 하는 것에 목표를 두고 있습니다. 따라서, 본 노트는 Next.js 프로젝트를 기반으로 설명하고 있으며, 해당 문서에 있는 내용을 실습하기 위해선 Next.js v16.0.1 설치되어 있다고 가정합니다.
1. Quick Start
히어로 세그먼트(hero segment) 스타일링을 빠르게 진행해 보겠습니다. 머전 Next.js 프로젝트를 생성해 봅시다.
app/page.tsx 파일을 아래와 같이 수정합니다.
HTML <h1> 태그에서 제공하는 어떤 형태로 반영되어 있지 않는 문자열을 브라우저에서 확인할 수 있습니다. 간단하게 Tailwind로 기능들을 추가해 보겠습니다. 상세한 설명은 생략하도록 하겠습니다. 그리고 제가 디자이너가 아니라는 점을 미리 밝혀둬야겠습니다.
단지, Tailwind를 사용해서 빠르게 레이아웃을 구성하는 방법을 실습을 통해서 확인해보도록 하겠습니다. 아래 코드를 적용하면, 첫 번째 버전과 크게 다르지 않습니다. 텍스트에는 여전히 스타일이 적용되지 않았고, 간격이나 다른 어떤 것도 없습니다.
몇 가지 변경 사항을 더 추가해 봅시다. 텍스트를 중앙에 맞추고, 두 부분 사이에 약간의 거리를 두겠습니다. 텍스트만 출력하면 너무 밋밋하기 때문에 로고를 추가하겠습니다.
아래 코드에 두 개의 클래스를 추가했습니다. 바깥쪽 div는 이제 flex와 justify-center라는 두 개의 Tailwind 클래스가 적용됩니다. 이미지는 mx-4와 order-last라는 두 개의 클래스를, 텍스트 블록 역시 mx-4와 self-center 클래스를 가집니다. mx-4 클래스는 수평 마진(horizontal margin)을 지정하며, 나머지 클래스들은 모두 CSS flexbox 구조를 사용한 레이아웃을 다룹니다.
// v3
<div className="flex justify-center">
<div className="mx-4 order-last">
<img src="next.svg" width={300} height={300} />
</div>
<div className="mx-4 self-center">
<h1 className="text-6xl font-bold text-blue-700">Welcome to Next.js</h1>
<h2 className="text-3xl font-semibold text-blue-300">The React Framework for the Web</h2>
</div>
</div>이제 텍스트를 손볼 차례입니다. 헤더는 크게, 서브헤더는 그것보다 작게 만들고, 모든 라인을 중앙 정렬해 봅시다. 그리고 전체에 배경색을 지정해 봅시다. 이것은 바깥쪽 div에 bg-gray-300이라는 새 클래스를 추가하여 배경색을 지정합니다. 텍스트 요소들을 감싸는 text-center 클래스를 포함하여 여러 클래스들을 텍스트 요소에 추가했습니다. 타이틀 요소는 이제 text-6xl font-bold text-blue-700으로 표시되어, 텍스트 크기, 글꼴 굵기, 색상을 지정합니다. 서브헤드는 text-3xl font-semibold text-blue-300으로, 더 작고, 덜 굵으며, 더 옅은 파란색입니다.
// v4
<div className="flex justify-center bg-gray-300">
<div className="mx-4 order-last">
<img src="next.svg" width={300} height={300} />
</div>
<div className="mx-4 self-center text-center">
<h1 className="text-6xl font-bold text-blue-700">Welcome to Next.js</h1>
<h2 className="text-3xl font-semibold text-blue-300">
The React Framework for the Web
</h2>
</div>
</div>이미지를 재정렬하며, 이미지를 더 둥글게 만들어 보도록 하겠습니다. 그리고 간단한 버튼도 추가해보겠습니다.
// v5
<div className="flex justify-center bg-gray-300">
<div className="mx-4 order-last">
<img className="rounded-full" src="next.svg" width={300} height={300} />
</div>
<div className="mx-4 self-center text-center">
<h1 className="text-6xl font-bold text-blue-700">Welcome to Next.js</h1>
<h2 className="text-3xl font-semibold text-blue-300">
The React Framework for the Web
</h2>
<button className="my-4 px-4 py-2 border-2 border-black rounded-lg text-white bg-blue-900">More</button>
</div>
</div>rounded-full 클래스는 이미지를 원형으로 만듭니다. my-4 px-4 py-2는 수직 마진(vertical margin) 및 수평/수직 패딩(padding)을 지정합니다. border-2 border-black rounded-lg는 테두리의 크기, 색상, 모양을 지정합니다. text-white bg-blue-900은 텍스트와 배경색을 지정합니다.
시작치고는 나쁘지 않습니다. 각 단계마다 마크업에 Tailwind 클래스를 추가하여 코드의 표시 방식을 점진적으로 변경할 수 있었고, 수정 사항이 즉시적으로 화면에 반영되는 것을 확인할 수 있습니다.
Tailwind 기본 사항
Tailwind는 복잡한 CSS 관리 문제를 해결하는 것처럼 보이지 않습니다. 오히려 코드의 중복이 많아 보입니다. 왜냐하면, Tailwind는 수많은 작은 유틸리티로 구성된 CSS 클래스로 구성되어 있기 때문입니다. 따라서 Tailwind에서 복잡한 동작을 구현하는 방법은 HTML 요소에 여러 CSS 클래스를 함께 조합하는 것입니다. 이 패턴은 수년에 걸쳐 개발된 많은 CSS 이름짓기 관례에 어긋납니다. 많은 CSS 프레임워크와 이름짓기 관례는 페이지에서 요소의 시맨틱 의미(semantic meaning)를 반영하는 이름(button, nav-bar 또는 menu-item)을 사용할 것을 제안합니다. 하지만, Tailwind 클래스는 전혀 시맨틱하지 않습니다.
Tailwind는 font-bold나 m-6처럼 특정 CSS 속성을 세부적으로 정의하고 있습니다. 다른 CSS 프레임워크도 유틸리티 클래스를 포함하지만, 시맨틱 클래스 이름을 더 중요하게 여깁니다. Tailwind 유틸리티 클래스는 종종 여러 DOM 요소에서 반복되기 때문에, Tailwind와 유틸리티 클래스를 사용하면 중복이 많이 발생할 가능성이 있습니다1.
따라서, Tailwind는 스타일 변경의 이유와 범위가 명확하고, 정확해야 합니다. Tailwind에서 제공하는 클래스의 이름이 짧기 때문에 처음에는 암호처럼 보일 수 있습니다. 하지만, 이름 패턴이 일관성이 있기 때문에 충실하게 배운다면 읽기 쉬워집니다. 또한 Tailwind 수식어(modifier)를 사용하면 hover 동작이나 다양한 크기의 화면에 대한 반응형 동작과 같은 특별한 동작을 HTML에서 정의할 수 있습니다. 수식어는 HTML을 보는 것만으로도 요소의 전체 스타일을 더 명확하게 파악할 수 있게 해줍니다.
그리고, Tailwind 클래스를 임의의 방식으로 조합해서 사용할 수 있는 방법을 제공합니다. 다른 CSS 스타일을 사용할 때보다 외부 CSS 코드를 적게 작성하게 됩니다. 그리고 Tailwind의 변경 사항은 HTML 마크업과 매우 밀접하게 연결되어 있으므로, 변경 시 결과를 예측하기가 더 쉽습니다.
Tailwind는 몇 가지 다른 부분으로 구성되어 있습니다. 이 노트는 유틸리티 클래스, 리셋(reset) 스타일시트, 그리고 Tailwind 작업을 더 쉽게 만들어주는 함수에 대해서 공식 문서를 참조할 수 있을 수준에서 간략하게 소개하겠습니다.
Utilities Classes
Tailwind의 유틸리티 클래스는 Tailwind를 이해하는 데 가장 중요한 부분입니다. Tailwind는 수천 개, 어쩌면 수백만 개의 유틸리티 클래스로 이루어져 있으며, 대부분은 단일 CSS 속성의 값을 설정합니다. 예를 들어, font-bold Tailwind 유틸리티 클래스는 CSS 속성 font-weight: 700의 별칭(alias)입니다. 이 유틸리티는 className="font-bold"처럼 HTML 요소의 class 속성 일부로 사용됩니다. 그리고, Next.js에서는 class 속성이 아니랄 className 속성을 사용합니다. 꼭 기억하세요.
Tailwind는 단일 프로젝트에서 사용하는 클래스를 능가하는 것들을 제공합니다. 불필요하게 생성되는 CSS를 제한하기 위해, Tailwind는 별도의 CSS 클래스 집합을 생성하는 방법을 제공합니다. 또한, Tailwind 설정 파일을 통해 Tailwind가 찾는 패턴과 이름을 더 세밀하게 제어할 수 있습니다. 이 노트에서 특별히 명시하지 않는 한, 저는 최소한의 설정으로 사용되는 기본 클래스에 대해서 소개합니다.
Tailwind 유틸리티는 종종 공통된 시작 패턴이나 종료 패턴을 가진 패밀리(family)로 제공됩니다. 예를 들어, text-xs, text-sm, text-xl 등을 포함하는 유틸리티 패밀리를 나타내기 위해 text-{크기}와 같은 구문을 사용합니다. 이 구문을 사용할 때, 중괄호 안의 부분이 비어 있지 않은 경우에만 대시(-)가 필요합니다. 따라서 text-sm을 사용하지만, 잠재적으로는 그냥 text만 사용할 수도 있습니다. 또한 마진 크기 유틸리티에서 .m{방향}-{크기}는 m-0 또는 .mt-10과 같은 유틸리티 패밀리를 나타냅니다. 앞으로 보게 되겠지만, 유틸리티의 변수 부분은 Tailwind의 여러 부분에서 일관되게 사용됩니다. 예를 들어, 마진 유틸리티의 {크기}와 {방향} 옵션은 패딩 유틸리티 및 여러 다른 유틸리티 패밀리에서도 공유됩니다.
Tailwind는 크기나 색상 같은 것에 대한 기본값 세트를 제공하지만, 대괄호([])로 값을 감싸서 임의의 값(arbitrary value)을 사용할 수도 있습니다. 예를 들어, 일회성 마진이 필요하다면 m-[104px]를 사용하여 104픽셀 마진을 지정할 수 있는데, 이는 기본으로 제공되는 크기가 아닙니다. 일반적으로, 변수 플레이스홀더가 있는 곳이라면 어디든 대괄호를 사용하여 임의의 값을 삽입할 수 있습니다. 이러한 임의의 값 사용은 일회성 수정을 위한 것입니다. 만약 동일한 임의의 값을 반복해서 사용하고 있다면, 해당 값을 설정 파일에 추가하여 전반적으로 사용 가능하게 하고 디자인 일관성을 유지하는 것이 좋습니다.
심지어 Tailwind가 지원하지 않는 CSS 스타일 속성을 사용해야 하는 경우, [mask-type:alpha]처럼 대괄호를 사용하여 전체 CSS 스타일 속성을 삽입할 수도 있습니다.
Preflight
Tailwind를 설치할 때, @tailwind base, @tailwind components, @tailwind utilities 명령어를 사용하여 세 개의 다른 파일을 임포트해야 합니다. 이 파일들은 각각 다른 CSS 규칙 세트를 포함하고 있습니다. app/globals.css 파일에서 Tailwind 관련 스타일을 정의하고 있습니다.
@tailwind base는 Preflight라고 불리는 Tailwind의 리셋 스타일시트(reset stylesheet)를 포함합니다. 리셋 스타일시트는 모든 기본 HTML 요소들을 최소한의 스타일 속성 세트로 다시 스타일링하는 것입니다. 리셋 스타일시트가 없다면, 각 브라우저는 추가적인 CSS 속성이 없는 개별 HTML 요소들을 렌더링하는 방법에 대해 자신만의 기본 스타일 속성 세트를 정의합니다. 리셋 스타일시트를 사용하면 애플리케이션이 이 기준선(baseline)을 제어할 수 있게 되어, 브라우저 간의 차이를 없애고 우리가 직접 커스텀 스타일링을 삽입할 수 있는 더 최소화된 배경을 제공합니다.
Tailwind가 사용하는 리셋 스타일의 전체 세트는 node_modules/tailwindcss/preflight.css 파일에서 확인할 수 있습니다.
- 헤더(
h1등)의 모든 스타일링을 오버라이드(override)하여, 아무런 스타일링이 적용되지 않은 형태로 만듬 - 일반적으로 마진을 가질 법한 요소들의 모든 마진을 0으로 설정
- 모든 테두리(border)를 기본적으로 0픽셀 너비,
solid(실선), 그리고 정의된 테두리 색상으로 설정, 반면 버튼에 기본 테두리를 제공 - 이미지 및 이미지와 유사한 객체들을
display: inline(마치span태그처럼) 대신display: block(마치div태그처럼 별개의 단락으로 설정됨)으로 설정
Preflight 스타일만 사용한다면 단순한 스타일링 규칙만 적용되는 페이지가 될 것입니다. 하지만 그것이 핵심입니다. Preflight를 사용함으로써 화면 표시 속성에 대한 모든 변경 사항이 반드시 명시적으로 추가되도록 보장합니다.
@tailwind components 파일은 매우 작으며, container CSS 클래스의 정의로만 구성되어 있습니다. 이 클래스들은 보통 페이지 최상위 레벨에서 전체 페이지가 그려지는 박스를 정의하는 데 사용됩니다.
Tailwind라고 여겨지는 것의 대부분은 @tailwind utilities 파일에 있으며, 이 파일은 모든 유틸리티와 그 변형 수식어들을 정의합니다.
Duplicates
Tailwind와 디자인 목표를 달성하기 가장 많은 고민은 중복을 어떻게 관리하느냐는 것입니다. 즉, ’소개’에서 그랬던 것처럼 h1이 필요할 때마다 className="text-6xl font-bold text-blue-700"을 입력해야 한다면, 이는 h1이 필요할 때마다 일관되게 유지해야 하는 많은 타이핑 작업이 아닐까요? 만약 h1 디자인이 바뀐다면 어떻게 할까요?
Managing Duplicates in Code
Tailwind에는 CSS 클래스 목록의 중복을 관리하는 방법이 있지만, 동시에 이 중복 문제를 단지 CSS 문제로서가 아니라 코드 설정의 일부로 바라보도록 권장됩니다. HTML 마크업을 빌드하기 위해 어떤 도구를 사용하든, 코드 중복을 줄이기 위해 이미 사용하고 있는 나름의 방법론(컴포넌트, 순수 함수)이 있습니다. Tailwind를 사용할 때, CSS 클래스 목록을 해당 코드의 일부로 보는 것은 아주 좋은 생각입니다.
예를 들어, React는 CSS에서 중복을 관리하는 대신, 공통 Tailwind 클래스를 가진 React 컴포넌트를 만들 수 있습니다.
export const Header = ({children}) => {
return (
<div className="text-6xl font-bold text-blue-700">
{children}
</div>
)
}
export const SubHeader = ({children}) => {
return (
<div className="text-4xl font-semibold">
{children}
</div>
)
}
export const SubSubHeader = ({children}) => {
return (
<div className="text-lg font-medium italic">
{children}
</div>
)
}그런 다음 이렇게 사용할 것입니다.
순수 JavaScript에서는 Tailwind 클래스 목록을 반환하는 함수를 만들 수도 있습니다.
그리고 React에서는 이렇게 사용할 것입니다.
만약 이 방법이 마음에 들지 않고 CSS 기반의 중복 해결책을 원한다면, Tailwind는 @apply라는 CSS 지시문과 @layer라는 지시문을 제공합니다. 해당 주제에 관심이 가시면 Functions and directives을 참고하세요.
Modifier
유틸리티 클래스로 넘어가기 전에 이야기해야 할 Tailwind 기능이 하나 더 있습니다. 바로 수식어(modifier)입니다.
수식어는 Tailwind가 HTML 마크업에서 CSS 유사 클래스(pseudo-class), 유사 요소(pseudo-element), 그리고 미디어 쿼리(media query)를 사용하는 방식입니다. 예를 들어, 사용자가 객체 위로 마우스를 가져갔을 때(CSS 유사 클래스인 hover에 해당) 객체가 다르게 표시되기를 원하는 경우가 많습니다.
Tailwind에서는 다른 Tailwind 유틸리티에 수식어를 추가하여 CSS 유사 클래스 측면에서 유틸리티를 정의할 수 있습니다. 만약 앵커 태그(<a>)에 마우스가 올라갔을 때 밑줄이 생기게 하고 싶다면, 이렇게 할 수 있습니다.
이 방식은 간결하고, 상당히 직관적이며, HTML과 함께 정의되어 언제 적용되는지 명확합니다. hover:는 어떤 Tailwind 유틸리티와도 함께 사용할 수 있습니다. 심지어 hover:[mask-type:luminance]처럼 임의의 CSS 스타일과도 hover:를 사용할 수 있습니다. 수식어를 hover:dark:underline처럼 조합할 수도 있습니다.
Tailwind는 화면 너비에 따라 다른 유틸리티가 호출되도록 하는 데에도 수식어를 사용합니다. 그래서 className="sm:m-2 lg:m-4"라고 작성하면, 화면이 넓어짐에 따라 요소의 마진이 더 커지게 됩니다. Tailwind는 24개가 넘는 수식어를 정의하고 있습니다.
@apply와 함께 수식어를 사용할 수도 있습니다. 따라서 @apply hover:underline은 새로운 CSS 클래스를 정의하는 유효한 방법입니다.
CSS Units
CSS에서 길이나 너비를 정의하는 대부분의 값은 단위를 가진 숫자를 사용할 수 있습니다. 높이와 너비 정의는 퍼센티지(%)도 사용할 수 있습니다. CSS는 절대(absolute) 단위와 상대(relative) 단위, 두 가지 종류의 단위를 정의합니다.
Absolute
절대 단위는 실제 세계의 단위를 기준으로 정의되므로, 너비를 인치(inch) 단위인 5in 등으로 정의할 수 있습니다. 더 흔하게는 픽셀(pixel) 단위인 px를 보게 될 것입니다. 아주 오래전에는 px가 실제 디스플레이 픽셀 하나를 나타냈지만, 지금은 컴퓨터와 휴대폰 디스플레이의 밀도가 훨씬 높아져서 CSS 픽셀은 1인치의 1/96로 정의됩니다#sidenote[아시다시피, 1인치를 96분의 1로 나누는 것은 흔히 사용되는 방식입니다.]. 폰트의 경우 font-size: 20pt와 같이 포인트(point) 단위를 자주 보게 될 것입니다. 1포인트는 1인치의 1/72이며, 이는 컴퓨터보다 훨씬 이전에 사용되던 측정 단위입니다.
Relative
CSS에서는 상대 단위를 더 자주 보게 될 것입니다. 그중 가장 일반적인 것은 em이며, width: 10em에서처럼 해당 요소의 (글꼴) 크기를 기준으로 합니다. 폰트 크기를 상대적인 용어로 정의하는 것은 매우 흔하지만, font-size: 1.5em은 순환 정의가 될 수 있으므로, 타이포그래피 속성의 목적상 em은 부모의 font-size를 참조합니다. 하지만 이건 생각보다 혼란스럽습니다. em으로 정의된 모든 것에 폰트 크기 변경으로 알 수 없는 파급 효과를 미칠 수 있기 때문에 불안정하기도 합니다. 더 안정적인 대안은 rem이며, 이는 루트(root) 요소의 폰트 크기를 기준으로 합니다. Tailwind 리셋 시스템에서 rem은 기본적으로 16포인트입니다. Tailwind의 대부분 거리는 퍼센티지 또는 rem 단위로 정의됩니다.
2. Typography
웹 애플리케이션은 문자열의 예술입니다. 웹사이트 디자인의 많은 부분은 텍스트의 배치, 크기, 굵기(weight), 그리고 레이아웃에 관한 것입니다.
Size and Shape
텍스트 크기의 실질적인 기본값은 text-base 클래스입니다. 이 클래스는 CSS 속성 font-size: 1rem과 line-height: 1.5rem으로 정의되어 있습니다. 즉, text-base의 폰트 크기는 페이지의 루트(root) 요소 폰트 크기와 같으며, 줄 높이(line height)는 그 크기의 1.5배입니다(1.5rem/1).
Tailwind는 text-{size} 유틸리티 계열(family)을 제공하며, 여기에는 더 작은 두 단계, 더 큰 10단계, 그리고 기본 클래스가 포함되어 총 13가지 크기를 제공합니다. 문서에서 제시된 것처럼 각 단계는 폰트 크기와 줄 높이를 정의합니다.
#table( columns: (1fr, 1fr, 1fr), align: horizon, [클래스], [폰트 크기], [줄 높이], [text-xs], [0.75rem], [1rem], [text-sm], [0.875rem], [1.25rem], [text-base], [1rem], [1.5rem], [text-lg], [1.125rem], [1.75rem], [text-xl], [1.25rem], [1.75rem], [text-2xl], [1.5rem], [2rem], [text-3xl], [1.875rem], [2.25rem], [text-4xl], [2.25rem], [2.5rem], [text-5xl], [3rem], [1], [text-6xl], [3.75rem], [1], [text-7xl], [4.5rem], [1], [text-8xl], [6rem], [1], [text-9xl], [8rem], [1], )
이것은 잠재적으로 무한한 값의 집합에 대해 일관된 단계의 집합을 제공하려는 Tailwind의 명시적인 디자인 목표 중 하나입니다. text-{size} 유틸리티 계열을 통해 Tailwind는 사이트 전체의 크기 및 간격을 일관되게 유지하기 쉽게 만듭니다. text-[20px]에서처럼 대괄호([])를 사용하여 크기(size)로 임의의 값을 정의할 수 있으며, 숫자뿐만 아니라 단위도 포함해야 합니다.
기본적인 굵게(bold), 기울임꼴(italic), 밑줄(underline)과 같은 폰트 스타일링은 몇 가지 다른 CSS 속성으로 다뤄지지만, Tailwind의 관점에서 이러한 스타일은 그저 유틸리티 클래스일 뿐입니다. italic과 not-italic, 그리고 underline과 no-underline입니다. 텍스트가 서로 다른 상태(state)에서 다른 특성을 갖도록 하고 싶을 때만 not-italic이나 no-underline을 사용할 것입니다. 이는 보통 다양한 화면 크기에서의 반응형 동작과 관련이 있습니다. overline(윗줄)과 line-through(취소선)도 사용할 수 있습니다.
underline, overline, 또는 line-through가 지정된 경우, 추가 클래스를 더해 선(line)의 스타일을 지정할 수 있습니다. 옵션으로는 decoration-solid(실선), decoration-double(이중선), decoration-dotted(점선), decoration-dashed(파선), decoration-wavy(물결선)가 있으며, 이들 모두 이름이 의미하는 대로 작동합니다.
꾸밈선(decoration)의 너비를 지정하는 패턴 decoration-{width}가 있으며, 기본값은 0, 1, 2, 4, 8이고 이는 픽셀 단위의 너비에 해당합니다. 또한 decoration-auto와 decoration-from-font도 있으며, 임의의 측정값을 사용할 수도 있습니다. 유사한 패턴인 underline-offset-{width}는 선으로부터의 간격(offset)을 지정하며, 동일한 숫자 값 세트와 auto를 사용합니다. decoration-{color} 패턴으로 밑줄의 색상도 지정할 수 있습니다.
굵은 폰트의 경우, CSS는 100부터 900까지 9단계의 굵기를 제공합니다. 보통 텍스트는 400입니다. Tailwind 또한 각 단계를 위한 9개의 유틸리티 클래스를 제공합니다.
font-hairlinefont-thinfont-lightfont-normalfont-mediumfont-semiboldfont-boldfont-extraboldfont-black
모든 폰트가 모든 굵기(weight)에서 뚜렷한 글자 형태를 가지는 것은 아니지만, 일반적으로 사용되는 웹 폰트들은 그래야 합니다. 왜 Tailwind가 font-weight-100 같은 이름을 사용하지 않았는지는 모르겠습니다. 그렇게 하는 것이 다른 이름들과 더 일관성이 있었을 텐데요. 하지만 설정을 변경하여 그렇게 하도록 만들 수는 있습니다. font-[1200]처럼 임의의 값을 넣을 수도 있습니다.
텍스트의 대소문자(case)를 통일하고 싶을 수도 있습니다. 예를 들어, 헤더(header)가 모두 대문자이기를 원할 수 있습니다. Tailwind는 대소문자 변환을 위해 4개의 유틸리티 클래스를 제공하며, 이들 모두 CSS의 text-transform 속성을 감싸 유틸리티 이름이 설명하는 동작을 제공합니다.
uppercaselowercasecapitalizenormal-case
이것들을 가지고, 실제 헤더에 대한 스타일을 만들어 볼 수 있습니다. 다음은 유명 CSS 프레임워크의 제목(title) 및 부제목(subtitle) 기본 스타일과 거의 유사합니다.
이렇게 하면 1.875rem(30포인트) 크기에 2.5rem(36포인트)의 줄 높이를 가진 ‘semibold’ 굵기의 제목과, 1.25rem(20포인트) 크기에 보통(normal) 굵기 및 1.75rem의 줄 높이를 가진 부제목이 만들어집니다. 저는 종종 헤더가 좀 더 눈길을 끌기를 원하기 때문에, 다음과 같이 할 수도 있습니다.
이렇게 하면 약간 더 굵고 큰 제목과 부제목, 그리고 일반 텍스트보다 조금 더 크고, 조금 더 굵으며, 기울임꼴(italic)이 적용된 3차 레벨 헤더가 만들어집니다. 헤더 주변에 약간의 간격을 추가할 수도 있습니다.
Tailwind의 리셋 스타일은 h1, h2 등이 기본 스타일을 갖지 않도록 만든다는 점을 기억하십시오. 따라서 Tailwind에서 이 태그들을 사용하는 것은 해당 텍스트가 어떤 종류의 헤더임을 나타내는 시맨틱(semantic)한 표기일 뿐입니다. 스타일에는 아무런 영향을 주지 않습니다.
지금쯤 여러분은 헤더를 원할 때마다 text-lg font-medium italic을 입력해야 하는 것이 좋은 생각이라고 제가 진지하게 말하는 것인지 묻고 싶을 것입니다. 타이핑 양이 많고, 암호 같기도 하며, 무엇보다 타이핑 양이 많습니다. Tailwind에서 중복을 관리하는 방법에 대한 아이디어는 12페이지의 ’중복’을 참조하십시오.
Colors and Opacity
먼저 색상에 대해 이야기해 봅시다. Tailwind는 기본적으로 수백 가지의 색상 유틸리티를 제공하며, 이 유틸리티들은 색상과 관련된 다양한 클래스 계열에서 유사하게 동작합니다. 텍스트 색상은 text-{color} 패턴을 따릅니다.
세 가지 특별한 색상 text-transparent, text-inherit, text-current 이 있습니다. text-transparent 클래스는 텍스트를 투명하게 만들어, 텍스트 뒤의 배경색을 볼 수 있게 합니다. 이 클래스는 때때로 효과를 주기 위해 사용될 수 있으며, 특히 배경이 텍스트 모양에 맞춰지도록 하는 bg-clip-text와 함께 사용됩니다. text-current와 text-inherit 옵션은 모두 유용한 리셋(reset) 기능입니다. text-inherit는 부모로부터 상속받은 색상을 사용합니다. text-current 클래스는 CSS의 currentColor를 사용하는데, 이는 보통 다른 색상 속성을 텍스트와 동일한 색상으로 설정하기 위해 사용됩니다. 텍스트 자체에 대해서는 text-inherit와 동일하게 동작할 것입니다.
Tailwind는 또한 색상을 #000000으로 설정하는 text-black과 #ffffff로 설정하는 text-white도 정의합니다.
하지만 대부분의 경우 Tailwind는 text-{color}-{level} 형태의 조합된 클래스를 사용합니다. Tailwind는 기본적으로 22가지의 서로 다른 색상을 10가지 레벨로 설정합니다. 가장 밝은 50부터 시작하여 100에서 900까지 100의 배수마다 가장 어두운 900까지 있습니다. 유사성(similarity)을 기준으로 그룹화한 기본 색상들도 제공합니다.
.text-yellow-400이나 .text-blue-200처럼 색상과 레벨의 어떤 조합이든 사용할 수 있습니다. 모든 80가지 조합의 정확한 RGB 16진수(hex) 값을 여기에 싣지는 않겠지만, Tailwind 공식 문서에서 온라인으로 확인할 수 있습니다. Tailwind 문서는 이 레벨들을 “전문적으로 제작된(expertly-crafted)”이라고 설명하는데, 이는 자동 계산되지 않았음을 의미하는 것으로 받아들이면 됩니다.
사용자 정의 색상은 설정 파일에서 정의할 수 있으며, text-[#34da33]처럼 일회성으로 사용할 수도 있습니다.
앞으로 보게 되겠지만, Tailwind 전체에서 동일한 색상과 레벨을 사용하는 많은 접두사(prefix)가 있습니다. 기본 색상은 숫자가 커질수록 어두워진다고 생각할 수 있으며, 이를 활용하여 몇 가지 미묘한 효과를 줄 수 있습니다.
이렇게 하면 옅은 회색 텍스트가 표시되고, 사용자가 그 위로 마우스를 가져가면(hover) 더 어두워집니다. 클래스 문자열을 반환하는 함수로 만들 수도 있습니다.
이제 불투명도(opacity)에 대해 이야기해 봅시다. 불투명도를 변경하면 색상이 더 보이거나 덜 보이게 됩니다. Tailwind에서는 text-gray-300/50 패턴을 사용하여 색상 선언의 확장으로 불투명도를 지정할 수 있습니다. 즉, 불투명도를 지정하려면 색상 뒤에 슬래시(/)와 불투명도 레벨을 추가합니다. 기본 불투명도 레벨 목록은 조금 이상합니다. 0에서 100 사이의 10의 배수 전체와, 5, 25, 75, 95가 포함됩니다. 이 숫자는 백분율을 나타냅니다. 예를 들어 20%는 text-gray-300/20, 95%는 text-gray-300/95입니다. text-gray-300/[42]처럼 임의의 값에 대괄호를 사용할 수 있습니다.
caret-fuschia-300 또는 caret-current처럼, caret-{color} 패턴을 사용하여 텍스트 포인터(커서)의 색상을 지정하는 데에도 모든 동일한 색상 패턴을 사용할 수 있습니다. 여기에는 caret-[#ababab]과 같은 임의의 색상도 포함됩니다.
Alignment and Spacing
텍스트의 수평 정렬을 지정하는 데 사용되는 몇 가지 Tailwind 클래스가 있습니다. CSS text-align 속성을 변경합니다. 정렬의 정확한 범위는 텍스트가 들어 있는 박스(box)에 따라 다릅니다.
text-lefttext-centertext-righttext-justify
수직 정렬을 위한 CSS 속성은 vertical-align이며, 관련 Tailwind 클래스들은 다음과 같습니다.
align-baselinealign-topalign-middlealign-bottomalign-text-topalign-text-bottomalign-subalign-super
수평 정렬과 마찬가지로, 정확한 위치는 텍스트 박스에 따라 달라집니다.
줄 간격(line spacing)을 위해 Tailwind는 상대적 옵션과 절대적 옵션을 모두 가지고 있습니다. 상대적 옵션은 leading-none으로 시작하며, 이는 줄 높이를 폰트 크기와 정확히 같게 만듭니다(Leading은 줄 높이를 의미하는 인쇄 용어). 일반적으로 이것은 약간 빽빽하게 느껴질 것이며, Tailwind는 가장 촘촘한 것부터 가장 넓은 것 순서로 다음 클래스들을 통해 줄 높이를 조절할 수 있습니다.
leading-tightleading-snugleading-normalleading-relaxedleading-loose
절대적 옵션은 rem에 기반하며, 이는 DOM 요소의 크기가 아닌 루트 요소 크기에서 파생됨을 의미합니다. leading-3부터 leading-10까지 있으며, 이는 0.75rem에서 2.5rem까지 0.25 단위로 증가합니다. leading-[4.3rem]처럼 임의의 옵션을 사용할 수도 있습니다.
다음은 CSS에서는 letter-spacing이라고 부르고 Tailwind에서는 tracking이라고 부르는 속성입니다. tracking-normal이 있고, 텍스트를 더 촘촘하게 만드는 두 가지 유틸리티가 있습니다.
tracking-tighttracking-tighter
또한, 글자 간격을 더 넓게 만드는 세 가지 유틸리티가 있습니다.
tracking-widetracking-widertracking-widest
이 유틸리티들은 큰 텍스트가 있는 헤더에 멋진 효과를 더할 수 있습니다.
Special Text
Tailwind는 다르게 처리하고 싶을 수 있는 몇 가지 텍스트 유형에 대해 CSS 유사 클래스(pseudo-class)와 일치하는 수식어(modifier)를 사용할 수 있게 합니다.
selection 수식어는 사용자가 선택한 텍스트에 적용되므로, 색상(selection:bg-red-400)이나 다른 스타일(selection:font-bold)을 적용할 수 있습니다. selection 수식어가 부모 요소에 적용되면, 모든 자식 요소에도 전달됩니다.
신문이나 잡지 스타일 효과에 관심이 있다면, Tailwind는 first-line(첫 번째 줄) 및 first-letter(첫 번째 글자) 수식어를 모두 제공합니다. 이는 first-letter:text-9xl first-letter:font-bold first-line:text-2xl 등과 같이 크기 및 굵기에 가장 적합해 보입니다.
또한, Tailwind는 CSS의 before:: 및 after:: 유사 클래스에 대한 수식어로 before:와 after:를 허용하여, DOM에 나타나지 않는 콘텐츠를 삽입할 수 있게 합니다. 하지만 대부분의 경우, CSS before 및 after 유틸리티를 사용하는 것보다 실제 HTML span 태그를 사용하여 콘텐츠를 올바른 위치에 배치하는 것이 더 쉽고 효과적입니다.
Lists
Tailwind는 <li> 태그를 관리하기 위한 두 가지 클래스 세트를 포함합니다. 첫 번째는 목록의 스타일입니다. list-disc(글머리 기호), list-decimal(숫자), 그리고 list-none(없음)이 있습니다. list-inside와 list-outside로 글머리 기호나 숫자가 텍스트 박스 안에 있을지 밖에 있을지 선택할 수도 있습니다.
marker:라는 특별한 수식어를 사용하면 목록의 글머리 기호나 숫자에 스타일을 적용할 수 있습니다. 주로 색상(marker:text-blue-300)이나 크기(marker:text-2xl)에 사용할 것입니다. marker: 수식어의 좋은 점은 상속될 수 있다는 것입니다. ul이나 ol 태그에 적용하면 포함된 li 태그들에 자동으로 적용됩니다.
Typography Plugin
페이지의 긴 텍스트에 대한 가독성 좋은 기본값을 원한다면, Tailwind는 공식 타이포그래피 플러그인(typography plugin)을 제공합니다.
플러그인을 설치하려면, 먼저 패키지를 추가합니다.
그런 다음 Tailwind 설정 파일에 추가합니다. 설정은 아래와 같이 할 수 있습니다. 더 자세한 사항은 Get started with Tailwind CSS을 참고하세요.
Forms Plugin
Tailwind는 @tailwindcss/forms 플러그인을 사용하여 폼(form)을 위한 유용한 기본값 시리즈를 제공합니다. 앞서 설명한 타이포그래피 플러그인과 마찬가지로, 플러그인을 설치하려면 먼저 패키지를 추가합니다.
이것은 기본 폼 요소에 적절한 스타일을 제공할 것입니다. Tailwind 폼은 그 자체로 완성된 작업을 의도한 것이 아니라, 사용자 정의 페이지에 스타일을 추가할 때 시작하기 좋은 더 나은 리셋(reset) 역할을 하도록 설계되었습니다. 더 자세한 사항은 Tailwind Forms을 참고하세요.
3. Boxes
DOM의 각 HTML 요소는 화면에서 사각형의 공간을 차지합니다. 모든 브라우저의 개발자 도구에는 그 사각형을 표현하는 기능이 포함되어 있습니다.
별다른 사용자 정의를 하지 않으면, 박스의 크기는 요소의 콘텐츠에 의해 결정됩니다. Tailwind는 박스의 모든 측면을 제어할 수 있게 해줍니다. 아마도 DOM 요소의 가장 중요한 특징은 사용자가 그것을 볼 수 있는지 여부일 것입니다. 약간의 JavaScript로 이 기능을 조작함으로써, 저렴한 비용으로 상호작용을 추가할 수 있습니다.
일반적인 패턴은 초기 페이지 로드 시 잠재적인 DOM 요소를 많이 로드하되, 그중 다수는 처음에는 숨겨진(hidden) 상태로 시작하게 하고, 가시성을 조작하여 더 많은 데이터를 위해 서버를 호출할 필요 없이 페이지를 변경하는 것입니다.
사용자가 볼 수 없는 DOM 요소를 만들고 싶을 때, 대부분의 경우 CSS 속성인 display: none을 감싸는 Tailwind의 hidden 유틸리티를 사용하게 될 것입니다. Tailwind에서 hidden의 반대는 보통 block입니다. display에 사용할 수 있는 다른 많은 잠재적 값들이 있지만, Tailwind의 Preflight는 많은 요소가 block 값을 사용하도록 만듭니다. 다른 일반적인 값은 inline이지만, Tailwind에서는 flexbox나 grid 레이아웃을 사용하여 inline 동작을 구성할 가능성이 더 큽니다.
Tailwind에는 visible과 invisible 유틸리티도 있습니다. invisible과 hidden의 차이점은, hidden 요소는 표시되지 않으며 DOM 레이아웃의 일부도 아니므로 그 존재가 다른 요소의 레이아웃에 영향을 미치지 않는다는 것입니다. 반면에 invisible 요소는 그 내용을 표시하지는 않지만, 페이지의 나머지 레이아웃에는 영향을 줍니다. 즉, 크기는 여전히 유지되지만 비어 있는, 페이지 상의 간격(gap)으로 나타납니다.
CSS 박스 모델은 네 부분으로 구성됩니다. 안쪽에서 바깥쪽으로 다음과 같습니다.
- 콘텐츠(Content): 콘텐츠는 요소 내부의 텍스트나 미디어
- 패딩(Padding): 패딩은 콘텐츠 주변, 하지만 테두리(border) 안쪽의 공간으로, 패딩은 네 방향 각각에 대해 개별적으로 지정하거나, 수평으로만, 수직으로만, 또는 모든 방향에 한 번에 지정할 수 있음
- 테두리(Border): 테두리는 패딩 주변의 가장자리, 테두리가 패딩과 구별되는 유일한 점은 패딩과 콘텐츠 주위에 테두리를 그릴 때 색상과 패턴을 사용할 수 있다는 것
- 마진(Margin): 마진은 테두리 바깥쪽, 그리고 이 요소와 다른 모든 요소 사이의 공간, 패딩을 지정하는 것과 같은 방식으로 모든 방향의 마진을 지정할 수 있음
또한 박스의 높이(height)와 너비(width)를 절대적인 크기나 사용 가능한 너비와 높이에 대한 백분율로 지정할 수 있습니다. 너비나 높이를 명시적으로 지정하면, 사용되지 않은 공간은 콘텐츠의 일부로 간주됩니다. 요소의 크기를 제한하는 경우, 그 크기를 초과하는(overflow) 콘텐츠를 페이지가 어떻게 처리할지 지정할 수도 있습니다. 마지막으로, 요소의 배경(background)으로도 꽤 많은 것을 할 수 있습니다.
Padding and Margins
패딩과 마진은 서로 옆에 있지 않으며, 항상 테두리(border)에 의해 분리됩니다. Tailwind는 패딩을 관리하기 위해 약 240개의 서로 다른 클래스(임의 값(arbitrary values) 제외)를 제공합니다. 우리가 이 모든 값을 알아야 할 필요는 없지만, 알고 싶다면 문서를 참고하세요.
우리는 p{direction}-{size}라는 패턴을 활용합니다. 모든 패딩 클래스는 p로 시작하며, 뒤에 방향을 나타내는 선택적 문자가 따릅니다. 여섯 가지 방향이 존재합니다. 각각 top, bottom, left, right를 의미하는 t, b, l, r와 수평(horizontal, left와 right를 의미)을 의미하는 x 그리고 수직(vertical, top과 bottom을 의미)을 의미하는 y가 있습니다. 방향 문자가 없으면 패딩이 모든 방향으로 적용됩니다.
기본적으로 Tailwind는 패딩과 마진에 사용할 수 있는 34개의 숫자 크기를 정의합니다. 특별한 크기인 1은 1px과 같습니다. 이 크기는 0.25rem과 같습니다.
0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 96
예를 들어, p-10은 모든 방향으로 2.5 rem의 패딩, px-4는 수평으로 1 rem의 패딩, pr-1.5는 오른쪽에 0.375 rem의 패딩, 그리고 pt-px는 위쪽에 1픽셀의 패딩을 의미합니다. 여기서의 목표는 작은 크기에서는 더 세밀한 제어를 제공하고, 더 큰 패딩 양에 대해서는 일관된 값 집합을 제공하는 것입니다. className="px-10 py-20"와 같이 여러 방향에 대해 다수의 패딩 클래스를 가질 수 있습니다.
크기 지정 패턴 (Sizing Pattern)은 앞에서도 소개한 내용입니다. 하지만 중요하니까, 다시 한번 더 상기시켜드리고 싶습니다. 이 크기 지정 패턴은 여러 다른 속성에서 사용되는 또 다른 Tailwind 패턴입니다. 여기서는 p-24와 같이 패딩에 사용되는 것을 보지만, 마진(m-24), 높이(h-24), 너비(w-24)에도 사용됩니다. 모든 경우에 p-[15px]처럼 대괄호를 사용하여 임의의 크기와 단위를 지정할 수 있습니다.
- 모든 방향에는
-auto라는 추가 크기 옵션이 있습니다.auto는 부모 컨테이너 내에서 요소를 수평으로 가운데 정렬하는 마진 옵션입니다. 위쪽과 아래쪽에auto를 지정할 수는 있지만, 아무런 효과가 없습니다. 마진은 음수(negative)가 될 수 있으며, 이는 요소를 다음 요소에서 더 멀리 떨어뜨리는 대신 더 가깝게 이동시켜, 옆 요소의 마진 안쪽에 배치합니다. 음수 마진은m대신-m으로 시작하며, 일반 마진과 동일한 방향 및 크기 옵션을 갖습니다.
Borders
테두리는 마진 및 패딩과 유사하지만, 자체적인 색상과 스타일을 가질 수 있기 때문에 더 복잡합니다. 테두리의 크기 옵션은 마진만큼 커지는 것을 일반적으로 원하지 않기 때문에 더 제한적입니다. 더 중요한 것은, 테두리의 크기 옵션은 rem이 아닌 픽셀(pixels) 단위로 측정된다는 것입니다.
가장 기본적인 테두리 옵션은 단순히 border이며, 이는 네 방향 모두에 1픽셀의 테두리를 줍니다. 그 다음으로는 border-{side}-{size}가 있으며, 여기서 side(방향)는 선택 사항입니다. 하지만 패딩이나 마진과는 달리, 방향 앞에 대시(-)가 포함됩니다. 방향 옵션으로는 -b, -t, -l, -r이 있으며, 두 방향을 조합하는 -x와 -y도 있습니다. 방향을 포함하지 않으면 크기가 네 면 모두에 적용됩니다.
크기 또한 선택 사항입니다. -0, -2, -4, -8이 있으며, 이는 테두리의 너비를 픽셀 단위로 나타냅니다. 크기를 지정하지 않으면 1을 의미합니다. 임의 값은 대괄호를 사용하여 지정할 수 있습니다. 방향이나 크기 둘 중 하나가 포함되지 않으면, 접두사 대시가 필요 없습니다. 예를 들어, 유효한 테두리 너비 클래스로는: 방향을 지정하지 않고 모든 면에 2픽셀 테두리를 주는 border-2, 크기를 지정하지 않고 아래쪽에 1픽셀 테두리를 주는 border-b, 그리고 오른쪽에 4픽셀 테두리를 주는 border-r-4가 있습니다.
테두리 선은 스타일을 가질 수 있으며, 이를 위해 별도의 Tailwind 유틸리티 클래스를 사용합니다. 기본값은 실선(solid) 테두리이며, border-solid로 표시합니다. Tailwind는 또한 border-dashed(파선), border-dotted(점선), border-double(이중선), border-none(없음)을 위한 유틸리티도 제공합니다.
테두리 선은 색상과 불투명도(opacity)도 가질 수 있습니다. 테두리 색상과 불투명도 옵션은 border 접두사가 붙는다는 점만 제외하면 텍스트 색상 옵션과 정확히 동일합니다. 예를 들어, border-gray-500처럼 border-{color}로 색상을 지정하고, border-gray-500/50과 같이 불투명도를 추가할 수 있습니다. 색상과 불투명도 수준은 텍스트의 경우와 동일합니다. border-r-gray-500 또는 border-x-gray-500처럼 동일한 방향 수정자를 추가하여 특정 면의 테두리 색상을 지정할 수 있습니다.
마지막으로, 테두리는 둥글게 만들 수 있습니다. Tailwind는 9가지 기본 rounded 옵션을 제공하며, 각 옵션은 rem 단위로 둥글기(radius) 크기를 지정합니다.
하나 또는 두 개의 모서리만 둥글게 하고 싶을 수도 있습니다. 이에 대해 당장 생각나는 유일한 경우는 여러 요소를 함께 그룹화하여 더 큰 둥근 사각형을 만들 때입니다. 원한다면 rounded와 크기 사이에 방향을 삽입할 수 있습니다. b, t, l, r 방향으로 한쪽 면의 모서리 두 개를 모두 지정할 수 있습니다. 또한 tl, tr, bl, br로 단일 모서리를 지정할 수도 있습니다. 유효한 옵션으로는 rounded-tr-md 또는 rounded-b-full 등이 있습니다.
다음은 마진과 테두리 옵션의 몇 가지 간단한 예입니다.
<div className="bg-gray-50 p-10 text-black">
<div className="mb-10">
<button className="p-10 border border-black">One</button>
<button className="m-10 border border-black">Two</button>
<button className="m-2 p-2 border-4 border-black">Three</button>
</div>
<div>
<button className="m-4 p-4 border-2 border-black rounded-md">
Four
</button>
<button className="m-4 p-4 border-2 border-black rounded-2xl">
Five
</button>
<button className="m-4 p-4 border-2 border-black rounded-full">
Six
</button>
</div>
</div>Tailwind에는 ’링(ring)’이라고 불리는 테두리를 지정하는 다른 방법이 있습니다. 링은 테두리에 비해 장점이 있습니다. 우선, 링은 둥근 요소에서 실제로 보기 좋고 잘 작동합니다. 또한, 링은 CSS의 box shadow 속성을 사용하여 구현되므로 레이아웃 간격에 영향을 주지 않습니다.
링은 너비, 색상, 불투명도, 그리고 선택적인 오프셋(offset)을 가질 수 있습니다. 색상이 지정되지 않으면, 기본 색상은 완전히 불투명하지 않은 파란색이 되며, 이는 버튼이 포커스(focus)를 받은 것처럼 보이게 합니다. 패턴은 ring-{width}이며, 여기서 너비는 (테두리처럼) 링의 픽셀 너비에 해당하는 0, 1, 2, 4, 8입니다. 또한, 3픽셀인 ring과, 링을 박스의 테두리 부분이 아닌 콘텐츠 부분에 그리는 ring-inset도 있습니다. 그리고 임의의 크기와 단위로 ring-[{arbitrary}]를 사용할 수 있습니다.
패턴 ring-{color}는 정의된 모든 색상과 함께 작동하여 링의 색상을 변경하며, ring-{color}/{opacity}처럼 슬래시를 추가하면 불투명도를 변경합니다. 이 또한 텍스트 불투명도와 동일한 수준을 사용합니다. ring-offset-{pixels}는 링을 약간 오프셋(이동)시키며, ring-offset-{color}는 오프셋된 링에 색상을 부여합니다.
Background Color
Tailwind의 배경색은 텍스트 색상 및 테두리 색상과 유사합니다. 패턴은 bg-{color}이며, 다른 그룹과 동일한 색상 이름을 사용합니다 (bg-red-700 또는 bg-orange-300).
Tailwind는 또한 텍스트 불투명도와 동일한 단계를 사용하는 bg-{color}/{opacity}도 제공합니다. 다른 곳에서와 마찬가지로, 색상(bg-[#cdcdcd])이나 불투명도(bg-red-700/[43])에 대해 대괄호를 통해 임의 값을 사용할 수 있습니다.
기술적으로 box shadow(박스 그림자)는 배경색이 아니지만, 배경색처럼 사용되기도 합니다. Tailwind는 box shadow를 관리하기 위한 몇 가지 유틸리티를 제공합니다. 기본 유틸리티인 shadow는 1픽셀 수직 오프셋과 3픽셀 너비를 가진 10% 불투명도의 검은색 테두리를 효과적으로 생성합니다. 그런 다음 xs 및 sm 수정자로 더 작게 만들거나 md, lg, xl, 2xl 수정자(shadow-sm, shadow-xl 등)로 더 크게 만들 수 있습니다. 여기서 임의 값은 다른 Tailwind 패턴보다 더 복잡하다는 점에 유의하세요. 그림자의 색상은 shadow-{color}로 지정할 수 있습니다.
별도로, shadow-inner 클래스를 사용하여 작은 내부 그림자(inset shadow)를 만들 수 있으며, 이는 요소가 나머지 화면보다 더 낮게 보이게 만듭니다. (안타깝게도 크기 변형은 없습니다.) 그리고 shadow-none으로 이 모든 효과를 취소할 수 있습니다. 다음 예에서 볼 수 있듯이, 크기를 키우지 않으면 꽤 미묘한 효과입니다.
<div className="bg-gray-50 p-10">
<div className="mb-10">
<button className="p-10 mx-10 shadow-sm bg-white">One</button>
<button className="p-10 mx-10 shadow-sm bg-white">Two</button>
<button className="p-10 mx-10 shadow-lg bg-white">Three</button>
</div>
<div>
<button className="p-10 mx-10 shadow-xl bg-white">Four</button>
<button className="p-10 mx-10 shadow-2xl bg-white">Five</button>
<button className="p-10 mx-10 shadow-inner bg-white">Six</button>
</div>
</div>Tailwind는 drop shadow 필터도 지원합니다. box shadow와 drop shadow의 차이는 미묘합니다. 우리의 목적에서 가장 큰 차이점은 drop shadow가 직사각형이 아닌 요소(예: 투명한 배경을 가진 이미지)에 더 잘 작동한다는 것입니다. drop-shadow로 drop shadow를 얻을 수 있으며, 일반 shadow에서 사용되는 것과 동일한 크기 수정자를 사용할 수 있습니다.
Tailwind는 또한 배경을 그라데이션으로 설정할 수 있게 해주며, 이를 위해서는 동일한 요소에 여러 클래스를 지정해야 합니다. 이것은 우리가 무언가를 올바르게 작동시키기 위해 여러 Tailwind 클래스가 필요한 경우를 본 첫 번째 사례라고 생각되며, 다음 장에서 페이지 레이아웃 옵션을 살펴보면서 더 자주 보게 될 패턴입니다.
순수 CSS에서는 background-image: 속성에 linear-gradient 함수 값을 할당하여 그라데이션을 지정합니다. 방향, “from” 색상(그라데이션의 시작점), “to” 색상(끝나는 점)을 지정합니다. 선택적으로 중간 지점인 “via” 색상을 지정할 수 있습니다.
Tailwind는 bg-gradient-to-{direction} 패턴의 유틸리티와 네 방향 t, b, r, l을 제공합니다. 따라서 bg-gradient-to-t는 그라데이션 “from” 색상이 아래쪽에서 시작하여 위쪽에 있는 “to” 색상으로 음영 처리됨을 의미하고, bg-gradient-to-r는 “from” 색상이 왼쪽에, “to” 색상이 오른쪽에 있음을 의미합니다.
또한 tl, tr, bl, br 네 개의 모서리 방향도 제공되며, 이는 대각선 그라데이션을 제공하기 위해 결합됩니다. 따라서 bg-gradient-to-tr은 왼쪽 하단에서 오른쪽 상단으로 향하는 대각선 그라데이션입니다. bg-none은 그라데이션을 제거합니다.
방향이 설정되었으면, 이제 색상을 추가할 수 있습니다. 우리는 이미 보았던 동일한 색상 이름을 사용하지만, from-, to-, via- 접두사를 붙여 사용합니다. 빨간색에서 파란색으로, 그리고 오른쪽에서 왼쪽으로 가게 하려면 세 개의 클래스가 필요합니다.
예를 들어, 왼쪽 방향 그라데이션에서 빨간색에서 시작해 중간에 노란색을 거쳐 파란색으로 끝나는 그라데이션을 만들 수 있습니다. 아래와 같이 적용할 수 있습니다.
다음은 회색조(grayscale) 예제입니다.
<div>
<div className="mb-10 bg-gradient-to-r from-gray-50 to-black p-10 w-1/2">
<button className="p-10 mx-10 bg-white">One</button>
<button className="p-10 mx-10 bg-white">Two</button>
</div>
<div
className="mb-10 p-10 w-1/2
bg-gradient-to-r from-gray-50 via-black to-gray-50">
<button className="p-10 mx-10 bg-white">Three</button>
<button className="p-10 mx-10 bg-white">Four</button>
</div>
</div>Background Images
CSS는 배경 이미지를 표시하기 위한 많은 속성을 가지고 있으며, Tailwind는 거의 모든 속성에 대한 유틸리티를 제공합니다.
URL에서 가져오는 배경 이미지를 원할 경우, Tailwind는 해당 이미지가 표시되는 방식에 대한 유틸리티는 제공하지만, URL 자체에 대한 유틸리티는 제공하지 않습니다. 배경 이미지 URL을 지정하는 데는 세 가지 옵션이 있습니다.
DOM 요소의 style= 속성을 사용하는 방법(<div style="background-image: url(whatever)"></div>, 또는 임의 구문(arbitrary syntax)을 사용하여 대괄호로 묶는 방법, 예: className="[background-image:url({url})]"이 있습니다. 마지막으로, 자신만의 CSS 유틸리티 클래스를 만들 수 있습니다.
배경 이미지가 있을 때, 그 배경 이미지가 박스 안에서 어떻게 위치할지 지정할 수 있습니다. 이는 CSS에게 이미지의 어느 쪽이 박스의 어느 쪽에 닿아야 하는지 알려줍니다. 더 자세한 내용은 배경 위치에 관한 사항을 참조하세요.
bg-centerbg-leftbg-rightbg-topbg-bottombg-left-topbg-left-bottombg-right-bottombg-right-top
이미지가 박스보다 작은 경우, 이미지를 타일처럼 반복해서 채울 수 있는 옵션이 있습니다. bg-repeat는 이미지를 수평 및 수직으로 타일링합니다. 한 방향으로만 하려면 bg-repeat-x 또는 bg-repeat-y를 사용합니다. bg-no-repeat 유틸리티는 모든 반복을 리셋합니다.
두 가지 특별한 옵션인 bg-repeat-round와 bg-repeat-space는 타일링이 이미지를 배치하는 방식을 변경합니다. 기본 repeat는 박스 끝에 부분적인 이미지를 배치할 것입니다. bg-repeat-space를 선택하면, 부분적인 이미지가 없으며 모든 공백이 타일링된 이미지 사이에 고르게 분배됩니다. bg-repeat-round를 선택하면, 각 이미지가 공백을 덮도록 늘어나기 때문에 공백이 생기지 않습니다.
일반적인 효과 중 하나는 페이지가 스크롤될 때 배경을 제자리에 고정시켜, 사용자가 스크롤함에 따라 뷰포트가 이미지의 다른 부분을 보여주게 하는 것입니다. Tailwind는 bg-fixed로 이를 수행할 수 있게 해줍니다. 그 반대는 뷰포트 자체에 스크롤 막대를 원하는지 여부에 따라 bg-local 또는 bg-scroll입니다.
이미지를 포함할 박스의 부분을 지정할 수 있습니다. 기본값은 bg-clip-padding이며, 이 경우 배경 이미지는 박스의 콘텐츠와 패딩 부분에는 표시되지만 테두리에는 표시되지 않습니다. bg-clip-border를 사용하여 이미지가 테두리까지 덮도록 만들거나, bg-clip-content를 사용하여 이미지를 패딩이 아닌 콘텐츠에만 제한할 수도 있습니다.
더 흥미로운 것은 bg-clip-text인데, 이는 콘텐츠 텍스트의 모양 안쪽에만 배경 이미지를 표시합니다. 텍스트 색상이 이를 가리지 않도록 text-transparent와 함께 사용하는 것이 좋으며, 이렇게 하면 배경색이나 이미지를 텍스트 안에서만 볼 수 있습니다. 이를 그라데이션과 결합하면 다음 예제와 같이 텍스트 그라데이션을 얻을 수 있습니다.
Filters
CSS는 요소의 디스플레이에 영향을 미치는 많은 필터를 정의합니다. Tailwind는 이를 사용할 수 있게 해주며, 다음은 가장 유용한 것들의 집합입니다.
요소를 흐리게(blur) 하려면 blur를, 배경을 흐리게 하려면 bg-blur를 사용할 수 있습니다. 기술적으로 이는 8픽셀의 블러입니다. Tailwind는 더 작은 블러인 blur-sm과 더 큰 블러인 blur-md, blur-xl, blur-2xl, blur-3xl을 제공합니다 (이들 중 어느 것에나 bg-를 추가하면 배경에만 작동합니다).
grayscale로 요소를 회색조로 만들고 grayscale-0로 이를 무효화할 수 있습니다. 비슷하게 sepia로 요소를 세피아 톤으로 만들고 sepia-0로 무효화할 수 있습니다.
brightness-{level}로 요소의 밝기를 조절할 수 있으며, 여기서 레벨은 0, 50, 75, 90, 95, 100, 105, 110, 125, 150, 또는 200이 될 수 있고, brightness-100은 100%, 즉 중간입니다. 유사하게 contrast-{level}로 대비를 조절할 수 있지만, 표준 값은 0, 50, 75, 100, 125, 150, 200뿐입니다. 마지막으로, saturate-{level}로 채도를 조절할 수 있으며, 기본값은 0, 50, 100, 150, 200으로 훨씬 적습니다. 이 세 가지 유틸리티 모두에 대해 대괄호를 사용하여 임의 값을 사용할 수 있습니다.
Height and Width
요소의 높이와 너비는 CSS에서 관리하기 어렵기로 악명 높습니다. Tailwind는 크기 조절을 위한 몇 가지 유틸리티를 제공하지만, 크기 조절은 종종 부모 요소와 콘텐츠 양쪽 모두에 기반한 사용 가능한 크기에 의존한다는 점을 기억하세요.
Tailwind는 너비와 높이 유틸리티 클래스를 위해 w-{size}와 h-{size} 패턴을 사용합니다. 양방향 모두에 대해, Tailwind는 우리가 패딩과 마진에서 보았던 것과 동일한 크기 조절 스케일(scale)과 동일한 숫자 집합에 기반한 고정 크기 옵션 세트를 제공합니다.
특별한 옵션은 다음과 같습니다.
-auto: 자동 크기 조절-px: 단일 픽셀-full: 부모 컨테이너의 100%-screen: 뷰포트의 100%-min: 최소 콘텐츠 크기 (CSSmin-content)-max: 최대 콘텐츠 크기 (CSSmax-content)-fit: 맞춤 콘텐츠 크기 (CSSfit-content)
이것들을 h-0, w-8, 또는 h-px와 같은 클래스에서 사용할 수 있습니다. -min 콘텐츠는 콘텐츠가 들어갈 수 있는 가장 작은 크기로 박스의 크기를 조절합니다. -max 콘텐츠는 가장 넓은 크기로 이동합니다. 그리고 -fit 콘텐츠는 min-content와 max-content 사이에 맞는 가장 넓은 크기입니다.
일련의 상대적인 너비 옵션도 사용할 수 있습니다. Tailwind는 50%를 위한 \(w-1/2\)와 같은 일련의 분수 옵션을 제공합니다. 절반(halves), \(1/3\)(thirds), \(1/4\)(quarters), \(1/5\)(fifths), \(1/6\)(sixths), \(1/12\)(twelfths) (12분의 1은 높이가 아닌 너비에만 존재)에 대한 분수를 사용할 수 있습니다.
이 모든 것은 실제 Tailwind 유틸리티 클래스입니다. w-3/4, h-2/3, w-7/12 이러한 너비를 사용하여 그리드 레이아웃을 흉내 낼 수 있지만, 그리드 레이아웃을 사용하는 것이 더 쉽습니다.
CSS는 또한 최소 및 최대 높이와 너비를 지정할 수 있게 해주며, Tailwind는 이에 대한 제한적인 유틸리티를 제공합니다. 최소값 측면에서는, 0 또는 전체 부모 컨테이너의 최소 크기를 제공하는 min-h-0와 min-h-full, 그리고 min-w-0와 min-w-full이 있습니다. 또한 양쪽 모두에 대한 접미사로 -min, -max, -fit이 있습니다. 높이의 경우, 뷰포트 옵션인 min-h-screen도 있습니다.
최대값 측면에서, 높이의 경우 max-h-{size}가 있으며, 모든 동일한 크기 숫자 목록과 더불어, 각각 전체 부모 컨테이너 높이나 전체 화면 높이를 위한 max-h-full과 max-h-screen이 있습니다.
최대 너비는 다른 옵션들을 가집니다. \(0\) 너비를 위한 max-w-0와 너비 없음을 위한 max-w-none이 있는데, 이는 CSS에서 서로 다른 것입니다.
xs, sm, md, lg, xl, 2xl부터 7xl까지의 max-w-{size} 옵션이 많이 있습니다. xs 옵션은 20\rem이고, 7xl 옵션은 80\rem입니다. 텍스트를 위한 특별한 옵션으로 65자 너비인 max-w-prose가 있습니다. 부모의 100% 옵션인 max-w-full이 있습니다. 또한 화면 크기에 기반한 화면 옵션들, max-w-screen-sm, max-w-screen-md, max-w-screen-lg, max-w-screen-xl, max-w-screen-2xl이 있습니다.
4. Page Layout
Tailwind를 사용하면 전체 페이지의 요소를 배치하고 내비게이션, 사이드바, 푸터와 같은 공통 기능을 관리할 수 있습니다. 먼저 Tailwind가 페이지에 요소를 배치하는 데 도움이 되는 몇 가지 일반적인 유틸리티, 즉 박스 간의 관계(box-to-box relationships)부터 시작하겠습니다.
Containers
많은 CSS 프레임워크는 페이지 너비를 지정하기 위한 일반적인 최상위 컨테이너로 container 클래스를 사용합니다. Tailwind도 container 유틸리티를 제공하지만, Tailwind 버전은 다른 프레임워크의 유사한 클래스보다 훨씬 적은 기능을 수행합니다.
Tailwind에서 container 유틸리티가 하는 일은 브라우저 뷰포트의 너비에 따라 요소의 max-width (최대 너비)를 지정하는 것뿐입니다. 예를 들어, 너비가 640px에서 768px 사이인 뷰포트는 max-width가 640px로 설정됩니다. 뷰포트가 768을 초과하면 max-width는 뷰포트가 1024px에 도달할 때까지 768px로 유지되다가, 뷰포트가 1280px에 도달하면 다시 증가합니다. container를 사용하면 뷰포트가 가질 수 있는 모든 너비를 고려할 필요 없이 디자인 시 특정 너비에만 집중할 수 있다는 이점이 있습니다.
CSS에서 뷰포트(viewport)는 사용자가 콘텐츠를 볼 수 있는 브라우저 영역입니다. 일반적으로 중요한 치수는 뷰포트의 너비인데, 이는 가로 스크롤 없이 화면에 얼마나 많은 콘텐츠를 배치할 수 있는지를 결정하기 때문입니다.
HTML meta 태그는 모바일 화면에서 뷰포트 너비를 제어하는 데 사용됩니다. 기본적으로 모바일 브라우저는 실제 기기보다 더 넓은 디스플레이(보통 980픽셀)를 가정하고 콘텐츠를 화면에 맞게 축소합니다. 이는 보통 끔찍하게 보입니다. content="width=device-width, initial-scale=1" 속성을 사용하면 브라우저가 더 넓은 크기에서 디스플레이를 축소하는 대신 기기 크기를 뷰포트로 사용하게 됩니다.
다른 프레임워크에 익숙하다면 Tailwind의 container에는 기대했던 기능이 없을 것입니다. Tailwind container는 자식 요소를 자동으로 수평 중앙 정렬하지 않습니다. 중앙 정렬 동작을 구현하려면 container를 mx-auto와 함께 사용합니다. 또한 Tailwind container는 요소를 브라우저 경계에서 떨어뜨리기 위한 padding (안쪽 여백)이나 margin (바깥쪽 여백)을 추가하지 않습니다. 이 동작을 구현하려면 container를 m- 또는 p- 유틸리티와 함께 사용합니다. 따라서 최상위 요소에 적용할 수 있는 적절한 클래스 목록은 className="container mx-auto py-12 px-6"와 같을 수 있습니다.
Float and Clear
새로운 디자인은 요소를 배치하기 위해 그리드(grid) 및 플렉스박스(flexbox) 도구를 사용할 가능성이 높지만, 레거시 프로젝트에서 Tailwind를 사용하는 경우 여전히 float와 clearfix를 다루어야 할 수도 있습니다.
CSS에서 float 속성은 컨테이너 내부의 콘텐츠를 배치합니다. 일반적으로 float 속성은 특정 요소(주로 이미지)를 컨테이너의 한쪽으로 배치하여 나머지 컨테이너(주로 텍스트)가 요소와 섞이지 않고 완전히 다른 쪽에 머무르도록 하는 데 사용됩니다. Tailwind는 위치 지정을 위해 float-left와 float-right를, 재설정 옵션으로 float-none을 제공합니다.
CSS clear 속성은 요소가 한쪽 또는 양쪽에서 겹칠 수 있는 다른 요소 아래에 배치되도록 강제합니다(기술적으로는 다른 요소가 float 되는 것을 막는데, 이는 결국 같은 의미). Tailwind는 한쪽, 양쪽 또는 양쪽 모두에 clear 동작을 지정하거나 지정하지 않는 유틸리티를 제공합니다. clear-left, clear-right, clear-both, clear-none을 제공합니다.
Position and Z-Index
CSS에서 z-index 속성은 화면에 수직으로 바깥쪽을 향하는 축을 “z축”이라고 가정할 때, 항목이 z축을 따라 서로 겹쳐 쌓이는 순서를 결정하는 정수입니다. Tailwind는 z-{index} 패턴을 제공하며, 여기서 index는 0, 10, 20, 30, 40, 50 또는 auto가 될 수 있습니다. -z 패턴(-z-20)을 사용하거나 임의의 값(z-[-1])을 사용하여 해당 값의 음수 z-index를 사용할 수 있습니다.
Tables
HTML 페이지의 간격을 맞추는 고전적인 방법은 테이블(table)을 사용하는 것입니다. 실제로 표 형식의 데이터를 표시하는 것이 아니라면, 이제는 레이아웃 목적으로 CSS 그리드를 사용하는 것이 더 바람직하므로 Tailwind는 많은 특정 테이블 유틸리티를 제공하지 않습니다.
Tailwind는 table-auto를 사용하여 콘텐츠에 따라 테이블의 열 간격을 자동으로 조절하는 브라우저 기본 동작을 유지할 수 있게 합니다. 열 너비를 명시적으로 지정하려면 <table> 요소에 table-fixed를 사용한 다음 테이블의 각 열에 명시적인 너비 헬퍼를 지정하면 됩니다. 이때 분수 헬퍼가 유용합니다.
Tailwind는 또한 border-collapse 유틸리티를 사용하여 인접한 테이블 셀의 테두리를 병합할 수 있게 하며, 이는 border-separate로 재설정됩니다. Tailwind는 odd: 또는 even: 변경자(modifier)를 제공하여 className="odd:bg-white even:bg-grey-300"와 같이 테이블 행에 번갈아 가며 색상을 지정할 수 있습니다.
Grids
초기 CSS 프레임워크의 위대한 혁신 중 하나는 12열 그리드에 요소를 쉽게 배치할 수 있는 그리드 레이아웃 지원이었습니다. 그리드 간격의 존재는 페이지 레이아웃을 훨씬 쉽게 만들었습니다.
프레임워크는 더욱 유연해졌고 결국 그리드 지원이 CSS에 직접 내장되었습니다. 그리드는 여전히 많은 레이아웃 선택에 훌륭하며, Tailwind는 CSS 그리드 속성을 사용하여 그리드 레이아웃을 설정하는 유용한 유틸리티를 제공합니다.
먼저 display: grid라는 CSS 속성을 위한 유틸리티인 grid가 있습니다. 그리드의 개별 요소 위, 즉 그리드의 최상위 레벨 클래스 목록에 grid 유틸리티가 포함되어야 합니다. 그리드 요소를 생성한 후에는 Tailwind를 사용하여 해당 그리드의 행 또는 열 수를 지정할 수 있습니다. 또한 그리드 내 개별 요소의 동작을 조정할 수도 있습니다. 그리드 내 요소의 시작점이나 끝점을 지정할 수도 있고, 요소가 차지하는 행 또는 열의 범위를 지정할 수도 있으며, 그리드 내부 각 요소의 간격을 변경할 수도 있습니다.
그리드의 가장 일반적인 용도는 페이지를 일련의 열로 분리하는 것이며, 이는 Tailwind의 grid-cols-{count} 헬퍼를 사용하여 수행할 수 있습니다. grid-cols-1부터 grid-cols-12까지 있으며, 각각 페이지를 해당 숫자만큼의 열로 분리합니다. 그리드 설정을 해제하는 것은 grid-cols-none입니다.
다른 CSS 그리드 프레임워크와 달리, 행(row)을 명시적으로 지정할 필요가 없습니다. 그리드 내부에서 CSS는 선언한 열 수를 기반으로 다음 행으로 자동 채우기(autofill)를 수행합니다. 예를 들어, 다음과 같이 사용할 수 있습니다.
그러면 A와 B가 첫 번째 행에, C와 D가 두 번째 행에 있는 2x2 그리드가 생성됩니다.
다른 CSS 프레임워크에서는 하기 어려운 CSS 그리드의 멋진 기능 중 하나는 행 수를 지정하여 90도 비틀기(twist)를 사용할 수 있다는 것입니다. Tailwind에서는 grid-rows-{count} 헬퍼를 사용하여 이 작업을 수행하며, 1에서 12까지의 접미사 또는 none을 가질 수 있습니다.
그리드를 통과하는 데이터의 흐름 방향을 지정할 수도 있습니다. 기본값인 grid-flow-row는 이전 예에서 본 것처럼 그리드 내부의 요소가 행을 따라 수평으로 흐르도록 합니다. 이는 여러분에게 익숙할 DOM 요소의 일반적인 동작입니다. 또는 grid-flow-col을 사용할 수 있으며, 이 경우 그리드의 요소가 열 단위로 수직으로 채워집니다. 다음과 같습니다.
이렇게 하면 2x2 그리드가 생성되지만 A와 B가 왼쪽 열이 되고 C와 D가 오른쪽 열이 됩니다.
이전 예에서 볼 수 있듯이, gap-{size}라는 편리한 이름의 헬퍼를 사용하여 테이블 셀 사이에 간격을 추가할 수 있습니다. 이 헬퍼는 간격의 크기를 접미사로 사용하며, 패딩 및 마진에서 봤던 것과 동일한 “0에서 96 사이의 일부 숫자 및 px” 측정 체계를 사용합니다. 간격 크기 조정을 수평으로만 적용하고 싶다면 gap-x-{size}를 사용할 수 있습니다. 그리고 간격을 수직으로만 적용하고 싶다면 gap-y-{size}를 사용합니다.
CSS 테이블과 마찬가지로, 때때로 셀이 두 개 이상의 행이나 열에 걸치도록 하고 싶을 수 있습니다. Tailwind는 이를 관리하는 두 가지 방법, 즉 범위(span)와 시작/끝(start/end)을 제공합니다.
span을 사용하면 col-span-{count} 또는 row-span-{count}로 셀이 차지하기를 원하는 열 또는 행의 수를 지정하며, 여기서 접미사는 열 또는 행의 수입니다. 기본값은 col-span-1 또는 row-span-1입니다. 재설정 헬퍼는 col-span-auto와 row-span-auto입니다.
중요한 점은 흐름(flow) 동작이 여전히 계속된다는 것입니다. 첫 번째 요소에 span을 추가하면, 네 개 셀 예제는 다음과 같이 됩니다.
행 방향으로 요소를 확장(span)할 수도 있습니다.
col-start-{column}과 col-end-{column} 또는 row-start-{row}와 row-end-{row}로 시작과 끝을 지정하여 그리드 아이템의 배치를 조정할 수 있습니다. 여기서 접미사는 위치 번호 또는 재설정 값인 auto입니다. 핵심은 가장 낮은 시작 위치는 1이며, 끝 위치는 배타적(exclusive)이라는 것입니다. 즉, 해당 항목에 포함되지 않습니다. 항목을 className="col-start-2 col-end-4"로 선언하면 해당 요소는 2열과 3열을 포함하지만 4열은 포함하지 않습니다.
기본적으로 시작 및 끝 위치는 그리드 내 이전 항목의 배치에 따라 자동으로 결정되며, 범위(span)는 1입니다. 시작, 끝, 범위 항목 중 임의의 두 가지를 지정하면 레이아웃이 작동합니다. 예를 들어, className="col-span-3, col-end-5"는 2열, 3열, 4열을 차지하게 되며, 3개 열에 걸쳐(span) 5열 앞에서 끝납니다.
더 고전적인 잡지 레이아웃을 원한다면 열 흐름(column flow)을 사용할 수 있으며, 이는 사진 레이아웃에도 적합합니다. Tailwind에서 열 레이아웃을 지정하는 방법은 두 가지입니다. column-{count} 패턴을 사용하여 1에서 12까지의 열 수를 지정할 수 있습니다. 또는 column-{size}를 사용하여 너비로 열을 지정할 수 있으며, 크기는 2xs에서 xs, sm, md, lg, xl, 그리고 2xl부터 7xl까지 다양합니다. 너비는 16rem에서 80rem까지 불규칙하게 분포하며, 대괄호 표기법 column-[{size}]을 사용하여 임의의 너비를 지정할 수 있습니다. column-auto를 사용하면 열 설정이 재설정됩니다. 그리드와 마찬가지로 gap 계열의 클래스를 사용하여 열을 분리할 수 있습니다.
Flexbox
Flexbox는 여러 관련 요소를 배열하는 또 다른 방법입니다. 그리드가 2차원 레이아웃으로 설계된 반면, flexbox 레이아웃은 1차원이며 항목을 행이나 열로 차례대로 배치합니다. 그리드보다 덜 유용할 것으로 예상되는 설명이지만, flexbox는 세 가지 이유로 그리드 레이아웃보다 더 유용할 수 있습니다.
- Flexbox 컨테이너는 요소의 크기를 동적으로 관리하기 위한 더 나은 제어 기능을 제공
- Flexbox 컨테이너는 개념적으로는 단일 행이지만, 콘텐츠가 너무 넓어질 때 화면에서 자동으로 줄 바꿈(wrap)하도록 만들 수 있음
- Flexbox 컨테이너는 중첩될 수 있는데, flexbox 행으로 시작하되 그 행 안의 요소들이 다시 flexbox 열이 될 수 있고, 그 열은 다시 flexbox 행을 포함할 수 있음
Flexbox를 중첩하면 레이아웃을 제어하기 위한 많은 옵션이 생깁니다.
그리드는 일부 데이터 디스플레이처럼 본질적으로 표(tabular) 형식인 콘텐츠를 관리하는 데 여전히 유용하지만, 모든 종류의 레이아웃에 해당하는 것은 아닙니다.
전체 너비의 헤더, 그 아래에 왼쪽 및 오른쪽 사이드바와 중앙의 메인 콘텐츠, 그리고 그 아래에 전체 너비의 푸터가 있는 일반적인 페이지 구조를 생각해 보십시오. 이 레이아웃을 그리드로 생각할 수 있습니다. 헤더는 3열을 차지하는(column span of three) 하나의 요소를 가진 그리드의 첫 번째 행입니다. 두 번째 행에는 너비가 조정된 사이드바와 메인 콘텐츠를 위한 세 개의 요소가 있고, 세 번째 행에는 다시 3열을 차지하는 또 다른 요소가 있습니다. 다음과 같습니다.
<div className="grid grid-cols-3 gap-4 w-1/3">
<div className="text-center col-span-3">Header</div>
<div className="text-center w-1/5">Left Sidebar</div>
<div className="text-center w-3/5">Content</div>
<div className="text-center w-1/5">Right Sidebar</div>
<div className="text-center col-span-3">Footer</div>
</div>나쁘지 않지만, 이 레이아웃을 flexbox로 생각할 수도 있습니다. Flexbox를 세 개의 요소를 가진 열(column)로 구성하고, 그 두 번째 요소가 세 개의 요소를 가진 행(row)이 되도록 할 수 있습니다. 다음과 같습니다 (이 유틸리티들이 무엇을 의미하는지는 곧 살펴보겠습니다):
<div className="flex flex-col w-1/3">
<div className="flex-grow">Header</div>
<div className="flex flex-row">
<div className="text-center w-1/5">Left Sidebar</div>
<div className="text-center w-3/5">Content</div>
<div className="text-center w-1/5">Right Sidebar</div>
</div>
<div className="flex-grow">Footer</div>
</div>또는, 페이지를 줄 바꿈(wrap)이 일어나는 단일 행으로 생각할 수도 있습니다. 다음과 같습니다.
이 세 가지 접근 방식은 거의 같은 레이아웃을 제공합니다. 결과적으로 flexbox가 그리드보다 유연(flexible)합니다. 특히, flexbox 레이아웃은 다양한 화면 크기에 적응하기가 훨씬 쉽습니다.
- Flexbox가 요소를 배치하는 방법의 기초는 방향(direction)이며, 이는 Tailwind 유틸리티로 설정합니다. 방향은
flex-row를 사용하는 수평(horizontal)이거나flex-column을 사용하는 수직(vertical)일 수 있습니다.flex-row-reverse와flex-col-reverse를 사용하여 흐름을 역방향으로 진행할 수도 있습니다. 흐름 방향의 축을 주축(main axis)이라고 하며, 다른 방향의 축을 교차축(cross axis)이라고 합니다.
Tailwind에서 부모 flexbox 컨테이너는 (그리드가 grid 클래스를 가져야 하는 것과 동일하게) flex 클래스를 포함해야 합니다.
행(row) 방향에 대해 알아야 할 중요한 점은 반드시 왼쪽에서 오른쪽은 아니라는 것입니다. 행은 텍스트의 방향으로 흐릅니다. 따라서 텍스트를, 예를 들어, 히브리어로 국제화하면 모든 flexbox의 방향이 자동으로 뒤집힐 것입니다. 열(column)의 주축은 항상 위에서 아래입니다.
- flexbox의 다음으로 중요한 속성은 줄 바꿈(wrap) 여부이며, 이는 박스의 부모 속성입니다. 기본값은
flex-no-wrap(줄 바꿈 없음)입니다. 하지만flex-wrap을 지정하면, 항목이 컨테이너의 주축을 벗어날 경우 행 컨테이너가 자동으로 항목을 다음 행으로 이동시킵니다. 일반적으로 이는 행 flexbox의 너비를 초과하는 경우지만, 열 박스의 높이를 명시적으로 설정하고 줄 바꿈을 하도록 할 수도 있습니다. 만약 어떤 이유로든 ’뒤집힌 세계’에 살고 있다면, Tailwind는flex-wrap-reverse를 제공합니다.
order-{integer} 유틸리티를 사용하여 flexbox 내 요소의 순서를 명시적으로 지정할 수 있습니다. 여기서 접미사는 1에서 12까지의 정수이거나, order-first, order-last, order-none을 사용할 수 있습니다. 항목이 12개 이상인 경우, order-[42]와 같이 임의의 값(arbitrary value) 구문을 사용하기에도 좋습니다. flexbox 내 하나 이상의 요소에 순서가 지정되면, 해당 order 속성이 소스 HTML에 요소가 나타나는 순서를 무시하고 박스 내에서 요소가 배치될 위치를 결정합니다.
이 속성의 한 가지 훌륭한 용도는 소스 순서상 메인 콘텐츠가 다른 요소보다 먼저 오도록 하면서도 화면에는 올바르게 표시되도록 하는 것입니다. 다음 코드는 이전에 보여드린 스니펫과 동일한 레이아웃을 제공합니다.
<div className="flex flex-row flex-wrap w-1/3">
<div className="text-center w-3/5 order-3">Content</div>
<div className="w-full order-1">Header</div>
<div className="text-center w-1/5 order-2">Left Sidebar</div>
<div className="text-center w-1/5 order-4">Right Sidebar</div>
<div className="w-full order-5">Footer</div>
</div>이렇게 하려는 이유는 적응형 스크린 리더(adaptive screen reader)가 콘텐츠에 빠르게 접근할 수 있도록 하면서, 페이지의 시각적 표시는 콘텐츠를 중앙에 배치하도록 허용하기 위함입니다.
- flexbox의 “flex”는 flexbox 컨테이너가 항목의 크기와 배치를 동적으로 변경할 수 있는 능력에서 유래합니다. Tailwind는 일반적인 기본값에 접근할 수 있게 해줍니다. 이 속성들은 부모가 아닌 flexbox 내부의 요소에 배치됩니다.
flexbox 내 요소의 크기를 지정하고 싶다면, CSS flex-basis 속성을 사용하는 basis-{size} Tailwind 클래스를 사용할 수 있습니다. Flex basis는 flex의 주축을 따라 요소의 크기를 지정합니다. 즉, 행 박스(row boxes)의 경우 너비(width)이고 열 박스(column boxes)의 경우 높이(height)입니다. flex-basis가 설정되면, flexbox 내부 요소의 width 또는 height 속성 대신 사용됩니다.
basis를 위한 크기 옵션은 width를 위한 옵션과 거의 동일합니다. 0에서 80까지의 동일한 표준 숫자 세트와 1/2, 1/3, 1/4, 1/5, 1/6, 1/12 분수, 그리고 auto, px, full이 있습니다. 따라서 basis-4 또는 basis-3/5, basis-auto와 같이 사용합니다. 그리고 basis-[20px]와 같이 임의의 값을 사용할 수 있는 옵션도 기억하세요.
특정 너비가 지정되지 않으면, flexbox는 사용 가능한 공간을 채우기 위해 내부 항목을 확장(grow)하거나 축소(shrink)합니다. 특정 항목이 확장되거나 축소되는 것을 원하지 않는다면, flex-none으로 지정하여 기본 크기를 유지하도록 합니다. 항목이 컨테이너의 사용 가능한 크기를 채우기 위해 필요에 따라 확장되거나 축소될 수 있기를 원한다면, flex-auto 또는 flex-1을 사용합니다.
두 가지의 차이점은 flex-auto는 각 요소의 기본 크기에서 시작하여 확장/축소 가능한 각 요소의 크기를 늘리거나 줄이는 반면, flex-1은 각 항목의 크기를 0으로 재설정하고 모든 항목에 자연 크기와 관계없이 공간을 동일하게 할당한다는 것입니다. 일반적으로 항목 세트에 flex-1을 사용하면 동일한 크기의 항목을 얻게 되지만, flex-auto는 그렇지 않습니다.
확장(grow) 동작에 영향을 주지 않고 축소(shrink) 동작만 지정할 수 있습니다. 축소를 허용하려면 flex-shrink를 사용하고, 축소를 방지하려면 flex-shrink-0을 사용합니다. 마찬가지로, flex-grow와 flex-grow-0은 축소 동작에 영향을 주지 않고 요소의 확장을 허용하거나 방지합니다.
- Tailwind는 flexbox를 사용하여 페이지에 항목을 배치하는 것 외에도, flexbox 내 요소의 정렬(alignment) 및 배치(justification)를 더 구체적으로 지정할 수 있는 유틸리티를 포함합니다. 이 유틸리티들은 그리드 레이아웃에도 적절한 경우 작동합니다.
앞서 flexbox 컨테이너에 주축(main axis)과 교차축(cross axis)이 있다고 이야기했습니다. 주축을 따른 배치에 영향을 미치는 Tailwind 유틸리티는 모두 justify-로 시작하고, 교차축을 따른 배치에 영향을 미치는 유틸리티는 그렇지 않습니다. 이 이름들은 기반이 되는 CSS 속성의 이름과 일치하도록 선택되었습니다.
먼저 주축을 살펴보겠습니다. 주축을 따라 항목 배치를 지정하는 방법에는 두 가지가 있습니다. 전체 flexbox의 주축을 따른 항목 배치와, flexbox 컨테이너 내 자신의 박스 주축을 따른 개별 항목의 배치입니다. 이 두 가지 배치는 별도로 정의할 수 있으며, 개별 요소가 아닌 부모 flexbox 컨테이너의 속성인 유틸리티를 포함합니다.
주축을 따라 요소를 배치할 때, Tailwind는 항목의 총 너비가 flexbox 컨테이너의 너비보다 작은 경우 항목을 어떻게 배치할지에 대한 유틸리티를 포함합니다. 이 유틸리티들은 여분의 공간을 어떻게 할당할지 제어합니다.
세 가지 유틸리티는 요소들을 가능한 한 가깝게 모읍니다.
justify-start는 텍스트 방향을 기준으로 축의 시작 부분에 요소를 배치justify-end는 항목을 축의 끝 부분에 배치justify-center는 항목을 중앙에 배치 (이는 CSS의 오랜 골칫거리였습니다.)
세 가지 유틸리티는 요소들 사이에 공간을 배치하며, 공간이 정확히 어디에 배치되는지에 따라 다릅니다.
justify-between은 첫 번째 요소를 flexbox의 시작 부분에, 마지막 요소를 flexbox의 끝 부분에 배치한 다음, 내부 요소들 사이에 균등한 간격을 둡니다. flexbox에 세 개의 항목이 있다면,AxBxC패턴으로 동일한 크기의 공간 두 개를 얻게 됩니다.justify-evenly는 각 항목 주위에 동일한 양의 공간을 배치합니다. flexbox에 세 개의 항목이 있다면,xAxBxCx패턴으로 동일한 크기의 공간 네 개가 항목들 주위에 배치됩니다.justify-around는 각 항목의 양쪽에 동일한 간격을 배치합니다. 실제로, 각 내부 공간은 한 요소의 왼쪽 공간과 다른 요소의 오른쪽 공간을 포함하기 때문에, 양 끝의 간격이 내부 간격보다 작아집니다. flexbox에 세 개의 항목이 있다면,xAxxBxxCx패턴으로 동일한 크기의 공간 여섯 개가 항목들 주위에 배치됩니다.
개별 박스 내 요소의 배치는 컨테이너의 클래스로 제어할 수 있으며, 옵션으로는 justify-items-start, justify-items-end, justify-items-center가 있습니다. 항목이 공간을 채우도록 확장시키고 싶다면 justify-items-stretch가 있으며, 재설정 옵션은 justify-items-auto입니다. 참고로, 보통 항목 간 간격을 조정하기 위해 일반 justify-를 사용하거나 박스 내 항목 간 간격을 조정하기 위해 justify-items-를 사용하며, 둘 다를 필요로 하는 경우는 드뭅니다.
박스의 단일 요소가 컨테이너의 정렬 방식을 재정의(override)하길 원한다면, justify-items에 존재하는 5가지 동일한 옵션과 함께 justify-self-{option}을 사용할 수 있습니다.
교차축을 따르는 유틸리티는 모두 주축의 유틸리티와 유사합니다. justify- 대신, Tailwind는 6가지 동일한 옵션을 가진 content를 제공합니다. 따라서 content-start는 다중 행(multi-row) flexbox의 상단으로 항목을 밀어 올리고, content-center는 항목을 수직으로 중앙 정렬합니다.
개별 항목의 경우, justify-items-와 동일한 5가지 옵션을 갖지만 접두사는 단순히 items-입니다. 따라서 items-center는 교차축을 따라 항목을 수직으로 중앙 정렬합니다. 마찬가지로, self 재정의를 위한 동일한 5가지 옵션이 존재하지만, 접두사는 self-start나 self-center에서처럼 self-뿐입니다.
마지막으로, place-content-, place-items-, place-self- 접두사를 사용하여 두 축을 동시에 관리할 수 있으며, 그 결과는 주축과 교차축 간격을 모두 설정한 것과 동일합니다. 따라서 place-content-center는 justify-center와 content-center를 합친 것과 동일하며, place-items-start는 justify-items-start와 items-start를 합친 것과 동일합니다.
5. Animation
Tailwind는 CSS 애니메이션과 변형(transformation) 동작의 전체 구현을 제공하지는 않습니다. 유틸리티 프레임워크에 그 정도를 기대하기는 무리일 것입니다. 일반적인 동작에 유용한 기본값들을 제공하기는 하지만, Tailwind 공식 문서조차도 이것들이 단지 제안 사항일 뿐이며 애니메이션을 사용하는 대부분의 프로젝트는 사용자 정의 동작을 정의해야 할 필요가 있다고 인정합니다.
Tailwind는 animate-bounce, animate-ping, animate-pulse, animate-spin의 네 가지 완전한 애니메이션 유틸리티를 제공합니다. 이 클래스들은 애니메이션을 위한 CSS와 키프레임(keyframe) 세트를 모두 정의하므로, 요소에 그대로 사용할 수 있습니다.
첫 번째 유틸리티인 animate-bounce는 1초 동안 요소 크기의 25%만큼 수직 위치를 아래로 이동시켰다가 다시 원래 위치로 복귀하는 트랜지션을 기술하며, 가벼운 아래쪽 바운스 효과를 줍니다. 예를 들어, hover:animate-bounce를 사용하면 멋진 “현재 위치” 효과를 줄 수 있습니다.
두 번째 유틸리티인 animate-ping으로 알림 효과에 약간의 애니메이션을 줄 수 있습니다. 이는 1초 동안 일반 크기와 불투명도에서 두 배의 크기와 0의 불투명도로 변하는 애니메이션으로, 꽤 효과적인 신호 펄스 효과를 줍니다.
일반적인 로딩 동작 중 하나는 더미(dummy) 요소를 표시하고 서버가 데이터를 제공함에 따라 점진적으로 데이터로 대체하는 것입니다. 세 번째 Tailwind 유틸리티인 animate-pulse는 0.1과 0.5 불투명도 사이를 2초간 전환하며, 요소에 약간의 페이드(fade) 효과를 만들어냅니다.
마지막 유틸리티인 animate-spin은 객체를 1초에 360도 완전히 회전시킵니다. 이는 로딩 상태 표시기 같은 것에 사용하도록 설계되었습니다.
사용하려는 SVG나 이미지가 있다면, animate-spin을 (컨테이너가 아닌) SVG나 이미지 요소 자체에 추가하십시오. 그러면 해당 요소가 회전할 것입니다. 이 모든 애니메이션은 animate-none으로 무효화됩니다.
Transitions
CSS에서는 하나 이상의 속성값이 변경될 때, 즉시 변경되는 대신 점진적으로 전환(transition)되도록 지정할 수 있습니다. 완전한 클라이언트 사이드 애플리케이션에서는, JavaScript를 사용하여 요소의 CSS 클래스를 수정하는 방식으로 값을 변경할 수 있습니다. Tailwind에서는 변경자(modifier)를 사용하여 일부 CSS 속성 변경을 CSS만으로 관리할 수 있습니다. 예를 들어, “bg-green-500 hover:bg-yellow-500” 클래스 목록을 가진 요소는 사용자가 그 위로 마우스를 올리면(hover) 색상이 녹색에서 노란색으로 변경되며, Tailwind의 트랜지션 유틸리티는 이 변경이 점진적으로 일어나게 할 수 있습니다.
대부분의 경우, 요소에 transition 클래스를 선언하게 되는데, 이는 해당 요소가 background-color, border-color, box-shadow, color, fill, opacity, stroke, transform CSS 속성에 대해 트랜지션 효과를 사용하도록 합니다. 종종 이 속성들이 트랜지션을 적용하고자 하는 속성의 전부일 때가 많지만, 만약 다른 속성에도 트랜지션을 적용해야 한다면 transition-all을 사용하여 모든 속성을 트랜지션 대상에 포함시킬 수 있습니다.
트랜지션을 특정 속성으로 제한하고 싶다면, Tailwind는 여러 선택지를 제공합니다. 일반적으로 이 유틸리티들은 즉시 변경되기를 원하는 다른 속성들이 있을 때 사용합니다.
transition-colortransition-opacitytransition-shadowtransition-transform
트랜지션이 실제로 보이게 하려면, 트랜지션이 일어나는 지속 시간(duration)을 지정해야 합니다. 기본값은 0이지만 (Tailwind 설정에서 변경 가능), Tailwind는 duration-{milliseconds} 계열의 유틸리티를 제공합니다. 여기서 접미사는 75, 100, 150, 200, 300, 500, 700, 1000 중 하나이며, 트랜지션이 진행될 밀리초(milliseconds)를 나타냅니다. 또한 임의의 값 구문(arbitrary value syntax)도 사용할 수 있습니다.
delay-{milliseconds}와 동일한 숫자 세트 또는 임의의 값을 사용하여 트랜지션의 시작을 지연시킬 수도 있습니다. 이는 트랜지션이 시작되기 전의 대기 시간을 밀리초로 나타냅니다.
Transformation
기본적으로 트랜지션은 선형(linearly)으로 적용됩니다. 즉, 속성 변경이 동일한 크기의 단계들로 연속적으로 일어납니다. 이 기본값은 Tailwind 유틸리티 ease-linear로 표시됩니다. 만약 속성 변경이 더 느리게 시작해서 속도를 높였다가 끝에 가까워질수록 다시 느려지게 하고 싶다면, ease-in-out을 사용할 수 있습니다. (또는, 변경의 한쪽(시작 또는 끝)에서만 감속 효과를 원한다면 ease-in이나 ease-out을 사용할 수도 있습니다.) 이 ’ease’의 차이는 미묘하지만, 특히 움직임(motion)의 경우, 변경이 가속했다가 감속하는 느낌을 주어 더 자연스럽고 매력적으로 보이게 할 수 있습니다.
CSS를 사용하면 요소의 박스(box)를 다양한 방식으로 변형(transform)하여 크기, 위치, 회전 또는 기울임(skew)을 변경할 수 있습니다. Tailwind는 여기에서도 합리적인 기본값들을 제공하며, 이를 트랜지션 및 애니메이션과 결합하면 몇 가지 멋진 효과를 쉽게 구축할 수 있습니다.
Tailwind는 scale-{percentage} 계열의 유틸리티로 요소의 크기(scale)를 변경할 수 있게 해주며, 여기서 접미사는 크기를 조절할 백분율입니다. 임의의 값이 아닌 기본 옵션으로는 0, 50, 75, 90, 95, 100, 105, 110, 125, 150이 있으며, (제 생각에는) 이는 “transition duration-1000 hover:scale-110”과 같은 미묘한 효과를 가능하게 하도록 설계된 것 같습니다. (이 경우 요소에 마우스를 올리면 1초에 걸쳐 요소가 약간 커집니다). 여기에 hover:box-shadow-lg를 추가하면, 마우스를 올렸을 때 요소가 사용자에게 더 가까이 다가오는 것처럼 보일 것입니다.
만약 한쪽 방향으로만 크기를 조절하고 싶다면, scale-x-{percentage} 또는 scale-y-{percentage}를 동일한 숫자 세트와 함께 사용할 수 있습니다 (예: scale-x-95, scale-y-125 등).
rotate-{degrees}로 요소를 회전시킬 수 있으며, 이는 지정된 각도(degrees)만큼 시계 방향으로 변형(transformation)하는 것입니다. 제공되는 옵션은 0, 1, 2, 3, 6, 12, 45, 90, 180이며, 임의의 값은 다른 단위를 사용할 수 있습니다. 반시계 방향 회전은 -rotate-{degrees}와 동일한 숫자들을 사용하여 구현합니다. 이 역시 사소한 효과들을 쉽게 만들 수 있도록 설계된 것입니다.
기본적으로 회전은 요소의 중앙에 있는 축을 중심으로 이루어지며, Tailwind는 이를 origin-center로 나타냅니다. origin-에 다른 곳에서 보았던 것과 동일한 네 방향 및 네 모서리에 대한 접미사를 추가하여 원점(origin)을 이동시킬 수 있습니다 (예: origin-top, origin-bottom-right 등).
기울이기(skew)를 위해서는 skew-x-{degrees}, -skew-x-{degrees}, skew-y-{degrees}, -skew-y-{degrees}가 있으며, 제공되는 옵션으로 숫자 접미사 0, 1, 2, 3, 6, 또는 12를 사용하며, 이는 기울이는 각도(degrees)를 나타냅니다.
translate-x-{size}, -translate-x-{size}, translate-y-{size}, 또는 -translate-y-{size}를 사용하여 요소를 아예 이동시킬 수 있으며, 각각 숫자 접미사를 사용합니다. 이는 패딩, 마진 등에서 보았던 것과 동일한 숫자 스케일(scale)을 사용하여 해당 방향으로 요소를 이동시키며, 여기서 각 숫자는 0.25rem을 나타냅니다. 양의 방향은 오른쪽과 아래쪽이며, 음의 방향은 왼쪽과 위쪽입니다.
숫자 세트 외에도, 접미사로 px(단일 픽셀), full(“해당 차원의 정확한 크기만큼 이동”), 그리고 \(1/2\)(“해당 차원 크기의 절반만큼 이동”)을 사용할 수 있습니다. 예를 들면 translate-x-full 또는 translate-y-1/2와 같습니다.
커서(cursor)와 텍스트에 대한 다른 변경 사항들도 적용할 수 있습니다. cursor-auto, cursor-default, cursor-move, cursor-not-allowed, cursor-pointer, cursor-text, cursor-wait 유틸리티를 사용하여, 사용자가 마우스를 올렸을 때(hover) 보게 되는 커서를 다른 표준 커서로 재정의(override)할 수 있습니다.
select-none으로 요소 내의 텍스트를 복사/붙여넣기 목적으로 선택할 수 없게 막고, select-text로 허용하거나, select-all을 사용하여 클릭 시 전체 텍스트가 자동 선택되게 할 수 있습니다. (부디 이 기능은 사용하지 마십시오. 이는 다소 사용자 적대적이지만, 특정 보안 또는 규정 준수 관련 이유로 요청받을 수도 있습니다.)
또한 resize로 요소에 크기 조절 핸들(handle)을 제공할 수 있으며, resize-x 또는 resize-y로 핸들을 한 방향으로 제한하거나 resize-none으로 이를 초기화할 수 있습니다.
6. Responsive Design
이 노트에서 지금까지 살펴본 모든 예제에는 한 가지 공통점이 있습니다. 바로 컴퓨터 화면용으로 설계되었으며 스마트폰이나 태블릿과 같은 더 작은 화면에서는 잘 보이도록 설계되지 않았다는 것입니다.
여러 크기의 화면에서 작동하는 CSS 디자인을 만드는 과정을 반응형 디자인(responsive design)이라고 합니다. 일반 CSS에서 반응형 디자인은 CSS 클래스와 @media 태그가 복잡하게 얽힌 문제일 수 있습니다. Tailwind는 화면 크기 세트를 제어하기 위해 모든 Tailwind 유틸리티에 적용할 수 있는 수정자(modifiers)를 제공합니다.
Tailwind가 반응형 디자인의 모든 복잡성을 해결해주는 것은 아닙니다. 여러 크기에 맞춰 디자인할 때는 여전히 많은 요소를 고려해야 합니다. 예를 들어, 사용자가 더 작은 화면을 볼 때 사이트의 어떤 요소가 가장 중요하고 강조되어야 하는지 생각해야 합니다. 하지만 Tailwind를 사용하면 다양한 크기에서 여러 디자인을 더 쉽게 실험하고, 모든 크기별 동작을 한눈에 볼 수 있습니다. 그렇긴 해도, Tailwind의 반응형 디자인은 CSS 클래스 선언이 극도로 길어져 읽기 어려워질 수 있습니다.
Tailwind 화면 너비와 중단점
CSS에서는 화면 너비에 따라 다양한 속성을 조건부로 적용할 수 있습니다. 이러한 조건은 @media 태그로 관리됩니다. 디자인이 변경되는 특정 화면 너비를 흔히 중단점(breakpoints)이라 부릅니다.
Tailwind에서는 모든 Tailwind 유틸리티에 반응형 수정자를 붙여 해당 유틸리티가 적용되어야 하는 최소 화면 너비를 지정할 수 있습니다.
Tailwind의 반응형 동작은 다른 프레임워크에서 익숙했던 방식과 약간 다릅니다. 주목해야 할 몇 가지 중요한 동작은 다음과 같습니다.
- 모든 반응형 수정자는 지정된 화면 너비
또는 그보다 큰화면 너비에서 유틸리티가 적용되도록 함 - Tailwind 유틸리티는 적용될
최소 너비를 정의하지만최대 너비는 정의하지 않음 - 수정자를 사용하지 않으면 기본 최소 너비는 0이며, 유틸리티는 항상 적용됨
만약 작은 화면 너비용으로 무언가를 정의하면, Tailwind는 그 동작을 작은 화면, 중간 화면, 큰 화면 및 그 이상까지 계속 적용합니다. 만약 작은 화면에서만 동작하게 하려면, 수정자 없이 작은 화면 동작을 정의하고, 중간 화면이나 큰 화면 수정자로 이를 취소하는 동작을 정의해야 합니다.
Tailwind는 기본적으로 5개의 화면 너비를 정의합니다. 이 5개 화면 너비의 픽셀 너비는 화면의 논리적 너비(logical width)입니다. 논리적 픽셀 하나가 여러 개의 물리적 픽셀로 구성된 레티나(retina) 화면 기기에서도 여전히 논리적 화면을 사용합니다. 예를 들어, iPhone 13은 물리적 픽셀 너비가 1170이지만 논리적 픽셀 너비는 390입니다.
5개의 화면 너비는 다음과 같습니다.
sm: 640픽셀 이상md: 768픽셀 이상lg: 1024픽셀 이상xl: 1280픽셀 이상2xl: 1536픽셀 이상
다음 표는 기존 기기 너비의 일부 목록입니다.
#table( columns: (1fr, 1fr), [ 기기 ], [ 논리적 픽셀 ], [ Galaxy S20], [ 360 ], [ Galaxy S20 가로 모드], [ 800 ], [ iPhone 13], [ 390 ], [ iPhone 13 가로 모드], [ 844 ], [ iPad Air 3], [ 834 ], [ iPad Air 3 가로 모드], [ 1112 ], [ iPad Pro 12], [ 1024 ], [ iPad Pro 12 가로 모드], [ 1366 ], [ MacBook Air], [ 2560 (주로 1680으로 조절됨) ], )
핵심은 sm:(예: sm:m-2)으로 무언가를 정의하면, 해당 m-2 유틸리티는 640픽셀 이상의 모든 화면에 대해 정의된다는 것입니다. 더 큰 화면에서 해당 마진을 변경하고 싶다면, 더 큰 수정자를 가진 유틸리티를 정의하면 됩니다. 더 큰 수정자가 더 작은 수정자보다 우선 적용되는 것이 보장됩니다. 따라서 sm:m-2 md:m-4 lg:m-8과 같이 사용하여 화면 너비가 넓어질수록 마진이 점차 넓어지게 할 수 있습니다.
이러한 패턴에 접근하는 일반적인 방법은 다음과 같습니다. 수정자가 없는 유틸리티는 가장 작은 화면에서 보이는 동작을 기술해야 하며, 그다음 화면이 커짐에 따라 동작을 조정하기 위해 수정자가 있는 유틸리티를 가져옵니다. 즉, 모바일 기기를 기준으로 먼저 디자인을 정의한 다음, 수정자를 사용하여 더 큰 화면에 맞게 디자인을 조정하는 것입니다.
저는 이 노트 전반에 걸쳐 부정(negation) 유틸리티나 기본 유틸리티가 어디에 사용될지 명확하지 않은 경우에도 일관되게 지적하려고 노력했습니다. 반응형 유틸리티가 바로 이러한 부정 유틸리티가 사용되는 곳입니다. Tailwind에서 너비 수정자는 해당 크기 이상에서 적용됩니다. 더 넓은 너비에서 유틸리티 적용을 해제하려면, 더 큰 너비에서 명시적으로 이를 부정해야 합니다. 예를 들어, sm:shadow-xl md:shadow-none과 같은 것은 shadow-none 초기화 유틸리티를 사용하여 shadow-xl을 되돌립니다. (어떤 이유로든 그렇게 하고 싶다면) 요소에 이 두 가지를 모두 사용하면 640과 768 사이의 너비에서 박스 섀도우를 얻게 됩니다.
화면 크기를 다른 수정자와 결합할 수 있다는 점도 언급할 가치가 있습니다. md:hover:font-bold lg:hover:font-black은 완벽하게 유효합니다.
크기에 따라 숨기기
애플리케이션을 더 작은 화면에 맞추는 한 가지 방법은 더 작은 화면에서 사용자 인터페이스의 일부를 숨기는 것입니다. 이 경우, 가장 작은 화면의 동작이 ’숨김’이므로, 수정자가 없는 속성은 hidden이 됩니다. 더 큰 크기에서는 항목을 표시하고 싶을 수 있으므로, lg:block(또는 항목이 보이기 시작하길 원하는 중단점)을 추가하여 className="hidden lg:block"과 같이 만듭니다.
때로는 반대로 더 작은 크기에서는 요소를 표시하고 더 큰 크기에서는 표시하지 않기를 원할 수도 있습니다. 작은 크기에서는 햄버거 메뉴 요소가 내비게이션 바를 대체하지만, 모든 내비게이션을 표시할 만큼 큰 기기에서는 사라지는 것이 매우 일반적입니다. 이 경우, 작은 크기의 동작은 기본값인 ’표시’이며, className="lg:hidden"에서처럼 중단점에 숨기는 동작을 추가합니다.
마찬가지로, 더 작은 기기에서는 헤더 텍스트의 크기를 줄이는 것이 일반적입니다. 더 작은 크기가 더 작은 너비에서 표시되므로, 결과 DOM 클래스는 className="text-xl md:text-2xl lg:text-4xl"과 같을 것입니다.
작은 기기에서 그리드 열 줄이기
일반적인 용어로, 많은 반응형 디자인의 목표는 작은 크기에서는 정보를 쌓고, 더 큰 크기에서 공간이 있을 때는 행으로 펼칠 수 있게 동시에 허용하는 것입니다. 이를 정확히 어떻게 하고 싶은지는 목표에 따라 다릅니다.
한 가지 가능성은 뉴스 사이트의 추천 게시물과 같이 카드와 유사한 요소 세트가 있는 경우입니다. 이 데이터는 실제 테이블이 아니라 행으로 배치된 일련의 항목들입니다. 이 경우, 항목이 화면 전체 너비를 채우되 화면 크기에 따라 항목 수가 달라지기를 원할 수 있습니다. 스마트폰에서는 화면에 항목이 하나만 표시되기를 원할 수 있고, 데스크톱에서는 4개가 표시되기를 원할 수 있습니다.
따라서 다음과 같이 사용할 수 있습니다.
여기서 몇 가지 작업이 진행 중입니다. 부모 div는 모든 너비에서 그리드이지만, 가장 좁은 너비에서의 기본 그리드 크기는 1이며, 중간 화면(md)에서는 2로, 큰 화면(lg)에서는 4로 늘어납니다. items-stretch는 각 개별 자식 요소가 너비의 해당 부분을 채우기 위해 늘어난다는 것을 의미합니다. 즉, 다음 중단점까지 화면이 커질수록 요소도 커지다가, 그다음에는 각 행에 더 많은 항목이 추가됩니다.
또한 화면이 커짐에 따라 항목 사이의 간격(gap)도 늘립니다.
자식 항목의 경우, 행에 요소가 하나만 있을 때(가장 작은 크기) 약간의 간격을 두기 위해 하단 마진 mb-6을 적용하지만, lg:mb-0을 사용하여 화면이 커지면 하단 마진이 사라집니다.
더 큰 기기에서 Flex 사용하기
크기 간 조정을 하는 또 다른 방법은 요소가 더 작은 기기에서는 기본 블록(block) 간격을 사용하다가 더 큰 기기에서는 플렉스(flex) 간격으로 변환하도록 하는 것입니다. 작은 기기에서의 블록 간격은 일부 항목이 좁더라도 항목들이 열(column)을 유지하도록 보장하는 반면, 더 큰 크기에서의 플렉스 간격은 항목들을 행(row)으로 펼칩니다.
여기서 일반적인 패턴은 더 큰 크기에서는 페이지 상단에 펼쳐지는 내비게이션 바입니다. 하지만 더 작은 크기에서는 메뉴 버튼을 클릭할 때까지 일반적으로 숨겨져 있는 메뉴 열이 됩니다. 관련 사항은 구글이나 검색 사이트에 ’Tailwind Hamburger Menu’를 검색하면 쉽게 찾을 수 있습니다.
Footnotes
중복이 발생할 수 밖에 없는 구조입니다. 이 문제는 Tailwind를 비판하는 분들이 가장 많이 거론하는 문제입니다. 하지만, 이 중복을 허용하는 관례를 감수하면서 Tailwind를 사용하다는 것은 중복 문제를 해결하는 방법이 있다는 것을 의미합니다. 단지, 이 노트를 참고하고 계신분들을 초급자라고 가정하고 있기 때문에, 해당 문제를 깊이있게 논의하지 않을 뿐입니다. 그리고 공통 CSS 클래스를 추출하여 더 시맨틱한 이름을 부여하는 방법에 대해서, Tailwind는 자신만의 클래스를 만들기보다는, 프런트엔드 스택에서 사용하는 것과 동일한 도구들을 활용하여 중복을 줄일 것을 권장하고 있습니다. 즉, Tailwind는 버튼 스타일을 위해 별도의 CSS 클래스를 만드는 대신, 재사용 가능한 React 컴포넌트나 Rails의 partial 또는 헬퍼 메서드(helper method)를 만들고, 해당 재사용 항목에 대해서만 CSS 스타일을 한 번 정의하라고 제안합니다.↩︎