ドキュメント

セットアップ

必要条件

Tailwind Plusのすべてのコンポーネントは、Tailwind CSSの最新バージョン(現在はTailwind CSS v4.0)向けに設計されています。Tailwindの最新バージョンを使用していることを確認するには、npmでアップデートしてください。

npm install tailwindcss@latest

Tailwind CSSを初めて使用する場合は、Tailwind Plusを最大限に活用するために、Tailwind CSSのドキュメントも読んでください。

Interフォントファミリーを追加する

Tailwind Plusのすべての例では、UIデザインに最適な美しいフォントであり、完全にオープンソースで無料であるInterを使用しています。カスタムフォントを使用すると、すべてのブラウザとオペレーティングシステムでコンポーネントの見え方を同じにできるため便利です。

自分のプロジェクトでは好きなフォントを自由に使用できますが、Interを使用したい場合は、まずCDN経由で追加するのが最も簡単な方法です。

<link rel="stylesheet" href="https://rsms.me/inter/inter.css" />

次に、Tailwindテーマの「sans」フォントファミリーに「InterVariable」を追加します。

@theme {
  --font-sans: InterVariable, sans-serif;
}

まだTailwind CSS v3.xを使用している場合は、tailwind.config.jsファイルでこれを行うことができます。

const defaultTheme = require('tailwindcss/defaultTheme')

module.exports = {
  theme: {
    extend: {
      fontFamily: {
        sans: ['InterVariable', ...defaultTheme.fontFamily.sans],
      },
    },
  },
  // ...
}

HTMLの使用

独自のJavaScriptを使用する

Tailwind Plusのすべてのコンポーネントは、React、Vue、およびバニラHTMLの3つの形式で提供されています。

ReactとVueの例は、すぐに使用できる完全に機能する状態で提供され、Tailwind CSSとの完璧な統合を目指して設計された、スタイルなしコンポーネントのライブラリであるHeadless UIによって動作しています。

バニラHTMLの例にはJavaScriptは含まれておらず、必要なJavaScriptを自分で記述したい人や、ReactやVue以外のフレームワークと統合したい人向けに設計されています。

コンポーネントの大部分はJavaScriptをまったく必要とせず、すぐに使用できますが、ドロップダウンやダイアログなどのインタラクティブな要素は、期待どおりに動作させるためにJSを記述する必要があります。

このような状況では、HTMLに簡単なコメントを提供して、さまざまな状態(トグルスイッチのオン/オフなど)で使用する必要があるクラスや、画面上または画面外に要素をトランジションさせるために推奨するクラス(ダイアログのオープンなど)について説明しています。

アクセシビリティに関する考慮事項

Tailwind Plusのすべてのマークアップができるだけアクセスしやすいように最善を尽くしましたが、インタラクティブなコンポーネントを構築する場合、多くのア​​クセシビリティのベストプラクティスはJavaScriptでのみ実装できます。

例えば

  • コンポーネントが適切にキーボードでアクセス可能であることを確認する(ドロップダウンは上下の矢印キーでナビゲートする必要があり、ダイアログはescapeキーを押すと閉じる必要があり、タブは左右の矢印キーを使用して選択する必要があるなど)
  • フォーカスを正しく処理する(ダイアログの背後にある要素にタブ移動できないようにする必要がある、ドロップダウンが開いたときにドロップダウンの最初の項目が自動的にフォーカスされる必要があるなど)
  • ARIA属性をコンポーネントの状態と同期させる(ドロップダウンが開いているときにaria-expanded="true"を追加する、トグルがオンのときにaria-checkedをtrueに設定する、オートコンプリートのオプションをナビゲートするときにaria-activedescendantを更新するなど)
  • ...その他多くの考慮事項。

ReactまたはVueでTailwind Plusを使用している場合、この複雑さのすべてはHeadless UIによって自動的に処理されますが、独自のJSを提供している場合は、インタラクティブな動作を追加する際にアクセシビリティのベストプラクティスに従う必要があります。

アクセシブルなUIコンポーネントの構築について詳しく学ぶには、W3Cによって公開されているWAI-ARIA Authoring Practicesを学習することをお勧めします。

動的クラス

要素が状態(トグルのオン/オフなど)に基づいて異なるクラスを適用する必要がある場合、各状態のクラスを要素の真上のコメントにリストします。

<!-- On: "bg-indigo-600", Off: "bg-gray-200" -->
<span
  aria-checked="false"
  class="focus:shadow-outline relative inline-block h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent bg-gray-200 transition-colors duration-200 ease-in-out focus:outline-none"
  role="checkbox"
  tabindex="0"
>
  <!-- On: "translate-x-5", Off: "translate-x-0" -->
  <span
    aria-hidden="true"
    class="inline-block size-5 translate-x-0 transform rounded-full bg-white shadow transition duration-200 ease-in-out"
  ></span>
</span>

提供するHTMLは常に定義された状態の1つに事前構成されており、状態を切り替えるときに変更する必要があるクラスは、クラスリストの先頭に常に配置されているため、簡単に見つけることができます。

例として、このHTMLをAlpine.jsに適合させるには、x-dataで宣言した状態に基づいて:classディレクティブを使用して正しいクラスを条件付きで適用できます。

<span
  x-data="{ isOn: false }"
  @click="isOn = !isOn"
  :aria-checked="isOn"
  :class="{'bg-indigo-600': isOn, 'bg-gray-200': !isOn }"
  class="focus:shadow-outline relative inline-block h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent bg-gray-200 transition-colors duration-200 ease-in-out focus:outline-none"
  role="checkbox"
  tabindex="0"
>
  <span
    aria-hidden="true"
    :class="{'translate-x-5': isOn, 'translate-x-0': !isOn }"
    class="inline-block size-5 translate-x-0 transform rounded-full bg-white shadow transition duration-200 ease-in-out"
  ></span>
</span>

ここでは一般的なアイデアを示すために基本的なクリックハンドラーを含めましたが、このようなコンポーネントを構築する際には、必要なすべてのキーボードインタラクションを実装し、必要なARIA属性を適切に管理するために、WAI-ARIA Authoring Practicesを参照してください。

トランジション

動的に表示または非表示にする必要がある要素(ドロップダウンのパネルなど)の場合、推奨されるトランジションスタイルを動的要素の真上のコメントに含めます。

<div class="relative ...">
  <button type="button" class="...">Options</button>

  <!--
    Show/hide this element based on the dropdown state

    Entering: "transition ease-out duration-100 transform"
      From: "opacity-0 scale-95"
      To: "opacity-100 scale-100"
    Closing: "transition ease-in duration-75 transform"
      From: "opacity-100 scale-100"
      To: "opacity-0 scale-95"
  -->
  <div class="absolute right-0 mt-2 w-56 origin-top-right rounded-md shadow-lg">
    <div class="rounded-md bg-white shadow-xs">
      <!-- Snipped  -->
    </div>
  </div>
</div>

例として、このHTMLをAlpine.jsに適合させるには、x-transitionディレクティブを使用して、トランジションライフサイクルの各時点で正しいクラスを適用します。

<div x-data="{ isOpen: false }" class="relative ...">
  <button type="button" @click="isOpen = !isOpen" class="...">Options</button>

  <div
    x-show="isOpen"
    x-transition:enter="transition ease-out duration-100 transform"
    x-transition:enter-start="opacity-0 scale-95"
    x-transition:enter-end="opacity-100 scale-100"
    x-transition:leave="transition ease-in duration-75 transform"
    x-transition:leave-start="opacity-100 scale-100"
    x-transition:leave-end="opacity-0 scale-95"
    class="absolute right-0 mt-2 w-56 origin-top-right rounded-md shadow-lg"
  >
    <div class="rounded-md bg-white shadow-xs">
      <!-- Snipped  -->
    </div>
  </div>
</div>

ここでは一般的なアイデアを示すために基本的なクリックハンドラーを含めましたが、このようなコンポーネントを構築する際には、必要なすべてのキーボードインタラクションを実装し、必要なARIA属性を適切に管理するために、WAI-ARIA Authoring Practicesを参照してください。

パーシャル/コンポーネントの作成

Tailwind Plusに含まれているバニラHTMLの例では、ループなどの機能を利用できないため、HTMLが動的なデータソースから生成される実際のプロジェクトでは存在しない多くの繰り返しがあります。たとえば、すべてのユーティリティが重複している5つのリスト項目を持つリストコンポーネントを提供する場合がありますが、実際のプロジェクトでは、配列をループ処理してこれらのリスト項目を生成します。

独自のプロジェクトに例を適合させる場合は、重複を管理するために必要に応じて再利用可能なテンプレートパーシャルまたはJSコンポーネントを作成することをお勧めします。

これについての詳細は、Tailwind CSSウェブサイトの「コンポーネントの使用」ドキュメントをご覧ください。

Reactの使用

依存関係のインストール

React用Tailwind Plusは、すべてのインタラクティブな動作をHeadless UIで、アイコンをHeroiconsで実現しているため、これら2つのライブラリをプロジェクトに追加する必要があります。

npm install @headlessui/react @heroicons/react

これらのライブラリとTailwind Plus自体は、すべてReact >= 16が必要です。.

コンポーネントの作成

すべてのReactの例は、シンプルな単一コンポーネントとして提供されており、コンポーネントをどのように分割したいか、どのようなprop APIを公開したいか、またはどこからデータを取得するかについて、一切の前提を置いていません。

重複を解消し、コードを読みやすく理解しやすくするために、一部のデータは基本的なローカル変数に抽出されていますが、不必要に厳格な意見を押し付けないように、できるだけ少ない変更に留めるように努めています。

Tailwind Plusのコードを自分のプロジェクトに適合させる場合は、プロジェクトに必要な再利用レベルを達成するために、必要に応じて例をより小さなコンポーネントに分割する必要があります。

たとえば、このスタックリストコンポーネントから始めることができます。

const people = [
  {
    name: 'Calvin Hawkins',
    email: 'calvin.hawkins@example.com',
    image:
      'https://images.unsplash.com/photo-1491528323818-fdd1faba62cc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
  },
  {
    name: 'Kristen Ramos',
    email: 'kristen.ramos@example.com',
    image:
      'https://images.unsplash.com/photo-1550525811-e5869dd03032?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
  },
  {
    name: 'Ted Fox',
    email: 'ted.fox@example.com',
    image:
      'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
  },
]

export default function Example() {
  return (
    <ul className="divide-y divide-gray-200">
      {people.map((person) => (
        <li key={person.email} className="flex py-4">
          <img className="size-10 rounded-full" src={person.image} alt="" />
          <div className="ml-3">
            <p className="text-sm font-medium text-gray-900">{person.name}</p>
            <p className="text-sm text-gray-500">{person.email}</p>
          </div>
        </li>
      ))}
    </ul>
  )
}

コンテンツを自分のプロジェクトに適合させ、個別のコンポーネントに分割し、データソースを接続すると、このようになる可能性があります。

function HockeyTeamItem({ team }) {
  return (
    <li className="flex py-4">
      <img className="size-10 rounded-full" src={team.logo} alt="" />
      <div className="ml-3">
        <p className="text-sm font-medium text-gray-900">{team.name}</p>
        <p className="text-sm text-gray-500">{team.city}</p>
      </div>
    </li>
  )
}

export default function HockeyTeamList({ teams }) {
  return (
    <ul className="divide-y divide-gray-200">
      {teams.map((team) => (
        <HockeyTeamItem key={team.id} team={team} />
      ))}
    </ul>
  )
}

Tailwind Plusは、厳格なUIキットというよりも、設計図、パターン、アイデアのセットのようなものです。最終的に作成するコードはあなたのものなので、好きなように構成できます。

Vueの使用

依存関係のインストール

Vue用Tailwind Plusは、すべてのインタラクティブな動作をHeadless UIで、アイコンをHeroiconsで実現しているため、これら2つのライブラリをプロジェクトに追加する必要があります。

npm install @headlessui/vue @heroicons/vue

コンポーネントの作成

すべてのVueの例は、シンプルな単一コンポーネントとして提供されており、コンポーネントをどのように分割したいか、どのようなprop APIを公開したいか、またはどこからデータを取得するかについて、一切の前提を置いていません。

重複を解消し、コードを読みやすく理解しやすくするために、一部のデータは基本的なローカル変数に抽出されていますが、不必要に厳格な意見を押し付けないように、できるだけ少ない変更に留めるように努めています。

Tailwind Plusのコードを自分のプロジェクトに適合させる場合は、プロジェクトに必要な再利用レベルを達成するために、必要に応じて例をより小さなコンポーネントに分割する必要があります。

たとえば、このスタックリストコンポーネントから始めることができます。

<template>
  <ul class="divide-y divide-gray-200">
    <li v-for="person in people" :key="person.email" class="flex py-4">
      <img class="size-10 rounded-full" :src="person.image" alt="" />
      <div class="ml-3">
        <p class="text-sm font-medium text-gray-900">{{ person.name }}</p>
        <p class="text-sm text-gray-500">{{ person.email }}</p>
      </div>
    </li>
  </ul>
</template>

<script>
  const people = [
    {
      name: 'Calvin Hawkins',
      email: 'calvin.hawkins@example.com',
      image:
        'https://images.unsplash.com/photo-1491528323818-fdd1faba62cc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
    },
    {
      name: 'Kristen Ramos',
      email: 'kristen.ramos@example.com',
      image:
        'https://images.unsplash.com/photo-1550525811-e5869dd03032?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
    },
    {
      name: 'Ted Fox',
      email: 'ted.fox@example.com',
      image:
        'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
    },
  ]

  export default {
    setup() {
      return {
        people,
      }
    },
  }
</script>

コンテンツを自分のプロジェクトに適合させ、個別のコンポーネントに分割し、データソースを接続すると、このようになる可能性があります。

<!-- HockeyTeamList.vue -->
<template>
  <ul class="divide-y divide-gray-200">
    <HockeyTeamItem v-for="team in teams" :key="team.id" :team="team" />
  </ul>
</template>

<script>
  export default {
    props: {
      teams: Array,
    },
  }
</script>

<!-- HockeyTeamListItem.vue -->
<template>
  <li class="flex py-4">
    <img class="size-10 rounded-full" :src="team.logo" alt="" />
    <div class="ml-3">
      <p class="text-sm font-medium text-gray-900">{{ team.name }}</p>
      <p class="text-sm text-gray-500">{{ team.city }}</p>
    </div>
  </li>
</template>

<script>
  export default {
    props: {
      team: Object,
    },
  }
</script>

Tailwind Plusは、厳格なUIキットというよりも、設計図、パターン、アイデアのセットのようなものです。最終的に作成するコードはあなたのものなので、好きなように構成できます。

リソースとアセット

アイコン

Tailwind Plusで使用しているすべてのアイコンはHeroiconsからのもので、HeroiconsはTailwind Plusの作業を開始したときに私たちが設計および開発した無料のMITライセンスのアイコンセットです。

画像

Tailwind Plusの画像は、ほぼ独占的にUnsplashから提供されています。プロジェクトで自由に使える写真が必要な場合に最適なリソースです。

イラスト

Tailwind Plusの例の一部では、Pixsellzによる無料のLucid Illustrationsパックのイラストを使用しています。イラストのフルセットを入手し、彼らのウェブサイトで他のデザインリソースをチェックできます。

Figmaアセット

かつてはTailwind PlusのFigmaアセットを提供していましたが、維持に非常に手間がかかり、使用している人が非常に少なかったため、最も価値を提供できると考えている実際のコードにより多くの時間を費やすことができるように、それらを廃止するという非常に難しい決断をしました。

Tailwind Plusのお客様は、リリースした最後のFigmaファイルをダウンロードできますが、Figmaファイルは更新されず、2021年7月14日以降にリリースされた例は含まれていないことに注意してください。

廃止されたFigmaキットをダウンロード →