디자인 시스템에서는 일관성과 이해력이 가장 중요합니다. 좋은 디자인 시스템은 이를 구현하는 코드 구성을 통해 구현의 일관성을 보장합니다. 다음과 같아야 합니다.
Tailwind와 함께 내 기본 React 스택을 사용하여 타이포그래피, 색상 및 간격에 대한 고유한 기본값을 설정하는 것이 앱의 모양과 느낌을 차별화하기 위한 시작점이 아니라는 점을 보여 드리겠습니다. 더 중요한 것은 작성하고 유지 관리해야 하는 코드를 대폭 줄여 체계적이고 일관되며 오류 없는 방식으로 스타일을 구현하는 데 따른 정신적 부담을 줄여준다는 것입니다.
항상 볼 수 있는 주요 비판부터 시작하여 이를 해결하기 위해 사용하는 일련의 구성 단계를 분석하겠습니다.
Tailwind를 사용하면 개발자가 스타일을 쉽게 작성할 수 있어 신속한 프로토타이핑에 적합합니다. 그러나 이러한 용이성이 좋은 디자인이나 확장 가능하고 유지 관리 가능한 디자인 시스템을 보장하지는 않습니다.
Tailwind와 같은 기본값 및 구성이 필요 없는 도구는 구축 시간을 더 많이 만들어 주는 인프라 속도 계층입니다. 하지만 차별화를 위해 디자인 시스템을 사용하는 앱을 확장하는 경우에는 "점심 시간에 무료로 제공되는" 기본 구성에만 의존할 수는 없습니다.
기본 Tailwind 구성을 사용하여 실행하고 구성 요소의 클래스 애플리케이션에 스타일 관리를 푸시하면 결과적으로 디자인 시스템으로 가장하여 구성 요소 전체에 흩어져 있는 추론하기 어려운 클래스가 엉망이 되는 경우가 많습니다.
위는 대표적인 예입니다. 거의 읽을 수 없으며 조작은커녕 이해하는 데 상당한 시간이 걸립니다. 그렇게 하면 중복과 오류가 발생하여 앱 전체의 디자인 일관성이 무너질 가능성이 높습니다.
디자인 클래스를 단일 className으로 묶는 것은 쉽습니다. 하지만 그렇게 하는 데에는 지식이 쉽지 않습니다.
사용 편의성에는 절충점이 따릅니다. 다른 사람의 기준을 따른다는 것은 그 사람의 노하우에 의존한다는 뜻이다. 이는 유익할 수도 있지만 함정이 될 수도 있습니다. 한발 물러서서 디자인 시스템의 기본이 무엇으로 구성되어 있는지 생각해 봅시다:
React with Tailwind의 맥락에서 이러한 요소와 기타 여러 디자인 시스템 요소는 Tailwind 구성에 설정되어 있으며 이를 사용자 정의할 수 있습니다.
{/* 더 예쁘다-무시 */}
const config = { theme: { fontSize: { /* ... */ }, colors: { /* ... */ }, spacing: { /* ... */ }, }, };
작은 텍스트의 올바른 글자 간격을 기억하는 데 어려움을 겪은 적이 있습니까? 한 번 설정하고 잊어버릴 수 있다면 어떨까요?
tailwind.config에서 직접 각 글꼴 크기 튜플에 대한 매개변수로 행간(줄 높이) 및 자간(문자 간격)을 설정할 수 있습니다. 즉, 글꼴 크기 클래스를 사용할 때 행간 또는 추적을 설정할 필요가 없습니다. 작은 텍스트의 글자 간격이 무엇인지 기억할 필요가 없습니다(또는 검색하지 않아도 됨).
fontSize: { small: [ "13px", { lineHeight: 1.5, letterSpacing: "0.015em" }, ], base: [ "16px", { lineHeight: 1.5, letterSpacing: 0 }, ], }
이제 text-small을 사용하면 글꼴 크기, 줄 높이 및 문자 간격이 설정됩니다. 핵심 인쇄 튜플을 하나의 클래스에 함께 포함하면 이러한 값의 구현이 코드베이스 전체가 아닌 구성으로 중앙 집중화됩니다. 유지 관리 측면에서 큰 승리를 거두었습니다.
/* 13px/1.5 with 0.015em letter-spacing */ <div className="text-small" />
CSS 변수를 사용하여 :root 및 html.dark 범위에서 반응형 색상을 설정할 수 있습니다. 이는 bg-gray-100 dark:bg-gray-800과 같은 두 개의 클래스 대신 bg-canvas와 같은 하나의 클래스를 작성하고 관리한다는 의미입니다.
@import "@radix-ui/colors/gray.css"; @import "@radix-ui/colors/gray-dark.css"; :root { --color-gray-base: var(--gray-1); --color-gray-bg: var(--gray-3); --color-gray-line: var(--gray-4); --color-gray-border: var(--gray-5); --color-gray-solid: var(--gray-10); --color-gray-fill: var(--gray-12); }
여기에서는 Radix Colors를 사용하고 있으므로 .dark 범위가 이미 설정되어 있으므로 설정할 필요가 없습니다. Radix 색상이 마음에 들지 않으면 맞춤설정하거나 다른 라이브러리를 사용하거나 직접 작성할 수 있습니다.
그런 다음 Tailwind 구성에서 CSS 변수를 설정하세요.
colors: { canvas: "var(--color-gray-base)", background: "var(--color-gray-bg)", line: "var(--color-gray-line)", border: "var(--color-gray-border)", solid: "var(--color-gray-solid)", fill: "var(--color-gray-fill-contrast)", }
이제 bg-canvas를 사용하면 밝은 모드 또는 어두운 모드에서 적절한 색상이 설정됩니다. 코드베이스 전체에서 이러한 중복을 제거하면 색상 관리를 구성 요소의 클래스 구현 전체에 분산시키는 대신 구성에 중앙 집중화합니다. 인지도와 유지 관리 측면에서 큰 승리를 거두었습니다.
/* sets --gray-1 as #fcfcfc on :root or #111111 on html.dark */ <div className="bg-canvas" />
저는 의미론적 이름을 사용하기 위해 의미를 묶는 강제 기능이기 때문에 색상과 글꼴 크기에 의미론적 이름을 옹호합니다. 이렇게 하면 구현 추측 작업이 제거되고 오류가 줄어듭니다.
일관되지 않은 회색-50, 회색-100 또는 회색-200이 모두 배경에 사용되는 수많은 프로젝트를 보았습니다. 이는 배경이라는 색상을 정의하면 쉽게 해결됩니다.
In the same way, it is easier to remember the names for dark and light text colors when they are called fill and solid. It's harder and more error-prone when they're called gray-900 and gray-600 because then you have to remember specifically that it wasn't gray-950 and gray-500, or gray-800 and gray-700.
But naming things—and agreeing on naming—is hard. In the spirit of zero-config, I suggest taking Radix Color's backgrounds, borders, solids & fills paradigm. Or this palette semantics.
And once you've set this in tailwind.config, Typescript will jog your memory at your fingertips with autocomplete.
If you're extending a Tailwind theme and not writing your own, don't use a scale key that's already been used. You may inadvertently overwrite a class that you need to use.
You'll note in the previous colour config example that I set the --color-gray-base var to canvas, not base. If I used base then using this color scale as a text colour (text-base) would clash with the default font-size base value, which is also text-base.
This isn't a downfall of customising the Tailwind config, it's a legacy of its theme naming: setting font-size or color classes in Tailwind both use text-*.1
We can also use CSS variables to set spacings.
:root { --height-nav: 80px; --height-tab: 54px; --space-inset: 20px; --container-text-px: 660px; --container-hero-px: 1000px; }
spacing: { em: "1em", /* relate icon size to parent font-size */ nav: "var(--height-nav)", inset: "var(--space-inset)", text: "var(--container-text)", hero: "var(--container-hero)", }
One could argue this is over-engineering. Except that when it comes time to compute complex interactive layouts like sticky headers, scroll margins and so on, this upfront configuration work makes it straight forward and error-free, to the pixel.
<div className="top-[calc(theme(spacing.nav)+theme(spacing.tab))]"> <div className="scroll-mt-[calc(theme(spacing.nav)+theme(spacing.tab))]"> /* ... */ </div> </div>
Note again the use of semantic naming makes it easy to remember and use.
We have now configured typography, colour and spacing tokens in a manner that is easy to understand and maintain in a single, centralised place. And we don't need to wrire as many classes to implement the system. Winning. And there's further steps we can take to reduce this implementation overhead.
What if I told you there's a way to completely avoid writing text-lg lg:text-xl xl:text-2xl p-2 md:p-4 lg:p-8 everywhere?
We can avoid setting responsive font-size classes by using clamp as a a font-size value in tailwind.config. Here's the simple clamp function I use.
fontSize: { title: [ /* clamp(17px, 14.1429px + 0.5714vw, 21px) */ generateClampSize(500, 1200, 17, 21), { lineHeight: 1.5, letterSpacing: "-0.015em" }, ]; }
So instead of writing text-lg lg:text-xl xl:text-2xl we can just write text-title. Once again, by hoisting font-size responsiveness into a clamp value, we avoid the "implement classes" pitfall again, saving mental effort, errors and debugging time.
Keep in mind, this means we've moved from text-lg lg:text-xl xl:text-2xl leading-none tracking-wide to text-title by properly configuring Tailwind. Winning!
/* 17px at 500px, 21px at 1200, fluidly calculated inbetween */ /* …with default line-height and letter-spacing also specified */ <h2 className="text-title"> Heading copy </h2>
We can also do this for spacing. When extending a theme, I prefix these keys with d for "dynamic" to differentiate it from the default spacing scale.
spacing: { /* lower value is 2/3 of upper value */ d4: generateClampSize(500, 1200, 10.5, 16), d8: generateClampSize(500, 1200, 21, 32), d16: generateClampSize(500, 1200, 43, 64), d24: generateClampSize(500, 1200, 64, 96), d64: generateClampSize(500, 1200, 171, 256), }
This allows us to write py-d24 instead of py-16 md:py-20 lg:py-24. This alleviates the weight of holding a range of website versions for each media-query in our minds. Instead it encourages us to picture fluidly responsive layouts where measurements don't matter as much as consistent relationships.
<main className="pt-d24 pb-d64 space-y-w8"> <header className="container max-w-hero space-y-1"> /* ... */ </header> <article className="container space-y-2"> /* ... */ </article> </main>
Well-crafted UI is your last defense against the coming slopwave of careless AI apps. Here's how customizing Tailwind can save you time and headaches so you can focus on the irrational amount of care it takes to build UI that works in the blink of an eye:
Yes, there's an upfront time cost. But it pays off in spades: less code, fewer errors, greater design consistency, and a team that actually understands the system.
Next up: We'll explore how to use Class Variance Authority to create a bulletproof styling API with semantic props drawn from Tailwind. Stay tuned.
This is also why I dislike using tailwind-merge to remove duplicate Tailwind classes in JSX. More often than not, I find it removing a text-color in favour of a text-fontSize when both are needed. I'm surprised more developers don't raise this issue. ↩
위 내용은 Tailwind를 디자인 시스템으로 구성의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!