Tailwind CSS v3.4: 동적 뷰포트 단위, :has() 지원, 균형 잡힌 헤드라인, 서브그리드 등

Adam Wathan
Tailwind CSS v3.4

자신의 도구에 추가하고 싶은 기능을 찾기 위해 주요 신제품을 개발하는 것만큼 좋은 방법은 없습니다. 그래서 우리는 그 영감을 활용해 Tailwind CSS v3.4를 만들었습니다.

항상 그렇듯이, 이번 개선 사항들은 여러분이 수년 동안 불편해했던 것부터, 아직 들어보지도 못했고 직장에서 사용할 수도 없는 CSS 기능까지 다양합니다.

모든 좋은 기능들이 이 목록에 있지만, 이 글에 포함되지 못한 몇 가지 세부 사항은 릴리스 노트에서 확인하세요.

프로젝트를 업그레이드하려면 npm에서 최신 버전의 tailwindcss를 설치하세요:

npm install tailwindcss@latest

또는 브라우저에서 바로 Tailwind Play를 통해 모든 새로운 기능을 시험해 보세요.


동적 뷰포트 단위

vh 단위가 브라우저에 추가되었을 때, 우리 모두는 매우 기뻤습니다. 드디어 DOM의 17개 레이어를 거치며 height: 100%를 설정하지 않고도 전체 높이의 애플리케이션 레이아웃을 만들 수 있게 되었기 때문입니다. 하지만 모바일 기기와 그들의 사라지는 메뉴 바가 모든 재미를 망쳐버렸고, vh 단위는 그렇게 좋을 수 있었던 미래를 잔인하게 상기시키는 존재가 되었습니다.

이제 우리는 새로운 미래를 맞이했습니다. dvh, lvh, 그리고 svh는 사라지는 브라우저 UI를 고려하여 설계되었으며, Tailwind CSS v3.4는 이를 기본적으로 지원합니다.

뷰포트에서 위아래로 스크롤하여 브라우저 UI를 숨기거나 표시하세요

tailwindcss.com

h-dvh

<div class="h-dvh">  <!-- ... --></div>

기본적으로 다음과 같은 새로운 클래스들이 추가되었습니다:

클래스CSS
h-svhheight: 100svh
h-lvhheight: 100lvh
h-dvhheight: 100dvh
min-h-svhmin-height: 100svh
min-h-lvhmin-height: 100lvh
min-h-dvhmin-height: 100dvh
max-h-svhmax-height: 100svh
max-h-lvhmax-height: 100lvh
max-h-dvhmax-height: 100dvh

다른 값이 필요하다면, min-h-[75dvh]와 같은 임의의 값을 사용할 수도 있습니다.

이러한 단위들은 브라우저 지원이 매우 좋기 때문에, Safari 14를 지원할 필요가 없다면 지금 바로 사용할 수 있습니다.


새로운 :has() 변형

:has() 의사 클래스는 플렉스 박스 이후로 CSS에 추가된 가장 강력한 기능입니다. 이제 처음으로 부모 요소가 아닌 자식 요소를 기반으로 스타일을 적용할 수 있습니다. 심지어 뒤에 오는 형제 요소를 기반으로 스타일을 적용하는 것도 가능합니다.

다음은 라디오 버튼이 체크되면 부모 요소에 색상이 있는 테두리가 적용되는 예제입니다:

Payment method
<label class="has-[:checked]:bg-indigo-50 has-[:checked]:text-indigo-900 has-[:checked]:ring-indigo-500 ...">  <svg fill="currentColor">    <!-- ... -->  </svg>  Google Pay  <input type="radio" class="accent-indigo-500 ..." /></label>

지난 몇 달 동안 새 UI 키트를 만들면서 매주 :has()의 새로운 사용 사례를 발견하고 있습니다. 이 기능은 우리 코드에서 엄청난 양의 자바스크립트를 대체했습니다.

예를 들어, 텍스트 입력 필드는 디자인적으로 꽤 복잡해서 작은 래퍼 엘리먼트가 필요합니다. :has()가 없으면 입력 필드의 :disabled 상태 같은 것에 따라 래퍼를 스타일링할 방법이 없었지만, 이제는 가능해졌습니다:

input.jsx
export function Input({ ... }) {  return (    <span className="has-[:disabled]:opacity-50 ...">      <input ... />    </span>  )}

이 기능은 아주 최신 기술이지만, 오늘 기준으로 모든 주요 브라우저의 최신 버전에서 지원됩니다. Firefox 사용자들이 오늘 업데이트를 설치하는 데 몇 주 정도 걸릴 수 있으니, 그 후에는 마음껏 사용할 수 있을 겁니다.


* 변형으로 자식 요소 스타일링하기

오랫동안 요청받아 왔던 기능이 드디어 추가되었습니다. 부모 요소에서 유틸리티 클래스를 사용해 자식 요소를 스타일링할 수 있는 방법입니다.

직접적인 자식 요소를 대상으로 하는 새로운 * 변형을 추가했습니다. 이를 통해 다음과 같은 작업을 할 수 있습니다.

Categories

Sales
Marketing
SEO
Analytics
Design
Strategy
Security
Growth
Mobile
UX/UI
<div>  <h2>Categories:<h2>  <ul class="*:rounded-full *:border *:border-sky-100 *:bg-sky-50 *:px-2 *:py-0.5 dark:text-sky-300 dark:*:border-sky-500/15 dark:*:bg-sky-500/10 ...">    <li>Sales</li>    <li>Marketing</li>    <li>SEO</li>    <!-- ... -->  </ul></div>

일반적으로는 자식 요소를 직접 스타일링하는 것을 권장하지만, 해당 요소를 제어할 수 없거나 요소가 사용되는 컨텍스트 때문에 조건부로 조정이 필요한 경우에 유용할 수 있습니다.

이 기능은 다른 변형과도 조합할 수 있습니다. 예를 들어 hover:*:underline은 자식 요소에 마우스를 올렸을 때 스타일을 적용합니다.

새로운 UI 키트에서 다양한 자식 요소에 조건부로 레이아웃 스타일을 추가하는 멋진 방법을 소개합니다.

JSX
function Field({ children }) {  return (    <div className="data-[slot=description]:*:mt-4 ...">      {children}    </div>  )}function Description({ children }) {  return (    <p data-slot="description" ...>{children}</p>  )}function Example() {  return (    <Field>      <Label>First name</Label>      <Input />      <Description>Please tell me you know your own name.</Description>    </Field>  )}

data-[slot=description]:*:mt-4 클래스를 보세요. 먼저 모든 직접적인 자식 요소를 대상으로 하고(*: 부분), 그 중에서 data-slot="description" 속성을 가진 요소만 필터링합니다(data-[slot=description]).

이를 통해 특정 자식 요소만 쉽게 대상으로 할 수 있으며, 임의의 변형을 사용할 필요가 없습니다.

이 기능을 추가한 것을 후회하게 만들 만한 끔찍한 작업들을 기대합니다.

새로운 size-* 유틸리티

아바타 크기를 조정할 때마다 h-5 w-5를 입력하는 것이 지겹다면, 여러분도 알고 있고 저도 알고 있습니다.

Tailwind CSS v3.4에서는 이제 size-* 유틸리티를 추가하여 너비와 높이를 동시에 설정할 수 있습니다:

HTML
<div>  <img class="h-10 w-10" ...>  <img class="h-12 w-12" ...>  <img class="h-14 w-14" ...>  <img class="size-10" ...>  <img class="size-12" ...>  <img class="size-14" ...></div>

이 기능을 추가하고 싶었지만 항상 정확한 이름에 대해 고민했습니다. size-*w-*h-*에 비해 입력해야 할 글자 수가 많았고, s-*는 너무 암호처럼 느껴졌습니다.

하지만 몇 주 동안 사용해 본 결과, 더 긴 이름에도 불구하고 별도의 너비와 높이 유틸리티보다 훨씬 낫다는 결론을 내렸습니다. 특히 변형과 결합하거나 복잡한 임의 값을 사용할 때 매우 편리합니다.


text-wrap 유틸리티로 균형 잡힌 헤드라인 만들기

랜딩 페이지에서 작은 섹션 헤드라인이 잘 줄바꿈되도록 max-width를 조정하거나 반응형 줄바꿈을 추가하는 데 얼마나 많은 시간을 보냈나요? 이제는 그런 작업에 시간을 들일 필요가 없습니다. 브라우저가 text-wrap: balance를 통해 이를 대신해 줄 수 있기 때문입니다.

Beloved Manhattan soup stand closes

New Yorkers are facing the winter chill with less warmth this year as the city's most revered soup stand unexpectedly shutters, following a series of events that have left the community puzzled.

<article>  <h3 class="text-balance ...">Beloved Manhattan soup stand closes<h3>  <p>New Yorkers are facing the winter chill...</p></article>

또한 text-pretty를 추가했습니다. 이 기능은 text-wrap: pretty를 사용하여 단락 끝에 혼자 남는 단어를 피하려고 합니다.

Beloved Manhattan soup stand closes

New Yorkers are facing the winter chill with less warmth this year as the city's most revered soup stand unexpectedly shutters, following a series of events that have left the community puzzled.

<article class="text-pretty ...">  <h3>Beloved Manhattan soup stand closes<h3>  <p>New Yorkers are facing the winter chill...</p></article>

이 기능의 좋은 점은 오래된 브라우저로 사이트를 방문하는 사용자가 있어도 일반적인 줄바꿈 동작으로 대체되기 때문에, 지금 바로 사용해도 안전하다는 것입니다.


서브그리드 지원

서브그리드는 비교적 최근에 추가된 CSS 기능으로, 엘리먼트가 부모의 그리드 컬럼이나 행을 상속받아 자식 엘리먼트를 부모 그리드에 배치할 수 있게 해줍니다.

<div class="grid grid-cols-4 gap-4">  <!-- ... -->  <div class="col-span-3 grid grid-cols-subgrid gap-4">    <div class="col-start-2">06</div>  </div>  <!-- ... --></div>

예를 들어, 우리가 작업 중인 새로운 UI 키트에서 드롭다운 메뉴에 서브그리드를 사용하고 있습니다. 이렇게 하면 아이콘이 있는 항목이 있을 때 다른 모든 항목이 들여쓰기되어 텍스트가 정렬됩니다.

<div role="menu" class="grid grid-cols-[auto_1fr]">  <a href="#" class="col-span-2 grid-cols-subgrid">    <svg class="mr-2">...</svg>    <span class="col-start-2">Account</span>  </a>  <a href="#" class="col-span-2 grid-cols-subgrid">    <svg class="mr-2">...</svg>    <span class="col-start-2">Settings</span>  </a>  <a href="#" class="col-span-2 grid-cols-subgrid">    <span class="col-start-2">Sign out</span>  </a></div>

아이콘이 없는 항목이 있을 때는 첫 번째 컬럼이 0px로 줄어들고 텍스트가 왼쪽으로 정렬됩니다.

더 자세한 내용은 MDN의 서브그리드 문서를 참고하세요. 처음에는 이해하기 어려울 수 있지만, 한번 이해하면 게임 체인저가 될 것입니다.


확장된 min-width, max-width, min-height 스케일

드디어 min-width, max-width, min-height 스케일을 전체 간격 스케일로 확장했습니다. 이제 min-w-12 같은 클래스가 실제로 사용 가능합니다:

HTML
<div class="min-w-12">  <!-- ... --></div>

이 작업을 v3.0에 포함시켰어야 했지만, 시간이 없어 미뤄졌습니다. 미안하고, 고마워하세요.

확장된 투명도 스케일

기본적으로 5단계마다 모든 단계를 포함하도록 투명도 스케일을 확장했습니다:

HTML
<div class="opacity-35">  <!-- ... --></div>

이제 마크업에서 임의의 값을 덜 사용할 수 있길 바랍니다. 다음은 2.5%를 노리고 있습니다.

확장된 grid-rows-* 스케일

기본 제공되는 그리드 행의 수를 6에서 12로 늘렸습니다. 이유는 간단합니다: 그냥 해봤어요.

HTML
<div class="grid grid-rows-9">  <!-- ... --></div>

다음 릴리스에서는 더 과감하게 16까지 늘릴지도 모릅니다.

새로운 forced-colors 변형

강제 색상 모드(forced colors mode)에 대해 들어본 적이 있나요? 여러분의 사이트가 이 모드에서 상당히 이상하게 보일 수 있습니다.

이제는 적어도 우리를 탓할 수 없게 되었습니다. Tailwind CSS v3.4에는 강제 색상 모드를 위한 스타일을 조정할 수 있는 forced-colors 변형이 포함되었기 때문입니다:

HTML
<form>  <input type="checkbox" class="appearance-none forced-colors:appearance-auto ..." /></form>

이 기능은 완전히 커스텀한 컨트롤을 미세 조정하는 데 매우 유용하며, 특히 임의 값과 CSS 시스템 색상에 대한 지식과 결합할 때 더욱 그렇습니다.


새로운 forced-color-adjust 유틸리티

강제 색상 모드가 디자인에 미치는 영향을 제어하기 위해 새로운 forced-color-adjust-autoforced-color-adjust-none 유틸리티를 추가했습니다:

HTML
<fieldset>  <legend>색상 선택</legend>  <div class="forced-color-adjust-none ...">    <label>      <input class="sr-only" type="radio" name="color-choice" value="white" />      <span class="sr-only">흰색</span>      <span class="size-6 rounded-full bg-white"></span>    </label>    <label>      <input class="sr-only" type="radio" name="color-choice" value="gray" />      <span class="sr-only">회색</span>      <span class="size-6 rounded-full bg-gray-300"></span>    </label>    <!-- ... -->  </div></fieldset>

이 유틸리티는 꼭 필요한 경우에만 사용해야 하지만, 온라인 상점에서 구매하는 물건의 색상을 선택하는 것처럼 특정 색상으로 렌더링되어야 하는 경우에 유용할 수 있습니다.

강제 색상에 대해 더 자세히 알고 싶다면, Polypane 블로그의 "강제 색상 설명: 실용 가이드"를 읽어보는 것을 추천합니다. 이 주제에 대해 가장 유용한 글 중 하나입니다.


주의 깊게 지켜본 분이라면, 올여름 Tailwind Connect에서 미리 보여준 Oxide 엔진 개선 사항에 대해 궁금해할 수 있습니다.

원래 이 개선 사항은 v3.4에 포함될 예정이었지만, 몇 가지 해결해야 할 문제가 남아 있고 다른 많은 개선 사항들이 쌓여 있어서 이를 모두 출시하는 것이 더 합리적이라고 판단했습니다. Oxide 관련 기능은 여전히 진행 중이며, 새해에 출시될 다음 Tailwind CSS 버전의 주요 개선 사항이 될 것입니다.

그동안, npm을 통해 최신 버전으로 업데이트하여 Tailwind CSS v3.4를 사용해보세요:

$ npm install tailwindcss@latest

:has()와 새로운 * 변형을 사용하면, HTML이 이전보다 더 복잡해질 것입니다.

모든 업데이트를 직접 받아 볼 수 있습니다.
뉴스레터에 가입하세요.