20200809のCSSに関する記事は23件です。

【翻訳】tailwindcss.com - Core Concepts

tailwindcss について興味を持ち理解を深めたいと考えたため翻訳しました。もともと個人メモ用に軽く訳そうと考えていたためですます調ではありませんが、読んでいるうちに普及させたいと思い推敲はしました。変なところあればどんどんご指摘いただけると幸いです。

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

https://tailwindcss.com/docs/utility-first

従来 Web 上でスタイルする必要がある場合はCSSを書く。

:x: 独自のデザインに独自のCSSが必要となる従来のアプローチを使用してはいけない

(一応コードを引用しますがオリジナルの方はプレビュー付きなので併読を推奨します)

<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に直接適用することで要素のスタイリングを行う。

:o: CSSを書かずユーティリティクラスを使用して独自のデザインを実現する

<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>

上記例では

  • Tailwind の flexboxpadding ユーティリティ ( flex , flex-shrink-0 , p-6 ) を使用してカードレイアウト全体を制御
  • max-widthmargin ユーティリティ ( max-w-smmx-auto ) によってカード幅を制限し横方向の中央揃えに
  • 背景色, 角丸度合い, そして box-shadow ユーティリティ ( bg-white, rounded-lg, shadow-xl ) によってカードの外観をスタイリング
  • 横幅高さ ユーティリティ ( w-12h-12 ) によるロゴ画像のサイズ指定
  • マージンパディング ユーティリティ ( ml-6pt-1 ) によるカードのテキストの位置調整
  • フォントサイズ文字色line-height ユーティリティ ( text-xl, text-gray-900, leading-tight など) によるカードのテキストのスタイリング

これらにより CSS を1行も書くことなく独自のコンポーネントのデザインを完全に実装することを可能としている。

「これは酷い、なんてこった!」と思われたかもしれないがその気持ちはわかるし、その通り受け入れがたいだろう。だが瞬間的に良し悪しを判断するのは早計である、 まずは実際に試してみてほしい

この方法で実際に何か構築するといくつか重要な利点があることにすぐ気がつくはずだ:

  • クラスの名前を考える労力が0である ... なにかスタイリングするためだけに sidebar-inner-wrapper のようなクラス名をわざわざ追加する必要はないし、ただの flex コンテナに完璧な抽象名をつけようと悩む必要もない
  • CSSの肥大化を阻止できる ... 従来の手法では新機能を追加する毎にCSSファイルが巨大化してしまうが、ユーティリティならば全て再利用可能なので、新しくCSSを書くことは稀になる
  • より安心して変更できる ... CSSはグローバルであるため、修正を加えた時に予期せぬ変更をしてしまっていても気づくことができない、HTML内のクラス(属性)ならローカルなので、うっかり他へ影響を与えていないか心配せずに変更することが可能である

インラインスタイル(style属性)を使用しない理由

「これってただのインラインスタイルではないのか?」と言う疑問があるかもしれない。要素のクラス名を決めてからそのクラスを使うのではなく、スタイルを要素に直接適用している点ではそうともいえよう。

しかしユーティリティクラスを使用することでインラインスタイルに対していくつかの重要な長所がある:

  • 制約ありのデザイン ... インラインスタイルを使用すると全ての値はマジックナンバーになってしまう。ユーティリティならあらかじめ用意されている デザインテーマ からスタイルを選択するので、視覚的に一貫性を持ったUIを構築することがはるかに容易となる
  • レスポンシブデザイン ... インラインスタイルではメディアクエリは使用できないが、 Tailwind の レスポンシブデザイン なら完全対応したUIを容易に構築できる
  • 擬似クラス ... インラインスタイルではホバーやフォーカスといった状態を指定できないが、Tailwindの 擬似クラスバリアント ならユーティリティクラスを使用して状態に応じたスタイリングを簡単に構築できる

次に示すコンポーネントはフルレスポンシブかつホバーに対応したスタイルのボタンを内包しており、ユーティリティクラスだけで構築されている:

<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>

保守性に対する懸念

ユーティリティファーストの手法で一番の懸念事項はユーティリティの組み合わせを毎回記述することであろう。

これはコンポーネントを部分テンプレート(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>

他にも、HTMLはCSSよりも保守が非常に容易であるということからユーティリティファーストのコードの保守は巨大なCSSの塊を保守するよりとても簡単であることがわかる。 GitHub や Heroku、Kickstarter、Twitch、Segment といった大企業でもこのアプローチを使うことで大きく成功している。

この手法に関する外部の情報をここに示しておく:

より詳しくは John Polacek が整理した The Case for Atomic/Utility-First CSS を確認されたい。

レスポンシブデザイン

Tailwind の全てのユーティリティクラスは異なるブレークポイントに対して条件的に適用が可能なため、HTMLの編集に集中したまま複雑なレスポンシブUIを構築できる。

デフォルトでは一般的な端末の解像度を想定した4つのブレークポイントを用意している:

/* 小 - Small (sm) */
@media (min-width: 640px) { /* ... */ }

/* 中 - Medium (md) */
@media (min-width: 768px) { /* ... */ }

/* 大 - Large (lg) */
@media (min-width: 1024px) { /* ... */ }

/* 特大 - Extra Large (xl) */
@media (min-width: 1280px) { /* ... */ }

特定のブレークポイントでのみ有効なユーティリティクラスを追加するには、クラス名の前にブレークポイント名と : をプリフィクスとしてつけるだけである:

<!-- デフォルトで横幅16, 中画面だと32, 大画面であれば48 -->
<img class="w-16 md:w-32 lg:w-48" src="...">

これは フレームワーク内のすべてのユーティリティクラス で有効であるため、文字の間隔やカーソルのスタイルなどであっても特定のブレークポイントによって変更することが可能である。

小さい画面では縦並び(stack)、より大きい画面では横並びとなるマーケティングページのコンポーネントの例を示す:

<div class="md:flex">
  <div class="md:flex-shrink-0">
    <img class="rounded-lg md:w-56" src="https://images.unsplash.com/photo-1556740738-b6a63e27c4df?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2550&q=80" alt="Woman paying for a purchase">
  </div>
  <div class="mt-4 md:mt-0 md:ml-6">
    <div class="uppercase tracking-wide text-sm text-indigo-600 font-bold">Marketing</div>
    <a href="#" class="block mt-1 text-lg leading-tight font-semibold text-gray-900 hover:underline">Finding customers for your new business</a>
    <p class="mt-2 text-gray-600">Getting a new business off the ground is a lot of hard work. Here are five ideas you can use to find your first customers.</p>
  </div>
</div>

これはこのような仕組みとなっている:

  • デフォルトでは外側のdivは display: block だが、 md:flex を追加することで中画面以上では display: flex となる
  • flex のコンテナが親の時は画像が縮まないようにしたいので md:flex-shrink-0 を追加し、中画面以上では縮小されないようにしている、厳密には小さい画面ではなにも起きないので flex-shrink-0 を使用することも可能ではあるが、 md の画面でしか意味がないのでクラス名で明示しておくほうが良い
  • 小さい画面では画像はデフォルトで自動的に横幅いっぱいで表示され、中画面以上では md:w-56 を指定して横幅を固定にしている
  • 小さい画面ではコンテンツの部分で mt-4 を追加して画像とコンテンツの間に若干のマージンを追加している、このマージンは横並びのレイアウトでは不要なため、 md:mt-0 を使用しこのマージンを打ち消しつつ、代わりに md:ml-6 も追加することで左マージンを若干追加している

この例では一つのブレークポイントしか使用していないが、 sm, lg, xl といったプリフィクスも同様に使うことでこのコンポーネントを他のサイズ向けにカスタマイズすることは容易である。

モバイルファースト

デフォルトでは Tailwind はモバイルファーストのブレークポイント体系を使用する。これは Bootstrap や Foundation で使われているものと似ている。

upppercase のようなプリフィクスなしのユーティリティは全ての画面サイズで有効なのに対し、 md:uppercase のようなプレフィクスありのユーティリティは指定されたブレークポイント 以上 でのみ有効ということになる。

ブレークポイント毎に背景色が変わる例をここに示す:

<div class="bg-red-500 sm:bg-green-500 md:bg-blue-500 lg:bg-pink-500 xl:bg-teal-500"></div>

(原文ではウィンドウ幅を変えることなくボタンだけで各レスポンシブ幅のレイアウトを確認するウィジェットについての説明が記述されているがここでは引用不可のため省略)

モバイル画面をターゲットにする

モバイル向けに何かスタイルを設定する場合、 sm: プレフィクス付きではなくプリフィクスなしを使う必要があるという点について驚かれるかもしれない。

sm: プリフィクスを「小さい画面のとき」として考えず、「小さなブレークポイントのとき」と考えてほしい。

:x: sm: をモバイル端末用として使ってはいけない

<!-- モバイルが対象ではなく画面幅が640px以上の時だけテキストがセンタリングされてしまう -->
<div class="sm:text-center"></div>

:o: モバイル向けはプリフィクスなしのユーティリティクラスを使い、より大きいブレークポイントで上書きする

<!-- モバイルではセンタリング、画面幅が 640px 以上なら左寄せ -->
<div class="text-center sm:text-left"></div>

以上から多くの場合、最初にモバイル用のデザインのレイアウトから実装し、その後 sm 画面用の変更を適用し、 md 画面などの変更に着手するのがよいはずだ。

1つのブレークポイントを狙い撃ちする

Tailwind のブレークポイントは min-width のみ指定しており max-width は指定していない。これは小さなブレークポイントに追加したユーティリティはより大きいブレークポイントにも適用されることを意味する。

一つのブレークポイントだけにユーティリティを適用したい場合はそれを打ち消す別のユーティリティをより大きいサイズに追加することで 取り消す ことが可能だ。

ここに md のブレークポイントの時に背景色を赤にし、他のブレークポイントではティール(色の名前)とする例を示す:

<div class="bg-teal-500 md:bg-red-500 lg:bg-teal-500"></div>

sm ブレークポイントや xl ブレークポイントに対して指定して いない ことに注目してほしい。ユーティリティクラスの効果を発揮する始点のみ指定するだけでよいということになる。

ブレークポイントのカスタマイズ

tailwind.config.js ファイルでブレークポイントを自由にカスタマイズすることが可能である:

// tailwind.config.js
module.exports = {
  theme: {
    screens: {
      'tablet': '640px',
      // => @media (min-width: 640px) { ... }

      'laptop': '1024px',
      // => @media (min-width: 1024px) { ... }

      'desktop': '1280px',
      // => @media (min-width: 1280px) { ... }
    },
  }
}

詳しくは ブレークポイントをカスタマイズする を参照されたい。

擬似クラスバリアント

前出の レスポンシブデザイン のように、ホバーやフォーカスといった要素のスタイリングも適切な擬似クラスのプリフィクスをつけることで実現が可能である。

<form>
  <input class="bg-gray-200 hover:bg-white hover:border-gray-300 focus:outline-none focus:bg-white focus:shadow-outline focus:border-gray-300 ...">
  <button class="bg-teal-500 hover:bg-teal-600 focus:outline-none focus:shadow-outline ...">
    Sign Up
  </button>
</form>

ファイルサイズについて熟慮した結果、 デフォルトで全ての擬似クラスバリアントがすべてのユーティリティで有効になっていない 点について注意が必要である。なにもせずとも(out-of-the-box)よく使われるであろう組み合わせでは有効になるよう最善を尽くしている。

デフォルトで有効になっているバリアントの完全なリストについては リファレンス表 を参照されたい。

もし Tailwind で未サポートの擬似クラスを使う必要があれば、 バリアントのプラグインを書く ことで対応バリアントを増やすことが可能である。

Hover

hover: プリフィクスを追加するだけでユーティリティを制限できる:

<button class="bg-transparent hover:bg-blue-500 text-blue-700 hover:text-white...">
  Hover me
</button>

hover バリアントを有効にするかどうかは tailwind.config.js ファイルの variants セクションで制御が可能である:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    backgroundColor: ['responsive', 'hover', 'focus'],
  },
}

Focus

focus: プリフィクスを追加するだけでユーティリティを制限できる:

<input class="bg-gray-200 focus:bg-white border-transparent focus:border-blue-400 ..." placeholder="Focus me">

focus バリアントを有効にするかどうかは hover 同様 tailwind.config.js ファイルの variants セクションで制御が可能である (記述例は繰り返しになるので省略)

Active

<button class="bg-blue-500 active:bg-blue-700 text-white...">
  Click me
</button>

Group-hover

特定の親要素上でホバーする時に子要素をスタイルする必要があるのであれば、 .group クラスを親要素に付与し group-hover: プリフィクスを子要素のユーティリティクラスに追加する。

<div class="group bg-white hover:bg-blue-500 ...">
  <p class="text-gray-900 group-hover:text-white ...">New Project</p>
  <p class="text-gray-700 group-hover:text-white ...">Create a new project from a variety of starting templates.</p>
</div>

Group-focus (v1.3.0+)

group-focus バリアントはフォーカス以外は group-hover と同様に機能する

Focus-within

:warning: この機能はIEまたはEdge < 79 ではサポートされない

focus-within: プリフィクスを付与すれば子要素にフォーカスした時のみユーティリティを適用できる

<form class="border-b-2 border-gray-400 focus-within:border-teal-500 ...">
  <input class="..." placeholder="Jane Doe" ...>
  <button class="...">
    Sign Up
  </button>
</form>

Focus-visible (v1.5.0+)

:warning: この機能は現時点ではブラウザを十分にサポートするためにポリフィルが必要である

focus-visible: プリフィクスを付与することで要素にフォーカスしつつユーザーがキーボードを使用している場合のみユーティリティクラスを有効にできる:

<ul class="flex space-x-8">
  <li>
    <a class="focus:outline-none focus:underline ..." href="#">
      Underlined on focus
    </a>
  </li>
  <li>
    <a class="focus:outline-none focus-visible:underline ..." href="#">
      Underlined on focus-visible
    </a>
  </li>
</ul>

(左のリンクはクリックすると下線がつくが右のリンクはつかない、クリックしてからキーを押下したりあるいはタブキーでフォーカスを当てると下線が出る)

Firefoxのみがサポートしているため、十分にブラウザをサポートするためには focus-visible のJSポリフィルfocus-visible のPostCSSポリフィル の両方がインストールされ設定されている必要がある。PostCSSのプラグインは一覧で Tailwind より 後に 追加されるようにしてほしい:

// postcss.config.js
module.exports = {
  plugins: {
    tailwindcss: {},
    'postcss-focus-visible': {},
    autoprefixer: {}
  }
}

Motion-safe (v1.6.0+)

motion-safe: プリフィクスを付与することで prefers-reduces-motion メディアクエリが no-preference の時のみユーティリティクラスが適用されるようにできる。たとえば下記のボタンはユーザーがシステム(ブラウザ)の設定で余計な動きを減らす("Reduce motion")設定を有効にしていない時だけアニメーションする:

<button class="transform motion-safe:hover:-translate-y-1 motion-safe:hover:scale-110 transition ease-in-out duration-300 ...">
  Hover
</button>

他の多数のバリアントとは異なり motion-safe はレスポンシブ用のバリアントや hover といった他のバリアントを組み合わせて使用することができる:

<div class="sm:motion-safe:hover:animate-spin">
  <!-- ... -->
</div>

Motion-reduce (v1.6.0+)

motion-reduce: プリフィクスを付与することで prefers-reduced-motion メディアクエリが reduce の時のみユーティリティが適用されるようにできる。例えば下記のボタンはデフォルトでホバー時にアニメーションするが、ユーザーが余計な動きを減らす("Reduce motion")設定を有効にしている場合は無効化される:

<button class="transform motion-reduce:transform-none hover:-translate-y-1 hover:scale-110 transition ease-in-out duration-300 ...">
  Hover
</button>

この motion-reducemotion-safe 同様、レスポンシブ用 / hover といった他のバリアントと組み合わせが可能。

Disabled (v1.1.0+)

disabled: プリフィクスを付与すれば要素が無効化(非活性化)しているときにユーティリティクラスが適用されるようにできる:

<button class="disabled:opacity-75 bg-blue-500...">
  Submit
</button>

<button disabled class="disabled:opacity-75 bg-blue-500...">
  Submit
</button>

Visited (v1.1.0+)

visited: プリフィクスを付与すれば訪問済みリンクに対してのみユーティリティクラスを適用できる:

<a href="#" class="text-blue-600 visited:text-purple-600 ...">Link</a>

Checked (v1.5.0+)

checked: プリフィクスを付与すればchecked状態のラジオボタン・チェックボックスに対してのみユーティリティクラスを適用できる

<input type="radio" class="appearance-none checked:bg-gray-900 checked:border-transparent ...">

First-child (v1.1.0+)

first: プリフィクスを付与すればその要素が親要素の最初の要素(first-child)のときだけユーティリティクラスが適用されるようにできる。ループなどで要素が複数作成される場合などで特に効果的である:

<div class="border rounded">
  <div v-for="item in items" class="border-t first:border-t-0">
    {{ item }}
  </div>
</div>

(3行のリストで各行のトップに境界線を入れつつ外側を枠線で囲っているデモ、first で最初の要素だけ境界線をなくすことで一番上の境界線が二重にならないようにしている)

first: プリフィクスは子要素のユーティリティクラスに対して追加するのであって、親要素ではないので注意。

Last-child (v1.1.0+)

last: プリフィクスを付与すればその要素が親要素の最後の要素(last-child)の時だけユーティリティクラスが適用されるようにできる。こちらも first: 同様ループで効果的である。

Odd-child (v1.1.0+)

odd: プリフィクスを付与すればその要素が親要素の奇数番目(odd-child)にある場合のみユーティリティクラスを適用できる。こちらも first: 同様ループで効果的である。
 
html
<div class="border rounded">
<div v-for="item in items" class="bg-white odd:bg-gray-200">
{{ item }}
</div>
</div>

Even-child (v1.1.0+)

even: プリフィクスは odd: の偶数版。

レスポンシブ用のプリフィクスと組み合わせる

擬似クラスバリアントはレスポンシブでもあるため、例えばブレークポイント別で要素のホバーのスタイルを切り替えるといったことが可能である。

特定のブレークポイントに擬似クラスバリアントを適用するには、まずレスポンシブ用のプリフィクスを書いて、その後ろに擬似クラスのプリフィクスを記述する:

<button class="bg-orange-500 hover:bg-orange-600 sm:bg-green-500 sm:hover:bg-green-600 md:bg-red-500 md:hover:bg-red-600 lg:bg-indigo-500 lg:hover:bg-indigo-600 xl:bg-pink-500 xl:hover:bg-pink-600 ">
  Button
</button>

独自ユーティリティ用のバリアント生成

CSS 内で @variants ディレクティブでラップすることによって自作ユーティリティに対しても擬似クラスバリアントは生成可能である:

/* ソース: */
@variants group-hover, hover, focus {
  .banana {
    color: yellow;
  }
}

/* 生成結果: */
.banana {
  color: yellow;
}
.group:hover .group-hover\:banana {
  color: yellow;
}
.hover\:banana:hover {
  color: yellow;
}
.focus\:banana:focus {
  color: yellow;
}

より詳しい情報については @variants を参照されたい。

独自バリアントの作成

Tailwind にデフォルトで含まれていない擬似クラス用のバリアントは独自バリアント用のプラグインを書くことで作成可能である。

ここに disabled 擬似クラスバリアントをサポートするための簡単なプラグインの例を示す:

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addVariant, e }) {
      addVariant('disabled', ({ modifySelectors, separator }) => {
        modifySelectors(({ className }) => {
          return `.${e(`disabled${separator}${className}`)}:disabled`
        })
      })
    })
  ]
}

詳しくは variant plugin documentation を参照されたい。

デフォルトバリアントのリファレンス

ファイルサイズについて検討した結果、デフォルトで全ての擬似クラスバリアントを組み込んでいない。

プロジェクト毎にどのバリアントを有効化するか設定するには configuring variants documentation を参照されたい。

// Default configuration
module.exports = {
  // ...
  variants: {
    accessibility: ['responsive', 'focus'],
    alignContent: ['responsive'],
    alignItems: ['responsive'],
    alignSelf: ['responsive'],
    appearance: ['responsive'],
    backgroundAttachment: ['responsive'],
    backgroundColor: ['responsive', 'hover', 'focus'],
    backgroundOpacity: ['responsive', 'hover', 'focus'],
    backgroundPosition: ['responsive'],
    backgroundRepeat: ['responsive'],
    backgroundSize: ['responsive'],
    borderCollapse: ['responsive'],
    borderColor: ['responsive', 'hover', 'focus'],
    borderOpacity: ['responsive', 'hover', 'focus'],
    borderRadius: ['responsive'],
    borderStyle: ['responsive'],
    borderWidth: ['responsive'],
    boxShadow: ['responsive', 'hover', 'focus'],
    boxSizing: ['responsive'],
    clear: ['responsive'],
    cursor: ['responsive'],
    display: ['responsive'],
    divideColor: ['responsive'],
    divideOpacity: ['responsive'],
    divideWidth: ['responsive'],
    fill: ['responsive'],
    flex: ['responsive'],
    flexDirection: ['responsive'],
    flexGrow: ['responsive'],
    flexShrink: ['responsive'],
    flexWrap: ['responsive'],
    float: ['responsive'],
    fontFamily: ['responsive'],
    fontSize: ['responsive'],
    fontSmoothing: ['responsive'],
    fontStyle: ['responsive'],
    fontWeight: ['responsive', 'hover', 'focus'],
    gap: ['responsive'],
    gridAutoFlow: ['responsive'],
    gridColumn: ['responsive'],
    gridColumnEnd: ['responsive'],
    gridColumnStart: ['responsive'],
    gridRow: ['responsive'],
    gridRowEnd: ['responsive'],
    gridRowStart: ['responsive'],
    gridTemplateColumns: ['responsive'],
    gridTemplateRows: ['responsive'],
    height: ['responsive'],
    inset: ['responsive'],
    justifyContent: ['responsive'],
    letterSpacing: ['responsive'],
    lineHeight: ['responsive'],
    listStylePosition: ['responsive'],
    listStyleType: ['responsive'],
    margin: ['responsive'],
    maxHeight: ['responsive'],
    maxWidth: ['responsive'],
    minHeight: ['responsive'],
    minWidth: ['responsive'],
    objectFit: ['responsive'],
    objectPosition: ['responsive'],
    opacity: ['responsive', 'hover', 'focus'],
    order: ['responsive'],
    outline: ['responsive', 'focus'],
    overflow: ['responsive'],
    padding: ['responsive'],
    placeholderColor: ['responsive', 'focus'],
    placeholderOpacity: ['responsive', 'focus'],
    pointerEvents: ['responsive'],
    position: ['responsive'],
    resize: ['responsive'],
    rotate: ['responsive', 'hover', 'focus'],
    scale: ['responsive', 'hover', 'focus'],
    skew: ['responsive', 'hover', 'focus'],
    space: ['responsive'],
    stroke: ['responsive'],
    strokeWidth: ['responsive'],
    tableLayout: ['responsive'],
    textAlign: ['responsive'],
    textColor: ['responsive', 'hover', 'focus'],
    textDecoration: ['responsive', 'hover', 'focus'],
    textOpacity: ['responsive', 'hover', 'focus'],
    textTransform: ['responsive'],
    transform: ['responsive'],
    transformOrigin: ['responsive'],
    transitionDelay: ['responsive'],
    transitionDuration: ['responsive'],
    transitionProperty: ['responsive'],
    transitionTimingFunction: ['responsive'],
    translate: ['responsive', 'hover', 'focus'],
    userSelect: ['responsive'],
    verticalAlign: ['responsive'],
    visibility: ['responsive'],
    whitespace: ['responsive'],
    width: ['responsive'],
    wordBreak: ['responsive'],
    zIndex: ['responsive'],
  }
}

基底スタイルの追加

https://tailwindcss.com/docs/adding-base-styles

基底(あるいはグローバル)のスタイルは <a> タグや見出しなどのHTML要素にデフォルト値をセットしたり、流行りの box-sizing のリセット のような個人意見的なリセット (opinionated reset) を適用するのに有用な、スタイルシートの先頭に記すスタイルのことである。

Tailwind では normalize.css に個人意見的なスタイルを追加した軽量な プレフライト という、すぐ使える便利な基底スタイルのセットを用意している。

プレフライトは大多数のプロジェクトにおいて良い開始地点となるが、独自の基底スタイルを追加したい場合は慣用的に行うべきいくつかの推奨事項をここに示す。

HTMLでクラスを使う

htmlbody 要素へグローバルなスタイルを適用したい場合はCSSを新規に書くのではなくHTML内の要素へ既存のクラスを追記する方法を検討してみてほしい:

<!doctype html>
<html lang="en" class="text-gray-900 antialiased leading-tight">
  <!-- ... -->
  <body class="min-h-screen bg-gray-100">
    <!-- ... -->
  </body>
</html>

CSSを使う

特定の要素へ基底スタイルを適用したい場合に最も簡単な方法はずばりCSSを書くことだ。 @tailwind base の後に任意の基底スタイルを定義し、一部の問題を避けるため @tailwind components で閉じてほしい:

@tailwind base;

h1 {
  @apply text-2xl;
}
h2 {
  @apply text-xl;
}
h3 {
  @apply text-lg;
}
a {
  @apply text-blue-600 underline;
}

@tailwind components;

@tailwind utilities;

@applytheme() を使用してスタイルを定義し、うっかりマジックナンバーを作ってしまったりデザインからの逸脱を避けるのは良い心がけであろう。

@font-face 規約

同じ要領で使用しているカスタムフォントに対して @font-face 規約も追加できる:

@tailwind base;

@font-face {
  font-family: Proxima Nova;
  font-weight: 400;
  src: url(/fonts/proxima-nova/400-regular.woff) format("woff");
}
@font-face {
  font-family: Proxima Nova;
  font-weight: 500;
  src: url(/fonts/proxima-nova/500-medium.woff) format("woff");
}

@tailwind components;

@tailwind utilities;

プラグインを使う

addBase 関数を使った プラグインを書く ことでも基底スタイルを追加することが可能だ:

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addBase, config }) {
      addBase({
        'h1': { fontSize: config('theme.fontSize.2xl') },
        'h2': { fontSize: config('theme.fontSize.xl') },
        'h3': { fontSize: config('theme.fontSize.lg') },
      })
    })
  ]
}

addBase を使用して追加したスタイルは自動的に @tailwind base スタイルの中に組み込まれる。

プラグインを使うタイミング

プラグインを書くよりかはCSSをプロジェクト内に書く方が一般的には簡単だ。ただし次のような場合はプラグインのほうがよいだろう:

  • 独自の基底スタイルを外部へ公開し他のユーザーが簡単に利用できるようにしたい場合
  • 社内の複数のプロジェクト間で基底スタイルを再利用し、CSSの依存ではなくJSの依存として共有したい場合

コンポーネントを抽出する

Tailwind では早い段階での抽象化を避け最初はユーティリティクラスのみを使用してデザインを実装する ユーティリティファースト なワークフローを奨励している。

<!-- ユーティリティクラスだけで実装したマーケティングのページ用のカードの例 -->
<div class="md:flex">
  <div class="md:flex-shrink-0">
    <img class="rounded-lg md:w-56" src="https://images.unsplash.com/photo-1556740738-b6a63e27c4df?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=448&q=80" alt="Woman paying for a purchase">
  </div>
  <div class="mt-4 md:mt-0 md:ml-6">
    <div class="uppercase tracking-wide text-sm text-indigo-600 font-bold">Marketing</div>
    <a href="#" class="block mt-1 text-lg leading-tight font-semibold text-gray-900 hover:underline">Finding customers for your new business</a>
    <p class="mt-2 text-gray-600">Getting a new business off the ground is a lot of hard work. Here are five ideas you can use to find your first customers.</p>
  </div>
</div>

しかしプロジェクトが大きくなるにつれ、あらゆるところで同じコンポーネントを作るためにユーティリティの組み合わせが繰り返されていることに気がつくであろう。これはボタンやフォーム要素、バッジといった小さいコンポーネントで顕著である。

<!-- ボタン毎にクラスを繰り返すのは辛い -->
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  Button
</button>

コンポーネントのインスタンス間でユーティリティの長い列を維持するのはすぐ保守の負担になりうるので、繰り返しがつらいと気がついたタイミングでコンポーネントの抽象化を行うとよい。

HTMLコンポーネントを抽出する

UIコンポーネントを定義するために必要な情報がCSSのみで完結することは極めて稀で、対となる重要なHTML構造が必要であろう。

:x: 複雑なコンポーネントを抽象化するためにCSSクラスに頼ってはいけない

<style>
  .vacation-card { /* ... */ }
  .vacation-card-info { /* ... */ }
  .vacation-card-eyebrow { /* ... */ }
  .vacation-card-title { /* ... */ }
  .vacation-card-price { /* ... */ }
</style>

<!-- 独自のCSSを使用しても、このHTML構造を複製する必要がある -->
<div class="vacation-card">
  <img class="vacation-card-image" src="..." alt="Beach in Cancun">
  <div class="vacation-card-info">
    <div>
      <div class="vacation-card-eyebrow">Private Villa</div>
      <div class="vacation-card-title">
        <a href="/vacations/cancun">Relaxing All-Inclusive Resort in Cancun</a>
      </div>
      <div class="vacation-card-price">$299 USD per night</div>
    </div>
  </div>
</div>

故に独自のCSSクラスを書くのではなくUIの再利用可能な部分を 部分テンプレートJavaScript コンポーネント に抽出する方がうまくいくことが少なくない。

ただ一つの情報源(single source of truth)となるテンプレートを作れば、同じクラスの並びを何度も複製して作ることによる保守負担を避けてユーティリティクラスを使い続けることが可能となる。

:o: 部分テンプレート/JavaScriptコンポーネントを作る

<!-- 使う側 -->
<VacationCard
  img="/img/cancun.jpg"
  imgAlt="Beach in Cancun"
  eyebrow="Private Villa"
  title="Relaxing All-Inclusive Resort in Cancun"
  pricing="$299 USD per night"
  url="/vacations/cancun"
/>

<!-- ./components/VacationCard.vue -->
<template>
  <div>
    <img class="rounded" :src="img" :alt="imgAlt">
    <div class="mt-2">
      <div>
        <div class="text-xs text-gray-600 uppercase font-bold">{{ eyebrow }}</div>
        <div class="font-bold text-gray-700 leading-snug">
          <a :href="url" class="hover:underline">{{ title }}</a>
        </div>
        <div class="mt-2 text-sm text-gray-600">{{ pricing }}</div>
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    props: ['img', 'imgAlt', 'eyebrow', 'title', 'pricing', 'url']
  }
</script>

上記例では Vue を使用しているが、 ReactのコンポーネントERBのパーシャルBladeのコンポーネントTwigのinclude などでも同じようなアプローチが可能だ。

@apply でCSSコンポーネントを抽出する

ボタンやフォーム要素といった小さいコンポーネント用に部分テンプレートやJavaScriptコンポーネントを作ることはCSSクラスを書くのに比べて荷が重いと感じてしまうことがよくあるであろう。

このような場合、Tailwindの @apply ディレクティブを使えば共通のユーティリティの組み合わせをCSSコンポーネントクラスに抽出可能だ。

ここに @apply を使用して既存のユーティリティを作成した .btn-blue クラスを示す:

<button class="btn-blue">
  Button
</button>

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

hover:focus:{screen}: といったバリアントは @apply では使用できないので、代わりに擬似セレクタやメディアクエリと通常版のユーティリティクラスを組み合わせて適用してほしい。

このようなクラスは特定の問題を避けるため @tailwind components ディレクティブより後ろに追加されるべきである。

:x: CSSの末尾に独自コンポーネント用のクラスを追加してはいけない

@tailwind base;

@tailwind components;

@tailwind utilities;

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

:o: utlities の前に独自コンポーネント用のクラスを追加する

@tailwind base;

@tailwind components;

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

@tailwind utilities;

組み合わせ可能な状態を維持する

このような二つのボタンに対して

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

<button class="bg-gray-400 hover:bg-gray-500 text-gray-800 font-bold py-2 px-4 rounded">
  Button
</button>

こんなコンポーネントクラスを実装したくなるかもしれない:

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

.btn-gray {
  @apply bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded;
}
.btn-gray:hover {
  @apply bg-gray-500;
}

このアプローチには苦痛な重複が発生しうるという問題がある。

もしサイト上の全てのボタンのパディングやフォントの太さ、角丸具合を変えようとした場合、全部のボタンのクラスの書き換えを余儀なくさせられるだろう。

より良いアプローチとしては共通部分を別のクラスへ抽出することだ:

.btn {
  @apply font-bold py-2 px-4 rounded;
}

.btn-blue {
  @apply bg-blue-500 text-white;
}
.btn-blue:hover {
  @apply bg-blue-700;
}

.btn-gray {
  @apply bg-gray-400 text-gray-800;
}
.btn-gray:hover {
  @apply bg-gray-500;
}

この場合ボタンにスタイルを当てる必要がある時は常に2つのクラスを適用することとなる:

<button class="btn btn-blue">
  Button
</button>

<button class="btn btn-gray">
  Button
</button>

この変更により .btn クラスを編集するだけで共有されたスタイルの変更が容易となった。

また新しいコンポーネントクラスを作ったり共通スタイルを複製することなく、1度しか使わないボタンのスタイルを追加することも可能となる:

<button class="btn bg-green-500 hover:bg-green-400 text-white">
  Button
</button>

コンポーネントプラグインを書く

CSSファイルに直接コンポーネント用のクラスを書くのに加えて、プラグインを作れば Tailwind にコンポーネント用のクラスを追加することも可能だ:

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addComponents }) {
      const buttons = {
        '.btn': {
          padding: '.5rem 1rem',
          borderRadius: '.25rem',
          fontWeight: '600',
        },
        '.btn-blue': {
          backgroundColor: '#3490dc',
          color: '#fff',
          '&:hover': {
            backgroundColor: '#2779bd'
          },
        },
        '.btn-red': {
          backgroundColor: '#e3342f',
          color: '#fff',
          '&:hover': {
            backgroundColor: '#cc1f1a'
          },
        },
      }

      addComponents(buttons)
    })
  ]
}

この方法は Tailwind 用のコンポーネントをライブラリとして公開したり、複数のプロジェクト間でコンポーネントを共有しやすくするのに適している。

詳しくは component plugin documentation を参照されたい。

新しいユーティリティを追加する

https://tailwindcss.com/docs/adding-new-utilities

Tailwind ではすぐに使える広範囲をカバーしたユーティリティクラスのセットを提供するが、独自のクラスを追加しなければならない状況もあるだろう。

ここでは可能な限り簡単な方法で独自のユーティリティを追加するのに役立つベストプラクティクスをいくつか紹介したい。

CSSを使用する

Tailwind に独自のユーティリティクラスを追加する最も簡単な方法は、ずばりCSSを書くことだ。

:o: CSSファイルの末尾に独自のユーティリティを追加する

@tailwind base;
@tailwind components;
@tailwind utilities;

.rotate-0 {
  transform: rotate(0deg);
}
.rotate-90 {
  transform: rotate(90deg);
}
.rotate-180 {
  transform: rotate(180deg);
}
.rotate-270 {
  transform: rotate(270deg);
}

CSS内で定義する順番が重要だ、特定の問題を回避するためいつでもCSSの 末尾 にユーティリティを追加するようにしてほしい。

:x: CSSの先頭に追加してはいけない

/* ユーティリティクラスを先頭に書くと特定の問題が起きる可能性がある */
.rotate-0 {
  transform: rotate(0deg);
}
.rotate-90 {
  transform: rotate(90deg);
}
.rotate-180 {
  transform: rotate(180deg);
}
.rotate-270 {
  transform: rotate(270deg);
}

@tailwind base;
@tailwind components;
@tailwind utilities;

postcss-import や Less, Sass, Stylus などのプリプロセッサを使用している場合はファイルを分けてインポートする方法を検討してみてほしい:

/* postcss-import を使用している場合 */
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
@import "./custom-utilities.css";

/* Sass か Less を使用している場合 */
@tailwind base;
@tailwind components;
@tailwind utilities;
@import "./custom-utilities";

レスポンシブバリアントを生成する

tailwind.config.js ファイルに定義したブレークポイントに基づいて独自ユーティリティクラスの レスポンシブバリアント を作成する場合、 @responsive ディレクティブ内でユーティリティをラップしてほしい:

@tailwind base;
@tailwind components;
@tailwind utilities;

@responsive {
  .rotate-0 {
    transform: rotate(0deg);
  }
  .rotate-90 {
    transform: rotate(90deg);
  }
  .rotate-180 {
    transform: rotate(180deg);
  }
  .rotate-270 {
    transform: rotate(270deg);
  }
}

Tailwind では独自のユーティリティクラス毎にプリフィクスがついたバージョンを自動的に生成するので、ブレークポイントに応じてスタイルを条件的に適用することが可能である:

<!-- デフォルトで180度回転させるが中画面以上では無効にする -->
<div class="rotate-180 md:rotate-0"></div>

さらに詳しい情報は レスポンシブデザイン を参照されたい。

擬似クラスバリアントを生成する

独自の 擬似クラスバリアント を作りたい場合は、 @variants ディレクティブでラップする:

@tailwind base;
@tailwind components;
@tailwind utilities;

@variants hover, focus {
  .rotate-0 {
    transform: rotate(0deg);
  }
  .rotate-90 {
    transform: rotate(90deg);
  }
  .rotate-180 {
    transform: rotate(180deg);
  }
  .rotate-270 {
    transform: rotate(270deg);
  }
}

Tailwind では独自のユーティリティクラス毎にプリフィクスがついたバージョンを自動的に生成するので、状態に応じてスタイルを条件的に適用することが可能である:

<div class="rotate-0 hover:rotate-90"></div>

擬似クラスバリアントは @variants ディレクティブ内で記述した順番と同じ順序で生成されるので、擬似クラスを別の擬似クラスより優先させたい場合は、必ず最後のほうに書くようにしてほしい:

/* フォーカスはホバーより優先される */
@variants hover, focus {
  .rotate-0 {
    transform: rotate(0deg);
  }
  /* ... */
}

/* ホバーはフォーカスより優先される */
@variants focus, hover {
  .rotate-0 {
    transform: rotate(0deg);
  }
  /* ... */
}

独自ユーティリティをレスポンシブかつ擬似クラスバリアント対応で生成したい時は @variants@responsive でラップしてほしい:

@tailwind base;
@tailwind components;
@tailwind utilities;

@responsive {
  @variants hover, focus {
    .rotate-0 {
      transform: rotate(0deg);
    }
    .rotate-90 {
      transform: rotate(90deg);
    }
    .rotate-180 {
      transform: rotate(180deg);
    }
    .rotate-270 {
      transform: rotate(270deg);
    }
  }
}

より詳しい情報については 擬似クラスバリアント を参照されたい。

プラグインを使う

CSSファイルへ直接ユーティリティクラスを記述する方法に加えて、プラグインを書くことで Tailwind にユーティリティクラスを追加することも可能である:

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addUtilities }) {
      const newUtilities = {
        '.rotate-0': {
          transform: 'rotate(0deg)',
        },
        '.rotate-90': {
          transform: 'rotate(90deg)',
        },
        '.rotate-180': {
          transform: 'rotate(180deg)',
        },
        '.rotate-270': {
          transform: 'rotate(270deg)',
        },
      }

      addUtilities(newUtilities, ['responsive', 'hover'])
    })
  ]
}

この方法は Tailwind 用のコンポーネントをライブラリとして公開したり、複数のプロジェクト間でコンポーネントを共有しやすくするのに適している。

詳しくは utility plugin documentation を参照されたい。

関数とディレクティブ

https://tailwindcss.com/docs/functions-and-directives

@tailwind

Tailwind の base, components, utilities そして screens の各スタイルをCSSに挿入するには @tailwind ディレクティブを使用する。

/**
 * Tailwind の基底スタイルとプラグインによって登録された追加の基底スタイルが挿入される
 */
@tailwind base;

/**
 * Tailwind のコンポーネント用のクラスとプラグインによって登録された追加のクラスが挿入される
 */
@tailwind components;

/**
 * Tailwind のユーティリティクラスとプラグインによって登録された追加のクラスが挿入される
 */
@tailwind utilities;

/**
 * 各ユーティリティクラスのレスポンシブの派生を挿入したい場所にこのディレクティブを書く
 * 
 * 省略した場合、デフォルトではスタイルシートの末尾にクラスを追加する
 */
 @tailwind screens;

@apply

自前のCSS内に既存のユーティリティクラスを展開するには @apply を使用する。

これはHTML内でユーティリティクラスの組み合わせが度々出現し新しいコンポーネントとして抽出したい場合に有用となる。

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

ルールは一行で綴ることもできるし @apply を複数回呼び出すこともできる:

.btn {
  @apply font-bold;
  @apply py-2;
  @apply px-4;
  @apply rounded;
}

@apply の宣言は通常のCSSの宣言と混ぜることも、もちろん可能である:

.btn:hover {
  @apply bg-blue-700;
  transform: translateY(-1px);
}

@apply でインライン化されたルールは特定の問題を回避するためにデフォルトで !important除去される:

/* ソース */
.foo {
  color: blue !important;
}

.bar {
  @apply foo;
}

/* 生成結果 */
.foo {
  color: blue !important;
}

.bar {
  color: blue;
}

もし既存のクラスを @apply して !important としたい場合は、 @apply の宣言の最後に !important を追加するだけである:

/* ソース */
.btn {
  @apply font-bold py-2 px-4 rounded !important;
}

/* 生成結果 */
.btn {
  font-weight: 700 !important;
  padding-top: .5rem !important;
  padding-bottom: .5rem !important;
  padding-right: 1rem !important;
  padding-left: 1rem !important;
  border-radius: .25rem !important;
}

Sass/SCSS を使用している場合は Sass の補完機能を使用してうまく動くようにする必要がある:

.btn {
  @apply font-bold py-2 px-4 rounded #{!important};
}

@apply は擬似クラスやレスポンシブのバリアントを使ったユーティリティクラスのインライン化には 非対応 なので注意されたい。
適宜擬似クラスやメディアクエリ内にバリアントを使用していないユーティリティクラスを apply してほしい。

/* 動かない: */
.btn {
  @apply block bg-red-500;
  @apply hover:bg-blue-500;
  @apply md:inline-block;
}

/* これならOK: */
.btn {
  @apply block bg-red-500;
}
.btn:hover {
  @apply bg-blue-500;
}
@screen md {
  .btn {
    @apply inline-block;
  }
}

ユーティリティクラスに プレフィクスを設定 していたとしても @apply を使用するときはプリフィクスを省略することが可能である:

/* 両方とも動く */
.btn {
  @apply tw-font-bold tw-py-2 tw-px-4 tw-rounded;
}
.btn {
  @apply font-bold py-2 px-4 rounded;
}

@variants

@variants ディレクティブで定義をラップすることで独自ユーティリティクラスの responsive, hover, focus, active 他の 擬似クラスバリアント を生成可能である。

@variants focus, hover {
  .rotate-0 {
    transform: rotate(0deg);
  }
  .rotate-90 {
    transform: rotate(90deg);
  }
}

このようなCSSが生成される:

.rotate-0 {
  transform: rotate(0deg);
}
.rotate-90 {
  transform: rotate(90deg);
}

.focus\:rotate-0:focus {
  transform: rotate(0deg);
}
.focus\:rotate-90:focus {
  transform: rotate(90deg);
}

.hover\:rotate-0:hover {
  transform: rotate(0deg);
}
.hover\:rotate-90:hover {
  transform: rotate(90deg);
}

バリアントは書いた順番の通りに生成される ということに注意されたい。

例えば hover より focus のユーティリティクラスが優先されるようにしたい場合は hover の あと に focus が来るようにしなければならない:

/* ソース */
@variants hover, focus {
  .banana {
    color: yellow;
  }
}

/* 出力結果 */
.banana {
  color: yellow;
}
.hover\:banana:hover {
  color: yellow;
}
.focus\:banana:focus {
  color: yellow;
}

@規則 である @variants は設定ファイルの variants セクションの値の全てとプラグインによって追加された カスタムバリアント をサポートする。

@responsive

@responsive ディレクティブの中に独自クラスの定義をラップすることでレスポンシブバリアントを生成することが可能である:

@responsive {
  .bg-gradient-brand {
    background-image: linear-gradient(blue, green);
  }
}

デフォルトのブレークポイントではこのように出力される:

.bg-gradient-brand {
  background-image: linear-gradient(blue, green);
}

/* ... */

@media (min-width: 640px) {
  .sm\:bg-gradient-brand {
    background-image: linear-gradient(blue, green);
  }
  /* ... */
}

@media  (min-width: 768px) {
  .md\:bg-gradient-brand {
    background-image: linear-gradient(blue, green);
  }
  /* ... */
}

@media (min-width: 1024px) {
  .lg\:bg-gradient-brand {
    background-image: linear-gradient(blue, green);
  }
  /* ... */
}

@media (min-width: 1280px) {
  .xl\:bg-gradient-brand {
    background-image: linear-gradient(blue, green);
  }
  /* ... */
}

レスポンシブバリアントはスタイルシート末尾の Tailwind の既存のメディアクエリに追加されるため、レスポンシブのプレフィクスが
付与されているクラスは同じCSSプロパティを対象とするレスポンシブではないクラスを常に無効化する。

@screen

@screen ディレクティブを使用すると独自のCSSの値を重複せずブレークポイントを名前で参照するメディアクエリを作成できる。
例えば sm640px のブレークポイントがあったとしてこれを参照するCSSを書く必要がある場合、このような値をコピーしなければいけない通常のメディアクエリ:

@media (min-width: 640px) {
  /* ... */
}

の代わりに @screen ディレクティブを使用してブレークポイントを名前で参照できる:

@screen sm {
  /* ... */
}

theme()

theme() 関数を使えばドット記法を使った Tailwind の設定値を取得することが可能である。

宣言の一部だけをテーマ設定から値を参照する必要がある場合 @apply の代わりに有用である:

.content-area {
  height: calc(100vh - theme('spacing.12'));
}

Tailwind では ネストオブジェクト記法 をデフォルトのカラーパレットの定義に使用しているのでネストされたカラーへアクセスする際ドット記法を使う必要があることに注意されたい。

:x: ハイフンを使用してネストされたカラー値へアクセスしてはいけない

.btn-blue {
  background-color: theme('colors.blue-500');
}

:o: ドット記法を使用してネストされたカラーへアクセスする

.btn-blue {
  background-color: theme('colors.blue.500');
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CSSの基礎知識

CSS基礎知識について

CSSとは Cascading Style Sheet の略である。
主にWebページをデザインするための言語で、文字の大きしゃ行間、色配置などHTMLのレイアウトに対してデザインの命令をする言語である。

CSSの基本文法

CSSは、セレクタ{プロパティ:値;}といった記述をする。

CSSの読み込み

CSSをhtmlに読み込むためには、htmlのheadタグないでlinkタグを用いて読み込むことができる。

CSSのセレクタの種類は数が多すぎるので今回は割愛する

便利だと思ったものは学習次第記述していく。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

レスポンシブデザイン入門

レスポンシブデザインとは

レスポンシブデザインとは、様々なデバイスや画面サイズに合わせて、コンテンツのレイアウトを調整するためのものです。

例えば、全体要素の幅を固定したサイトを作成した場合、それより画面幅が狭くなると、コンテンツの一部が隠れてしまいます。
ここにレスポンシブデザインを適用することで、画面のサイズに合わせて最適なレイアウトを組めるようになります。

メディアクエリの利用

メディアクエリ(Media Queries)とは

メディアクエリとは、ブラウザの画面サイズに応じてCSSのスタイルを設定できる手法です。

利用方法

viewportの設定

レスポンシブデザインを適用する準備として、<head>タグ内にviewportを設定しましょう。
viewportを設定しないと、スマートフォンやタブレットでの閲覧時にメディアクエリが正しく機能しません。

index.html
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
<head>

記述方法

メディアクエリは、@media (条件) { .... }という様に記述します。
指定された条件が当てはまるときにのみ{ }内のCSSが適用されます。

style.css
@media(max-width: 1000px) {
  /* 画面幅が1000px以下のときに適用するCSSを記載する */
}

メディアクエリの条件には、max-width(最大幅)、またはmin-width(最小幅)を指定できます。
max-width: ◯◯pxと指定すると、画面幅が◯◯px以下の時にCSSを適用できます。min-widthはその反対となります。

max-width: ◯◯px(またはmin-width: ◯◯px)のようにメディアクエリの条件を指定するとき、◯◯pxの部分をブレイクポイントと呼びます。
今回はスマートフォンの画面幅は670px以下、タブレットの画面幅は670px ~ 1000pxと想定して、ブレイクポイントを設定しましょう。

style.css
/* タブレット */
@media (max-width: 1000px) {
  h1 {
    color: blue;
  }
}

/* スマホ */
@media (max-width: 670px) {
  h1 {
    color: green;
  }
}

レイアウト崩れの回避

要素のwidth25%などの割合で指定されている場合、左右のpaddingなどがあると要素の幅の合計が100%を超えてしまい、レイアウトが崩れてしまうことがあります。
このようなレイアウト崩れは、box-sizing: border-box;を用いることで防ぐことができます。

box-sizing: border-box;

box-sizingborder-boxに指定すると、要素の幅(width)の合計にpaddingborderが含まれるようになります。そのため、paddingborderを追加した時に生じるレイアウト崩れを未然に防ぐことができます。
※ただし、marginborder-boxでの合計値に含まれないので注意

box-sizing: border-box;を指定するときは、*(アスタリスク)に対して指定することが推奨されています。
*はすべての要素に対してCSSを適用したい場合に用います。
border-boxをすべての要素に対して適用することで、レイアウトを管理しやすくなります。

style.css
* {
  box-sizing: border-box;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者でもわかる】要素の順番をPCとスマホで変える方法(レスポンシブ)

どうも7noteです。レスポンシブサイトを作る時、PCとスマホで要素の順番を入れ替える方法。

レスポンシブサイトを作る時、PCとスマホで要素の順番を変えたい時のCSSの書き方について記述していきます。
flexbox(フレックスボックス)を使って、順番を変更する方法です。

PCデザイン
mihon.png

スマホデザイン
mihon_sp.png

コーディング例

index.html
<h2>■レスポンシブデザインとは</h2>
<ul>
    <li class="reverse">
        <div class="text">
            <h3>point1</h3>
            <p>PCとスマホ両方に対応。<br>
            1つのHTMLファイルで済む。</p>
        </div>
        <img src="point1.jpg" alt="point1">
    </li>
    <li>
        <div class="text">
            <h3>point2</h3>
            <p>CSSファイルでメディアクエリを使い、
            cssを書き分けることができる。</p>
        </div>
        <img src="point2.jpg" alt="point2">
    </li>
</ul>
style.css
/* 共通CSS(主にスマホ用) */
body {
    background: #9afeff; /*背景色に青を指定*/
}

h2 {
    font-size: 20px; /*フォントサイズを指定*/
}
ul {
    margin: 0; /*ブラウザのCSSを無効化*/
    padding: 0; /*ブラウザのCSSを無効化*/
}
ul li .text h3 {
    font-size: 16px; /*文字サイズを16pxに指定*/
    font-weight: bold; /*太文字に指定*/
}
ul li .text p {
    font-size: 14px; /*フォントサイズを14pxに指定*/
}
ul li img {
    width: 100%; /*画像を幅いっぱいにする*/
}

    /* PC用CSS */
@media screen and (min-width:750px) {

    h2 {
    }
    ul {
        width: 500px; /*表示するエリアの幅を指定*/
    }
    ul li {
        display: flex; /*要素を横並びにする*/
    }
    ul .reverse {
        flex-flow: row-reverse; /*.reverseが付いている要素の順番を逆順に変える*/
    }
    ul li .text {
        width: 50%; /*テキストの幅を50%に指定*/
        padding-right: 10%; /*画像との距離を取るため10%を右側に指定*/
    }
    ul .reverse .text {
        padding-right: 0; /*右のpaddingを無効化*/
        padding-left: 10%; /*画像との距離を取るため10%を左側に指定*/

    }
    ul li img {
        width: 40%; /*画像の幅を40%に指定*/
    }
}

解説

フレックスボックスのflex-flow: row-reverse;を使うことで、並び順を逆順に変えることができます。

「1・2・3・4・5」と要素があれば、flex-flow: row-reverse;を指定することで
「5・4・3・2・1」という順番になります。

これでスマホとPCで要素の順番を変えることで、それぞれのデザインに合わせたCSSを書くことができます。

まとめ

flex-flowを使うには、必ずdisplay: flex;を指定してください。
レスポンシブサイトへの対応は必要な場面が多くあるので、覚えておきたい技術です。

おそまつ!

(コメント・質問・ソースの指摘等なんでもウェルカムです!初心者の方でも気軽に質問ください!)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

なぜかCSSがあたらないってとき

自分用メモみたいな感じですが

どう考えてもちゃんと書いてるのになぜか反映されず、キャッシュクリアしても chrome の検証にもそもそも出てこないってときは、一番基本に立ち返ってよーくコードを見ます。
タイプミスもしくは余計な文字が入っていることでしょう(}が一個多いとか)。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ヘッダーを固定する

画面上の要素を固定する

position: fixed;を使うと、常に要素を画面上の指定した位置に固定させておくことができます。
位置は、topleftrightbottomを使って指定します。

index.html
<header></header>
style.css
header {
 position: fixed;
 top: 0px;
 left: 0px;
}

要素の重なり順

positionを使用すると要素の重なりが生じます。
その結果、コンテンツ部分とヘッダーが重なった時に、ヘッダーが隠れてしまいます。
重なり順を指定して、ヘッダーが上に表示されるようにしましょう。

要素の重なり順を指定する

z-indexプロパティは、要素の重なりの順序を指定する際に使用します。
z-indexは整数値で指定し、値が大きいほど上に表示されます。
z-indexプロパティは必ずpositionプロパティと併用する必要があるので、注意しましょう。

style.css
header {
    position: fixed;
    top: 0px;
    left: 0px;
    z-index: 10;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

立体的なボタンを作ってみる

立体的なボタンを作る

<a>タグで立体的なボタンを作ってみます。
ボタンに影をつけることによって、立体的に見えるようにします。
また、ボタンにカーソルを当てた時の、カーソルの形も変更してみます。

影をつける

ボックスに影を付けるためにはbox-shadowプロパティを用います。
「影の位置」と「影の色」を指定します。

style.css
.box {
 box-shadow: 10px 10px #000000; /* 水平方向 垂直方向 色 */
}

垂直方向のみつけると立体っぽくなる

style.css
.btn {
 box-shadow: 0px 6px #000000;
}

cursor

cursorプロパティを用いることでマウスのカーソルが要素に乗ったときのカーソルの形を変えることができます。
タグによってcursorが初期状態で設定されているものもあり、例えば<a>タグは初期状態でpointerが設定されています。

style.css
.box {
 cursor: pointer; /* text, pointer, default */
}

ボタンを押したらへこむようにする

ボタンを押したときに以下の処理をすると、へこんで見えるようになります。
・影を消す
・ボタンの位置を影の分だけ下げる

active

セレクタにactiveを用いることで、要素がクリックされている間だけCSSを適用することができます。
セレクタ:activeというように指定します。

style.css
div:active {
 background-color: red;
}

CSSを打ち消す

box-shadow: none;とすると、影を消すことが出来ます。
このように多くのプロパティはnoneを指定することによって消すことができます。

style.css
.btn:active {
 box-shadow: none; /* 影を打ち消し */
}

position: relative;による位置の変更

要素の位置を変更する方法を学びましょう。
前回position: relative;position: absolute;の基準位置を決めるために使っていましたが、要素の位置を変更するためにも使うことが出来ます。
position: relative;topleftと併用すると、その要素を本来の位置からずらせます。

style.css
.btn:active {
 position: relative;
 top: 6px;
 left: 10px;
}

ボタンを凹ませる

クリック時に、以下の処理をすることによって、ボタンがへこんで見えるようになります。
box-shadownoneにする
position: relative;topによって影の分だけ位置を下げる

style.css
.btn:active {
 position: relative;
 top: 6px;
 box-shadow: none;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

画像と文字を重ねる

画像と文字を重ねる

通常、HTMLでは要素同士が重なって表示されることはありません。
しかし、CSSを用いることで要素同士を重ねることができます。

position: absolute;

HTMLの要素同士は通常重なって表示されることはありませんが、position: absolute;を使うと、要素同士を重ねて表示することが出来ます。
サイト全体の左上部分を基準とし、そこからの位置をtopleftを用いて指定します。また、rightbottomを併用することも可能です。

style.css
.box1 {
 position: absolute;
 top: 50px;
 left: 70px
}

.box2 {
 position: absolute;
 top: 120px;
 left: 140px;
}

基準位置の変更

position: absolute;の基準位置はサイト全体の左上部分ですが、この基準位置は変更することが出来ます。
基準としたい親要素にposition: relative;と指定すると、その要素の左上部分が基準位置となります。

index.html
<div class="parent">
 <img class="child" src="./assets/icon.jpg">
</div>
style.css
.parent {
 position: relative;
}

.child {
 position: absolute;
 top: 20px;
 left: 15px;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

相対的な大きさを指定する

相対的な大きさの指定

ボックスのwidthheightpxではなく%で指定すると、親要素に対してどのくらいの幅や高さを持つか指定することができます。

index.html
<div class="parent">
 <div class="child"></div>
 <div class="child"></div>
</div>
style.css
.child {
 width: 50%;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

文字の太さを指定する

font-weightプロパティを用いると文字の太さを変更することができます。normalまたはboldを指定します。
<h1>~<h6>の要素は初期状態でfont-weight: bold;となっているので、font-weight: normal;と指定すれば文字が細くなります。

style.css
h1 {
  font-weight: normal; /* デフォルトより細くなります */
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

<a>タグのクリックできる範囲

<a>タグはインライン要素なので、中身のテキストの部分しか大きさを持ちません。
その結果、<a>タグをクリックできる範囲はテキストの部分だけになってしまいます。
<a>タグをブロック要素にすると、大きさが親要素いっぱいに広がるので、全体をクリックできるようになります。

style.css
.header-right a {
  display: block;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

行間を指定する(line-height)

line-heightプロパティを使うと、行の高さを指定することができます。
値が大きいほど行間が大きくなります。

style.css
.text{
 line-height: 10px;
}

line-heightと縦の中央寄せ

line-heightプロパティは本来行間を調整するためのプロパティですが、要素の縦方向の中央に文字を配置するのにも使えます。
line-heightプロパティの「高さの中心」に文字が配置されるため、要素の高さとline-heightプロパティを同じ値にすると、文字がちょうど中央に配置されるようになります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

アニメーションをつける(transition)

transitionを使うとアニメーションをつけることができます。
「変化の対象」や、「変化にかかる時間」などを指定できます。
「変化の対象」にはcolorなどのプロパティを指定しますが、allを指定すると全てのプロパティに適用出来ます。
transitionは多くの場合hoverと組み合わせて使います。

index.html
<div>
 <h1> ゆっくり背景がつくよ</h1>
</div>
style.css
div {
 transition: all 1s; /* 変化の対象 変化の時間 */
}

div:hover {
 background-color: red;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

背景だけを透過させる

要素を透明にするにはopacityが利用できますが、
opacityには要素の中身全てを透明にするという性質があります。
背景のみを透明させたい時とかは、rgbaを利用しましょう。

rgb

rgbaを学ぶには、まずrgbというものを理解する必要があります。
rgbは色の指定の仕方の1つで、3つの値の組み合わせで表示する色を決めます。色を指定するときは#ffffffのようなカラーコードを使ってもrgbを使っても構いません。

style.css
.box {
 background-color: rgb(255, 147, 30);
}

.box{
 background-color: #ff931e;
}

rgba

色を透明にしたいときは色をrgbaで指定します。rgbaは4つの値をコンマ(,)区切りで入れます。4つ目の値が透明にする度合いで、0 ~ 1の数値で指定します(値が小さいほど透明になります)。
opacityプロパティは要素全体を透過させますが、rgbaを使うとその色だけを透明にすることが出来ます。

index.html
<div class="rgba-sample">
 <p>rgbaの透過</p>
</div>
<div class="opacity-sample">
 <p>opacityの透過</p>
</div>
style.css
/* 背景だけ透過される */
.rgba-sample {
 background-color: rgba(84, 190, 238, 0.5);
}

/* 要素の中身も透過される */
.opacity-sample {
 background-color: rgb(84, 190, 238);
 opacity: 0.5;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「margin: 0 auto」と 「text-align: center」の使い分け

要素を中央寄せにする方法として、margin: 0 autotext-align: centerがありますが、2つの使い分けについて説明します。
divなどで広い範囲を囲うようなブロック要素の場合はmarginを、テキストやボタンのようなインライン要素・インラインブロック要素の場合はtext-alignを使うようにしましょう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

角を丸める

角を丸めるにはborder-radiusプロパティを用います。
数字が大きいほど角が丸くなります。

index.html
<div class="box"></div>
style.css
.box {
  border-radius: 10px;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

カーソルが乗った時のスタイルを指定する

カーソルが乗ったときの状態をhoverと言います。
CSSで、セレクタ:hoverとすることで、カーソルが乗ったときのCSSを指定することができます。

style.css
div:hover {
  background-color: red; /* カーソルが乗った時に背景色を変更 */
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

displayプロパティの利用方法

ボタンを<a>タグで実装しようと思ったときなど、
<a>タグはインライン要素なのでwidthheightが指定できないなど不都合がある場合があると思います。
そんな時はdisplayプロパティでインラインブロック要素に変更することができます。

インラインブロック

ブロック要素とインライン要素の特徴を併せ持つインラインブロック要素というものがあります。
インラインブロック要素はインライン要素と同様に横に並びますが、ブロック要素のように幅や高さをもちます。

ブロック要素(<div>タグなど) インラインブロック要素 インライン要素(<a>タグなど)
width, height 指定できる 指定できる 指定できない
margin, padding 指定できる 指定できる 左右のみ指定できる
配置 縦並び 横並び 横並び

display

<a>タグは初期状態でインライン要素になっていますが、displayプロパティを使うと、インラインブロック要素に変更することができます。
displayプロパティはblock(ブロック要素), inline-block(インラインブロック要素), inline(インライン要素)を指定することができます。

style.css
a.btn {
  display: inline-block;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

文字の感覚を調整する

文字の間隔を調整する

letter-spacingプロパティを用いることで文字の間隔を指定することができます。

style.css
.letter-space{
 letter-spacing: 2px;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

文字の間隔を調整する

文字の間隔を調整する

letter-spacingプロパティを用いることで文字の間隔を指定することができます。

style.css
.letter-space{
 letter-spacing: 2px;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

要素を透過させる

要素を透過させる

opacityプロパティを使えば要素を透明にできます。
透明度は0.0(完全に透明) ~ 1.0(完全に不透明)の数値で指定します。

style.css
header {
  opacity: 0.9;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

要素を中央に配置する

中央に寄せるためにはmarginの左右にautoを指定する。
marginautoを指定するときは必ずwidthも併せて指定しましょう。
なお、上下のmarginautoは指定できません。

style.css
.box {
 width: 300px;
 margin: 0 auto;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WEBページの背景画像を指定する

背景画像はCSSで指定します。
CSSで背景画像を指定するにはbackground-imageプロパティを使います。
ただbackground-imageで指定された背景画像は表示範囲を埋め尽くすまで、繰り返し表示される性質があります。
そんなときはbackground-size: cover;を指定して、1枚の画像が表示範囲を埋め尽くすように画像の大きさを拡大縮小します。

style.css
.background {
 background-image: url(画像URL);
 background-size: cover;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む