Tailwind CSS v2.2
- Date
- Adam Wathan
우리가 정말로 계획하고 있었다고 말할 수는 없지만, 지난 몇 주 동안 Tailwind에 새롭고 흥미로운 기능들을 추가하는 데 재미를 느꼈고, 이제는 릴리즈를 할 적절한 시기라고 생각합니다. 그래서 여기 있습니다 — Tailwind CSS v2.2!
이번 릴리즈는 지금까지 가장 기능이 풍부한 Tailwind 릴리즈 중 하나입니다. v2.1에서 Just-in-Time 모드를 도입하면서, 이전에는 쉽게 추가할 수 없었던 많은 멋진 기능들을 추가할 수 있게 되었고, 이번 릴리즈는 그런 기능들의 훌륭한 예시들로 가득 차 있습니다.
주요 기능은 다음과 같습니다:
- 새로운 고성능 Tailwind CLI
- Before 및 after 변형
- 첫 글자/줄 변형
- 선택된 텍스트 변형
- 리스트 마커 변형
- 형제 선택자 변형
- 완전한 의사 클래스 지원
- 단축 색상 불투명도 구문
- 확장된 임의 값 지원
- 개선된 중첩 지원
- 캐럿 색상 유틸리티
- 배경 오리진 유틸리티
- 단순화된 변환 및 필터 합성
- 측면별 테두리 색상 유틸리티
- 내장된 안전 목록, 변환 및 추출 지원
자세한 내용은 GitHub의 릴리즈 노트를 확인하세요.
이번 릴리즈는 마이너 릴리즈이며, 클래식 엔진에는 호환성이 깨지는 변경 사항이 없지만, Just-in-Time 모드는 아직 미리보기 상태이며, v2.2에서는 몇 가지 매우 작은 변경 사항이 있어 영향을 받을 수 있습니다. 따라서 업그레이드할 때 릴리즈 노트의 변경 사항 및 폐기 예정 항목을 꼭 읽어보세요.
업그레이드할 준비가 되었다면, npm에서 최신 버전을 설치하면 됩니다:
npm install -D tailwindcss@latest
완전히 새로워진 고성능 Tailwind CLI
우리는 Tailwind CLI 도구를 처음부터 다시 작성하며 성능을 최우선으로 고려했고, 여러 새로운 기능도 추가했습니다.
npx tailwindcss -o dist/tailwind.css --watch --jit --purge="./src/**/*.html"
주요 특징은 다음과 같습니다:
- 설치나 설정이 필요 없음 — 어디서든
npx tailwindcss -o output.css
명령어로 Tailwind를 컴파일할 수 있습니다. 설정 파일 없이도--jit
플래그로 JIT 모드를 활성화하고--purge
옵션으로 콘텐츠 파일을 전달할 수 있습니다. - 워치 모드 — 파일 변경 시 자동으로 CSS를 다시 빌드합니다.
- JIT 성능 최적화 — CLI가 Tailwind 전용이기 때문에 JIT 모드에서 CSS를 컴파일하는 가장 빠른 빌드 도구로 만들 수 있었습니다.
- 최소화 지원 — 이제
--minify
플래그만 추가하면 cssnano를 사용해 CSS를 최소화할 수 있습니다. - PostCSS 플러그인 지원 — 새로운 CLI는
postcss.config.js
파일로 설정한 추가 플러그인을 읽고 적용합니다.
이전 CLI와 완벽하게 호환되므로, 이미 설정한 스크립트가 있다면 v2.2로 업그레이드해도 스크립트를 변경할 필요가 없습니다.
더 자세한 내용은 업데이트된 Tailwind CLI 문서를 참고하세요.
참고: tailwindcss-cli
래퍼 패키지를 사용 중이라면, 이제 tailwindcss
로 안전하게 전환할 수 있습니다. 래퍼 패키지를 만든 이유였던 peer-dependency 문제를 해결했기 때문입니다.
before와 after 의사 엘리먼트 변형
이 기능은 Just-in-Time 모드에서만 사용할 수 있습니다.
오랜 시간 동안 요청받아 왔던 기능이 드디어 추가되었습니다! 이제 before
와 after
같은 의사 엘리먼트를 스타일링할 수 있는 퍼스트클래스 지원이 제공됩니다:
<div class="before:block before:bg-blue-500 after:flex after:bg-pink-300"></div>
before
나 after
변형을 사용할 때마다 자동으로 content: ""
를 설정하여 엘리먼트가 렌더링되도록 보장합니다. 하지만 새로운 content
유틸리티를 사용하여 이를 재정의할 수 있으며, 이 유틸리티는 완전한 임의 값 지원을 제공합니다:
<div class="before:content-['hello'] before:block ..."></div>
CSS attr()
함수를 사용하여 속성에서 내용을 가져올 수도 있습니다:
<div
before="hello world"
class="before:content-[attr(before)] before:block ..."
></div>
이 기능은 내용에 공백이 포함된 경우에 매우 유용합니다. CSS 클래스 이름에는 공백을 사용할 수 없기 때문입니다.
첫 글자/첫 줄 변형 기능
이 기능은 Just-in-Time 모드에서만 사용할 수 있습니다.
first-letter
와 first-line
의사 엘리먼트를 위한 변형 기능을 추가했습니다. 이를 통해 드롭 캡스(drop caps) 같은 효과를 만들 수 있습니다:
<p class="first-letter:text-4xl first-letter:font-bold first-letter:float-left">
1996년 3월 31일 밤, 브렛 하트와 숀 마이클스의 오랜 기다림 끝에 이루어진 아이언맨 매치가 펼쳐졌습니다. 이 60분간의 지구력 대결에서 가장 많은 승점을 얻은 선수가 WWF 월드 헤비웨이트 챔피언의 자리를 차지하게 됩니다.
</p>
선택된 텍스트 스타일링
이 기능은 Just-in-Time 모드에서만 사용할 수 있습니다.
디자인에 맞게 강조된 텍스트를 쉽게 스타일링할 수 있는 새로운 selection
변형을 추가했습니다:
<p class="selection:bg-pink-200">
거의 한 시간 동안 치열한 싸움을 벌였지만, 어느 쪽도 승리를 거두지 못한 상황에서 Hart는 그의 시그니처 서브미션 홀드인 Sharpshooter를 걸었습니다. Michaels가 고통에 비명을 지르자, 관중들은 Hart가 WrestleMania XII에서 여전히 세계 헤비급 챔피언으로 남을 것이라고 확신했습니다.
</p>
이 기능은 부모 엘리먼트에 적용하여 하위 엘리먼트로 캐스케이드할 수 있도록 설계되었습니다. 따라서 body에 유틸리티를 적용하여 전체 사이트의 강조 색상을 설정할 수 있습니다:
<body class="selection:bg-pink-200">
<!-- ... -->
<p>
하지만 Michaels는 포기하지 않았습니다 — 그는 종이 울리고 지정된 60분이 끝날 때까지 버텼습니다. Hart는 명확한 승자가 없으므로 타이틀을 유지할 수 있다고 생각하며 만족스럽게 떠났습니다. 그는 Gorilla Monsoon이 갑작스러운 죽음 규칙으로 경기를 계속할 것이라고 선언할 때 벌어질 일에 대해 준비가 되어 있지 않았습니다.
</p>
</body>
리스트 마커 스타일링
이 기능은 Just-in-Time 모드에서만 사용할 수 있습니다.
새로운 marker
변형을 사용하면 리스트의 불릿이나 숫자에 스타일을 적용할 수 있습니다:
<h1>WrestleMania XII 결과</h1>
<ol class="marker:text-gray-500 marker:font-medium">
<li>
The British Bulldog, Owen Hart, Vader가 Ahmed Johnson, Jake Roberts, Yokozuna를 물리쳤습니다
</li>
<li>Roddy Piper가 Goldust를 물리쳤습니다</li>
<li>Stone Cold Steve Austin이 Savio Vega를 물리쳤습니다</li>
<li>The Ultimate Warrior가 Hunter Hearst Helmsley를 물리쳤습니다</li>
<li>The Undertaker가 Diesel을 물리쳤습니다</li>
<li>Shawn Michaels가 Bret Hart를 물리쳤습니다</li>
</ol>
selection
변형과 마찬가지로, 이 기능은 부모로부터 캐스케이드되도록 구현되어 있어 각 리스트 항목마다 반복할 필요가 없습니다.
형제 선택자 변형
이 기능은 Just-in-Time 모드에서만 사용할 수 있습니다.
Tailwind CSS v2.2는 group-*
변형과 유사하게 동작하지만, 부모 엘리먼트 대신 형제 엘리먼트를 대상으로 하는 새로운 peer-*
변형을 추가했습니다.
이 기능은 앞에 있는 체크박스가 체크되었을 때 엘리먼트를 스타일링하거나, 플로팅 레이블을 구현하는 등 다양한 용도로 유용합니다:
<label>
<input type="checkbox" class="peer sr-only">
<span class="h-4 w-4 bg-gray-200 peer-checked:bg-blue-500">
<!-- ... -->
</label>
group
이 다른 변형과 결합할 수 있는 것처럼, peer
도 마찬가지입니다. 따라서 peer-hover
, peer-focus
, peer-disabled
등 다양한 변형을 손쉽게 사용할 수 있습니다.
생성된 CSS는 일반 형제 결합자를 사용하며 다음과 같이 보입니다:
.peer:checked ~ .peer-checked\:bg-blue-500 {
background-color: #3b82f6;
}
따라서 일반 CSS와 마찬가지로, 이 기능은 DOM에서 뒤에 나오는 형제가 아닌 이전 형제만 대상으로 동작합니다.
완벽한 의사 클래스 지원
이 기능은 Just-in-Time 모드에서만 사용할 수 있습니다.
이번 릴리스에서는 생각할 수 있는 거의 모든 누락된 의사 클래스에 대한 변형을 추가했습니다:
only
(only-child)first-of-type
last-of-type
only-of-type
target
default
indeterminate
placeholder-shown
autofill
required
valid
invalid
in-range
out-of-range
이 목록에서 개인적으로 가장 좋아하는 것은 placeholder-shown
입니다. 새로운 형제 선택자 변형과 함께 사용하면 플로팅 레이블과 같은 멋진 기능을 구현할 수 있습니다:
<div class="relative">
<input id="name" class="peer ...">
<label for="name" class="peer-placeholder-shown:top-4 peer-focus:top-0 ...">
</div>
색상 불투명도 단축 문법
이 기능은 Just-in-Time 모드에서만 사용할 수 있습니다.
Tailwind CSS v2.2에서는 bg-opacity-50
, text-opacity-25
, placeholder-opacity-40
같은 유틸리티를 사용하는 대신, 색상 유틸리티 내에서 직접 색상의 알파 채널을 조정할 수 있는 새로운 색상 불투명도 단축 문법을 제공합니다:
<div class="bg-red-500 bg-opacity-25">
<div class="bg-red-500/25">
이제 Tailwind 어디에서든 색상의 불투명도를 변경할 수 있습니다. 예를 들어 그라데이션과 같이 이전에는 특정 불투명도 유틸리티가 없던 곳에서도 사용할 수 있습니다:
<div class="bg-gradient-to-r from-red-500/50"></div>
불투명도 값은 opacity
스케일에서 가져오지만, 대괄호 표기법을 사용하여 임의의 불투명도 값을 사용할 수도 있습니다:
<div class="bg-red-500/[0.31]"></div>
솔직히 말해서, 이 기능을 실제로 사용하는 것보다는 여러분을 위해 placeholderOpacity.js
같은 코어 플러그인을 더 이상 만들지 않아도 된다는 점이 더 기쁩니다. 그리고 이 기능에 대해 정말로 기대가 크다는 점이 무언가를 말해줍니다.
확장된 임의 값 지원
이 기능은 Just-in-Time 모드에서만 사용할 수 있습니다.
우리는 Tailwind의 모든 코어 플러그인을 검토하여 가능한 한 유연한 임의 값 지원을 추가하려고 노력했고, 이제 거의 모든 것을 다룬 것 같습니다.
여러분은 거의 모든 곳에서 원하는 임의 값을 사용할 수 있어야 합니다:
<div class="col-start-[73] placeholder-[#aabbcc] object-[50%] ..."></div>
만약 우리가 놓친 부분을 발견하면 이슈를 열어주세요. 우리가 해결해 드리겠습니다.
임의 값 지원을 더 포괄적으로 만들기 위해, 모호한 상황을 처리하기 위한 새로운 타입 힌트 구문도 추가했습니다. 예를 들어, CSS 변수를 임의 값으로 사용할 때 생성된 CSS가 무엇인지 항상 명확하지 않을 수 있습니다:
<!-- 이건 폰트 크기 유틸리티일까요, 아니면 텍스트 색상 유틸리티일까요? -->
<div class="text-[var(--mystery-var)]"></div>
이제 타입 이름을 접두사로 붙여 엔진에 힌트를 제공할 수 있습니다:
<div class="text-[color:var(--mystery-var)]"></div>
현재 지원되는 타입은 다음과 같습니다:
length
color
angle
list
시간이 지나면서 사람들이 새로운 예외 사례를 발견하면 더욱 확장할 예정이지만, 이 정도면 충분히 활용할 수 있을 것입니다.
개선된 중첩 지원
Tailwind는 @tailwind
나 @apply
와 같은 비표준 CSS at-규칙을 많이 도입하기 때문에, postcss-nested
나 postcss-nesting
같은 PostCSS 중첩 플러그인과 함께 사용할 때 이상한 출력이 발생할 수 있습니다.
이 문제를 해결하기 위해, tailwindcss
패키지에 새로운 PostCSS 플러그인을 포함시켰습니다. 이 플러그인은 기존 중첩 플러그인과 Tailwind 사이의 경량 호환성 레이어 역할을 합니다.
따라서 프로젝트에서 중첩 지원이 필요하다면, 이 플러그인을 사용하고 PostCSS 플러그인 목록에서 Tailwind 앞에 배치하세요:
// postcss.config.js
module.exports = {
plugins: [
// ...
require('tailwindcss/nesting'),
require('tailwindcss'),
// ...
],
}
기본적으로 이 플러그인은 내부적으로 postcss-nested
를 사용합니다 (Tailwind 플러그인에서 중첩을 지원하기 위해 사용하는 것과 동일). 하지만 postcss-nesting
을 사용하고 싶다면, 플러그인을 함수로 호출하고 postcss-nesting
플러그인을 전달하면 됩니다:
// postcss.config.js
module.exports = {
plugins: [
// ...
require('tailwindcss/nesting')(require('postcss-nesting')),
require('tailwindcss'),
// ...
],
}
내부적으로 이 플러그인은 새로운 screen()
함수를 사용합니다. 이 함수를 통해 구성된 브레이크포인트에서 확장된 미디어 표현식을 얻을 수 있습니다:
/* 입력 */
@media screen(sm) {
/* ... */
}
/* 출력 */
@media (min-width: 640px) {
/* ... */
}
이 기능을 직접 사용할 일은 거의 없겠지만, @media
를 이해하지만 @screen
을 제대로 처리하지 못하는 다른 도구와 Tailwind를 통합할 때 유용할 수 있습니다.
@screen sm { /* ... */ }
@media screen(sm) { /* ... */ }
캐럿 색상 유틸리티
이 기능은 Just-in-Time 모드에서만 사용할 수 있습니다.
이제 새로운 caret-{color}
유틸리티를 사용해 폼 필드의 커서 색상을 설정할 수 있습니다:
<input class="caret-red-500" />
이 유틸리티는 tailwind.config.js
파일의 theme
섹션에서 caretColor
키를 사용해 커스터마이징할 수 있습니다.
배경 오리진 유틸리티
background-origin
속성을 위한 새로운 유틸리티를 추가했습니다. 이 유틸리티를 사용하면 엘리먼트의 배경이 테두리, 패딩 박스, 콘텐츠 상자 중 어디에 위치할지 제어할 수 있습니다.
<div
class="bg-origin-border p-4 border-4 border-dashed ..."
style="background-image: url(...)"
>
배경이 테두리 아래에 렌더링됩니다.
</div>
<div
class="bg-origin-padding p-4 border-4 border-dashed ..."
style="background-image: url(...)"
>
배경이 테두리 안쪽에 렌더링되지만 패딩 위에 위치합니다.
</div>
<div
class="bg-origin-content p-4 border-4 border-dashed ..."
style="background-image: url(...)"
>
배경이 패딩 안쪽에 렌더링되고 콘텐츠 아래에 위치합니다.
</div>
더 자세한 내용은 배경 오리진 문서에서 확인할 수 있습니다.
간소화된 transform과 filter 합성
이 기능은 Just-in-Time 모드에서만 사용할 수 있습니다.
transform
, filter
, 그리고 backdrop-filter
클래스는 더 이상 각각의 합성 가능한 유틸리티를 “활성화”하기 위해 필요하지 않습니다.
<div class="transform scale-50 filter grayscale backdrop-filter backdrop-blur-sm">
<div class="scale-50 grayscale backdrop-blur-sm">
이제 이러한 기능들은 관련 하위 유틸리티를 사용할 때 자동으로 활성화됩니다.
하지만 이러한 유틸리티가 더 이상 필요하지 않기 때문에, transform과 filter가 기본적으로 “비활성” 상태일 것이라고 기대할 수 없다는 점을 이해하는 것이 중요합니다. 만약 이러한 클래스를 토글하여 transform이나 filter를 조건부로 “활성화”하는 방식에 의존하고 있었다면, 이제는 하위 유틸리티 자체를 토글해야 합니다.
<div class="scale-105 -translate-y-1 hover:transform">
<div class="hover:scale-105 hover:-translate-y-1">
대부분의 사람들에게는 실제 문제가 되지 않을 것으로 예상하지만, 기술적으로는 호환성이 깨지는 변경 사항이기 때문에 이 개선 사항을 JIT 엔진에만 적용했습니다.
각 면별 테두리 색상 유틸리티
이 기능은 Just-in-Time 모드에서만 사용할 수 있습니다.
지난 4년 동안 매달 최소 한 번씩 요청되었던 기능인데, 이제 개발 스타일시트 크기를 걱정할 필요가 없어져서 드디어 각 면별 테두리 색상 지원을 추가했습니다.
<div
class="border-2 border-t-blue-500 border-r-pink-500 border-b-green-500 border-l-yellow-500"
>
<!-- ... -->
</div>
이제 마음껏 못생긴 웹사이트를 만들어 보세요! (농담입니다, 농담. 유용하다는 걸 알지만 진정하세요.)
내장된 safelist, transform, extract 지원
우리는 PurgeCSS의 중요한 기능들을 퍼스트클래스로 지원하도록 추가했고, 이 기능들을 JIT 엔진에서도 작동하도록 만들었습니다. JIT 엔진은 사실 PurgeCSS를 사용하지 않습니다.
첫 번째는 safelist
입니다. 이 기능은 데이터베이스나 유사한 곳에서 가져온 콘텐츠에 사용되는 특정 클래스가 프로덕션 CSS에서 제거되지 않도록 보호해야 할 때 매우 유용합니다.
module.exports = {
purge: {
content: ['./src/**/*.html'],
safelist: [
'bg-blue-500',
'text-center',
'hover:opacity-100',
// ...
'lg:text-right',
],
},
// ...
}
클래식 엔진은 여기서 정규 표현식을 허용하지만, JIT 엔진은 허용하지 않습니다. 이는 클래스를 요청 시 생성할 때, 클래스가 사용되기 전까지는 존재하지 않기 때문에 정규 표현식과 매칭할 대상이 없기 때문입니다. 따라서 JIT 모드를 사용 중이라면, 예상한 결과를 얻기 위해 완전한 클래스 이름을 제공해야 합니다.
다음은 transform
입니다. 이 기능은 파일 확장자에 따라 콘텐츠를 변환한 후, 잠재적인 클래스 이름을 스캔할 수 있게 해줍니다.
let remark = require('remark')
module.exports = {
purge: {
content: ['./src/**/*.{html,md}'],
transform: {
md: (content) => {
return remark().process(content)
},
},
},
// ...
}
이 기능은 Markdown처럼 HTML로 컴파일되는 언어로 작성된 템플릿이 있을 때 매우 유용합니다.
마지막으로 extract
가 있습니다. 이 기능은 특정 파일 타입에서 클래스 이름을 감지하는 로직을 커스터마이징할 수 있게 해줍니다.
module.exports = {
purge: {
content: ['./src/**/*.{html,md}'],
extract: {
pug: (content) => {
return /[^<>"'`\s]*/.match(content)
},
},
},
// ...
}
이 기능은 고급 기능이며, 대부분의 사용자에게는 필요하지 않습니다. Tailwind의 기본 추출 로직은 거의 모든 프로젝트에서 매우 잘 작동합니다.
이 기능들에 대한 더 자세한 정보는 프로덕션 최적화 문서를 참고하세요.
업그레이드
Tailwind CSS v2.2로 업그레이드하려면 npm에서 최신 버전을 설치하세요:
npm install -D tailwindcss@latest
Just-in-Time 모드 미리보기를 사용 중이라면, 릴리스 노트의 변경 사항 및 폐기 예정 기능도 확인해 보세요.
업그레이드할 준비가 되셨나요? npm에서 다운로드 →