ユーティリティファースト

制約された単純なユーティリティのセットから複雑なコンポーネントを構築します。


Overview

従来のやり方だと、ウェブ上で何かをデザインする必要があるときはいつもCSSを書きますよね。

従来のやり方だと、デザインをカスタムするにはカスタムされたCSSが必要

ChitChat

You have a new message!

<div class="chat-notification">
  <div class="chat-notification-logo-wrapper">
    <img class="chat-notification-logo" src="/img/logo.svg" alt="ChitChat Logo">
  </div>
  <div class="chat-notification-content">
    <h4 class="chat-notification-title">ChitChat</h4>
    <p class="chat-notification-message">You have a new message!</p>
  </div>
</div>

<style>
  .chat-notification {
    display: flex;
    max-width: 24rem;
    margin: 0 auto;
    padding: 1.5rem;
    border-radius: 0.5rem;
    background-color: #fff;
    box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
  }
  .chat-notification-logo-wrapper {
    flex-shrink: 0;
  }
  .chat-notification-logo {
    height: 3rem;
    width: 3rem;
  }
  .chat-notification-content {
    margin-left: 1.5rem;
    padding-top: 0.25rem;
  }
  .chat-notification-title {
    color: #1a202c;
    font-size: 1.25rem;
    line-height: 1.25;
  }
  .chat-notification-message {
    color: #718096;
    font-size: 1rem;
    line-height: 1.5;
  }
</style>

Tailwindなら、既存のクラスを直接HTMLに適用することで要素のスタイルを設定できます。

ユーティリティクラスを使用して、CSSを記述せずにカスタムデザインを構築する

ChitChat

You have a new message!

<div class="max-w-sm mx-auto flex p-6 bg-white rounded-lg shadow-xl">
  <div class="flex-shrink-0">
    <img class="h-12 w-12" src="/img/logo.svg" alt="ChitChat Logo">
  </div>
  <div class="ml-6 pt-1">
    <h4 class="text-xl text-gray-900 leading-tight">ChitChat</h4>
    <p class="text-base text-gray-600 leading-normal">You have a new message!</p>
  </div>
</div>

上記の例で私達は:

  • 全体的なカードレイアウトをコントロールするためにflexboxpadding utilities (flex, flex-shrink-0, and p-6)を使用。
  • カードの横幅の制約と垂直方向にセンタリングするためにmax-widthmargin utilities (max-w-sm and mx-auto) を使用。
  • カードの見た目をデザインするためにbackground colorborder radius,とbox-shadow utilities (bg-white, rounded-lg, and shadow-xl) を使用。
  • ロゴを適切な大きさに整えるためにwidthheight utilities (w-12 and h-12)を使用。
  • カードのテキスト位置を整えるためにmarginpadding utilities (ml-6 and pt-1)を使用。
  • カードのテキストをデザインをするためにfont sizetext colorline-height utilities (text-xl, text-gray-900, leading-tight, etc.) を使用。

これらを使用することによって、独自のCSSを1行も記述せずに、完全にカスタムされたコンポーネント設計を実装できます。

今あなたはこのように考えているでしょう。「これは残虐行為だ!なんてひどい有様だ!」

こう考えるのは正しいですし、これは確かに少し醜いです。 実際、これを初めて見たときに良いアイデアだと考えるのはほぼ不可能です。実際に試してみる必要があります。

しかし、一度あなたが実際にこのやりかたで何かを構築したとき、あなたは重要ないくつかの利点に気づくはずです:

  • クラス名を考えるのに余計な労力を使う必要がない 何かをデザインするために sidebar-inner-wrapperというような愚かなクラス名を追加する必要はありません。 そして、単なるフレックスコンテナに対して、完璧で抽象的な名前を考えるのに悩まされることはもうありません。
  • CSSが肥大化しない 従来のやり方だと、新たな機能を追加するたびにCSSファイルは大きくなってしまいます。ユーティリティを使うことで、全ては再利用可能で新たなCSSを書く必要は滅多にありません。
  • 変更を加えるのが怖くない CSSはグローバルであり、変更を加えたときに何を壊しているのかがわかりません。HTMLのクラスはローカルであるため、他の何かが壊れることを心配せずにクラスを変更できます。

事前定義されたユーティリティクラスを使用してHTMLで排他的に作業できることを実感すると、他の方法で作業することは苦痛のように感じられます。


なぜインラインスタイルだけを使用しないのか?

このアプローチに対する一般的な反応は、「これは単なるインラインスタイルではないか」という疑問です。 ある意味では、それは正しいです。 あなたは要素にクラス名を割り当ててそのクラスのスタイルを設定するのではなく、要素に直接スタイルを適用しているのです。

しかし、ユーティリティクラスを使用することは、インラインスタイルに比べていくつかの重要な利点があります:

  • 制約付きのデザイン インラインスタイルを使用すると、すべての値がマジックナンバーになります。 ユーティリティを使用すると、事前定義されたdesign systemからスタイルを選択するため、視覚的に一貫性のあるUIを簡単に構築できます。
  • レスポンシブデザイン インラインスタイルではメディアクエリを使うことはできませんが、Tailwindのresponsive utilitiesを使えば簡単にレスポンシブなインターフェイスを構築することができます。
  • 疑似クラス インラインスタイルは、ホバーやフォーカスなどの状態をターゲットにすることはできません。しかしTailwindのpseudo-class variantsユーティリティクラスを使用して、これらの状態のスタイルを簡単に設定できます。

このコンポーネントは完全にレスポンシブで、ホバースタイルのボタンが含まれており、ユーティリティクラスで完全に構築されています。

Woman's Face

Erin Lindford

Product Engineer

<div class="max-w-sm mx-auto bg-white shadow-lg rounded-lg overflow-hidden">
  <div class="sm:flex sm:items-center px-6 py-4">
    <img class="block mx-auto sm:mx-0 sm:flex-shrink-0 h-16 sm:h-24 rounded-full" src="/img/erin-lindford.jpg" alt="Woman's Face">
    <div class="mt-4 sm:mt-0 sm:ml-4 text-center sm:text-left">
      <p class="text-xl leading-tight">Erin Lindford</p>
      <p class="text-sm leading-tight text-gray-600">Product Engineer</p>
      <div class="mt-4">
        <button class="text-purple-500 hover:text-white hover:bg-purple-500 border border-purple-500 text-xs font-semibold rounded-full px-4 py-1 leading-normal">Message</button>
      </div>
    </div>
  </div>
</div>

保守性への懸念

ユーティリティファーストアプローチを使用する場合の最大の保守性への懸念は、一般的に繰り返されるユーティリティの組み合わせを管理することです。

これは簡単にextracting componentsによって解決されます。extracting componentsをtemplate partials/JavaScriptコンポーネントとして、またはTailwindの@apply機能を使用して一般的なユーティリティパターンの周りに抽象化を作成することによっても解決されます。

<!-- Using utilities -->
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  Button
</button>

<!-- Extracting classes using @apply -->
<button class="btn btn-blue">
  Button
</button>

<style>
  .btn {
    @apply font-bold py-2 px-4 rounded;
  }
  .btn-blue {
    @apply bg-blue-500 text-white;
  }
  .btn-blue:hover {
    @apply bg-blue-700;
  }
</style>

それとは別に、ユーティリティファーストのCSSプロジェクトを維持することは、大規模なCSSコードベースを維持するよりもはるかに簡単であることがわかります。 単純にHTMLはCSSよりも保守がはるかに簡単だからです。 GitHub、Heroku、Kickstarter、Twitch、Segmentなどの大企業は、このアプローチを使用して大きな成功を収めています。 このアプローチに関する他の人の経験について知りたい場合は、次のリソースを確認してください。

より詳しくはJohn Polacekによってキュレートされたこちらをご覧ください。 The Case for Atomic/Utility-First CSS


Translated by T.Arai @ Entap,Inc. / スマホアプリ開発会社

Tailwind UI is now in early access!