「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > Tailwind を設計システムとして構成する

Tailwind を設計システムとして構成する

2024 年 11 月 6 日に公開
ブラウズ:740

デザインシステムでは、一貫性と理解がすべてです。優れた設計システムは、それを実装するコードの構成を通じて実装の一貫性を保証します。それは次のようにする必要があります:

  • 優れたデザインに必要なニュアンスを無視することなく理解しやすい;
  • 一貫性を損なうことなくスケーラブルで保守可能。

Tailwind で React のデフォルトのスタックを使用して、タイポグラフィ、色、間隔の独自のデフォルトを設定することが、アプリの外観と操作性を差別化するための単なる開始点ではないことを説明します。さらに重要なことは、作成および保守しなければならないコードが大幅に削減され、体系的で一貫性があり、エラーのない方法でスタイルを実装する際の精神的負担が軽減されることです。

私が常に目にする大きな批判から始めて、それを解決するために私が使用する一連の設定手順を詳しく説明します。

使いやすさは知識の容易さとは一致しません

Tailwind を使用すると、開発者はスタイルを簡単に作成できるため、ラピッド プロトタイピングに最適です。しかし、その容易さは、優れた設計やスケーラブルで保守可能な設計システムを保証するものではありません。

デフォルトと Tailwind のようなゼロ構成ツールは、構築により多くの時間を生み出すインフラストラクチャ ペース レイヤーです。しかし、差別化を図るためにデザイン システムを使用するアプリを拡張する場合、「ランチのように無料」のすぐに使える構成だけに依存することはできません。

デフォルトの Tailwind 構成で実行し、スタイル管理をコンポーネント上のクラスのアプリケーションにプッシュすると、その結果、多くの場合、デザイン システムを装った、推論が困難なクラスがコンポーネント全体に分散した混乱が生じます。

Configuring Tailwind as a Design System

上記はその代表的な例です。ほとんど判読できず、操作することはおろか、理解するのにもかなりの時間がかかります。そうしようとすると、重複やエラーが発生する可能性が高く、アプリ全体のデザインの一貫性が損なわれます。

設計クラスを単一の className に押し込むのは簡単です。しかし、そうすることで知識を得るのは簡単ではありません。

理解しやすいようにシステムを構成する

使いやすさにはトレードオフが伴います。他人の標準を使用するということは、その人のノウハウに依存することを意味します。これは有益なこともありますが、罠になることもあります。一歩下がって、デザイン システムの基本が何で構成されているか考えてみましょう:

  • タイポグラフィ
  • 間隔
  • 応答性 (カラー モードを含む)

Tailwind を使用した React のコンテキストでは、これらおよび他の多くのデザイン システム要素が 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 を使用すると、フォント サイズ、行の高さ、文字間隔が設定されるようになりました。コアの文字体裁タプルを 1 つのクラスにまとめることで、これらの値の実装がコードベース全体ではなく構成に集中化されます。保守性が大幅に向上しました。

/* 13px/1.5 with 0.015em letter-spacing */

色のデフォルト

CSS 変数を使用して、:root および html.dark スコープでレスポンシブ カラーを設定できます。これは、bg-gray-100 dark:bg-gray-800 などの 2 つのクラスではなく、bg-canvas などの 1 つのクラスを作成して管理することを意味します。

@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);
}

ここでは基数カラーを使用しているため、.dark スコープを設定する必要はありません。すでに設定されているためです。基数カラーが気に入らない場合は、カスタマイズしたり、別のライブラリを使用したり、独自のライブラリを作成したりできます。

次に、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 */

セマンティックな命名

私は色とフォント サイズにセマンティックな名前を付けることを提唱しています。なぜなら、セマンティックな名前付けは意味と使用を結び付ける強制的な機能だからです。そうすることで実装の推測作業がなくなり、エラーが減ります。

一貫性のないグレー 50、グレー 100、またはグレー 200 がすべて背景に使用されているプロジェクトを数え切れないほど見てきました。これは、背景と呼ばれる色を定義することで簡単に解決できます。

同様に、暗いテキストの色と明るいテキストの色の名前も、塗りつぶしと塗りつぶしと呼ぶと覚えやすくなります。グレー 900 とグレー 600 と呼ばれる場合は、グレー 950 とグレー 500、またはグレー 800 とグレー 700 ではないことを特に覚えておく必要があるため、より難しく、間違いが発生しやすくなります。

しかし、物事に名前を付けること、そして名前に同意することは難しいです。ゼロ構成の精神に基づいて、Radix Color の背景、境界線、ソリッド、塗りつぶしのパラダイムを採用することをお勧めします。または、このパレットのセマンティクス。

これを tailwind.config で設定すると、Typescript はオートコンプリートを使用してすぐに記憶を呼び起こします。

名前空間の衝突を避ける

Tailwind テーマを拡張し、独自のテーマを作成していない場合は、すでに使用されているスケール キーを使用しないでください。使用する必要があるクラスを誤って上書きしてしまう可能性があります。

前のカラー設定の例では、--color-gray-base 変数をbaseではなくcanvasに設定​​していることがわかります。 Base を使用した場合、このカラー スケールをテキスト カラー (text-base) として使用すると、デフォルトのフォント サイズのベース値 (同じく text-base.

) と衝突します。

これは、Tailwind 構成のカスタマイズの失敗ではなく、そのテーマの名前付けの遺産です。Tailwind でのフォント サイズまたは色のクラスの設定は両方とも text-* を使用します。1

間隔のデフォルト

CSS 変数を使用して間隔を設定することもできます。

: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)",
}

これはオーバーエンジニアリングであると主張する人もいるかもしれません。ただし、スティッキー ヘッダーやスクロール マージンなどの複雑なインタラクティブ レイアウトを計算するときを除いて、この事前設定作業により、ピクセルまでの処理が簡単かつエラーなく行われます。

/* ... */

セマンティックな名前を使用すると、覚えやすく、使いやすくなります。

Tailwind 構成を拡張する

タイポグラフィ、色、間隔のトークンを、理解しやすく、一元化された場所で管理しやすい方法で構成できるようになりました。また、システムを実装するために多くのクラスを作成する必要もありません。勝ちました。そして、この実装のオーバーヘッドを削減するために実行できるさらなる手順があります。

クラスを Clamp()

どこにでも text-lg lg:text-xl xl:text-2xl p-2 md:p-4 lg:p-8 を書くことを完全に避ける方法があると言ったらどうしますか?

tailwind.config のフォント サイズ値としてクランプを使用することで、レスポンシブなフォント サイズ クラスの設定を回避できます。これが私が使用する単純なクランプ関数です。

fontSize: {
  title: [
    /* clamp(17px, 14.1429px   0.5714vw, 21px) */
    generateClampSize(500, 1200, 17, 21),
    { lineHeight: 1.5, letterSpacing: "-0.015em" },
  ];
}

したがって、text-lg lg:text-xl xl:text-2xl と書く代わりに、単に text-title と書くことができます。もう一度、フォント サイズの応答性をクランプ値に引き上げることで、「クラスの実装」の落とし穴を再び回避し、精神的な労力、エラー、デバッグ時間を節約します。

これは、Tailwind を適切に構成することで、text-lg lg:text-xl xl:text-2xl leading-none tracking-wide から text-title に移行したことを意味することに注意してください。勝ちました!

/* 17px at 500px, 21px at 1200, fluidly calculated inbetween */
/* …with default line-height and letter-spacing also specified */

Heading copy

間隔についてもこれを行うことができます。テーマを拡張する場合、デフォルトの間隔スケールと区別するために、これらのキーの前に「動的」を表す d を付けます。

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),
}

これにより、py-16 md:py-20 lg:py-24 の代わりに py-d24 を書くことができます。これにより、メディア クエリごとにさまざまな Web サイトのバージョンを頭の中に保持しておく負担が軽減されます。代わりに、一貫した関係性ほど測定値は重要ではない、流動的に応答するレイアウトをイメージすることを奨励します。

/* ... */
/* ... */

まとめ

巧みに作られた UI は、今後の不用意な AI アプリの波に対する最後の防御策となります。 Tailwind をカスタマイズすると時間と頭痛の種がどのように節約され、瞬く間に機能する UI を構築するために必要な不合理な量の注意に集中できるようになります:

  • tailwind.config を最大限に活用してください。設計トークンを一元化してグループ化し、「どこにでもクラスを実装する」という罠を回避します。
  • 流動的なタイポグラフィとスペースには、clamp() を使用します。
  • ダークモードを簡単に行うために、:root と .dark にカラー変数を設定します。
  • 意味的に色と間隔に名前を付けます。いつでも背景はグレー 100 を上回ります。
  • size-em を使用してアイコンをテキスト サイズに関連付けます。

はい、前払い料金がかかります。しかし、コードが減り、エラーが減り、設計の一貫性が高まり、チームがシステムを実際に理解できるようになり、その効果は十分にあります。

次は、Class Variance Authority を使用して、Tailwind から抽出されたセマンティック プロップを備えた完全なスタイリング API を作成する方法を検討します。乞うご期待。


  1. これが、JSX で重複する Tailwind クラスを削除するために tailwind-merge を使用するのが嫌いな理由でもあります。多くの場合、両方が必要な場合、text-fontSize を優先して text-color が削除されることがわかります。この問題を提起しない開発者が増えていることに驚いています。 ↩

リリースステートメント この記事は次の場所に転載されています: https://dev.to/callumflack/cconfiguring-tailwind-as-a-design-system-2f5h?1 侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3