2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Tailwind CSS】擬似クラス・擬似要素の指定方法

Last updated at Posted at 2024-07-07

はじめに

TailwindCSSのドキュメントを一読して学んだことをメモした記事です。
多少省略してあるので、全文を確認したい方はドキュメントを確認してください!

また、タイトルと一致するドキュメントにリンクを設定しておきました。
ドキュメントを確認したい場合はリンクから確認いただけます。

Handling Hover, Focus, and Other States

スタイルの指定方法は、擬似クラス・グループ化・親要素・子孫要素・擬似要素など様々な方法で対応できます。

利用できる具体的なクラスについては公式ドキュメントに「Quick reference」掲載されているのであえて書きません。

TailwindCSSではクラス名の先頭に修飾子を追加することで条件付きで適用できますと書かれています!

この条件付きでというところがポイントです。

TailwindCSSでは、既存のクラスにホバー状態を追加するのではなく、ホバー時のみ実行するクラス要素を追加されることを留意しなければなりません…

ホバーやフォーカスなどが「条件付きで適用できる」とは?

通常hoverの状態を指定したい場合は下記のように記述します。

.btn-primary {
  background-color: #0ea5e9;
}
.btn-primary:hover {
  background-color: #0369a1;
}

TailwindCSSで記述すると通常の状態のclassとホバーした時の状態のclassが定義されます。

.bg-sky-500 {
  background-color: #0ea5e9;
}
.hover\:bg-sky-700:hover {
  background-color: #0369a1;
}

上記の定義のされ方をドキュメントでは条件付きで適応できると表現されています。

修飾子は重ねられる

修飾子を複数かさなて定義することが可能です!

<button className="dark:md:hover:bg-fuchsia-600">
  Save changes
</butto

擬似クラス

普段スタイリングに利用している擬似クラスを修飾子として付与してスタイルを適用させます。
利用できるクラスについては一覧化されているので詳細はそちらを確認ください!

親の状態に基づく設定

親のclassNameにgroupを付与します。
子要素のclassにgroup-*のようなに指定することでスタイルを設定できます。

<a href="#" class="group">
  <p className="group-hover:text-white">sample text</p>
</a>

特定の親の状態に基づいたスタイルを適用する

グループされたネスト内でスタイルを分けたい時はグループに一意の名前をつけることで特定の親要素の状態に基づいてスタイルを設定できます。

<ul role="list">
  <li className="group/item hover:bg-slate-100">
    <a className="group/edit hover:bg-slate-200 group-hover/item:visible" href="">
      <span className="group-hover/edit:text-gray-700">Call</span>
    </a>
  </li>
</ul>

任意の値でも設定できます。

// classセレクターでの指定
<div className="group is-published">
  <div className="hidden group-[.is-published]:block">
    Published
  </div>
</div>

// &を利用することで詳細な設定できます
<div className="group">
  <div className="group-[:nth-of-type(3)_&]:block">
    Published
  </div>
</div>

兄弟要素の状態に基づいて要素にスタイルを適用する

<form>
  <label>
    <span>Email</span>
    <input type="email" class="peer"/>
    <p className="peer-invalid:visible">
      Please provide a valid email address.
    </p>
  </label>
</form>

peerは、peerの直後にpeer-*を付与した要素を設置することで利用できます。
順番を前後させてしまうと動作しないことに注意してください。

<p className="peer-invalid:visible">
  Please provide a valid email address.
</p>
<input type="email" className="peer"/>

peerも一意の名前をつけることで区別できたり、任意の値を指定できたりします!

見やすいようにclass属性やpeer以外のclassは排除してます
<fieldset>
  <legend>Published status</legend>
  <input className="peer/draft" />
  <label className="peer-checked/draft:text-sky-500">D</label>

  <input className="peer/published" />
  <label className="peer-checked/published:text-sky-500">P</label>

  <div className="peer-checked/draft:block">Drafts...</div>
  <div className="peer-checked/published:block">Your...</div>
</fieldset>

// 任意の値を設定するパターン
<form>
  <label for="email">Email</label>
  <input className="is-dirty peer" required />
  <div className="peer-[.is-dirty]:peer-required:block">This...</div>
</form>

<div>
  <input type="text" class="peer" />
  <div className="peer-[:nth-of-type(3)_&]:block">
    ....
  </div>
</div>

直接の子要素にスタイルを適用する

ユーティリティクラスを付与できることが望ましいとされていますが*を利用してスタイルを適用する必要がある場合には下記のように記述できます!

<ul className="*:p-4">
  <li>list item</li>
  <li>list item</li>
  <li>list item</li>
</ul>

親要素で*を利用して子要素に対してスタイルを適用させた場合、子要素でユーティリティクラスを適用してのclassのオーバーライドは機能しないので注意してください…

<ul className="*:p-4">
  <li className="p-2">list item</li>
  <li className="pt-6">list item</li>
  <li>list item</li>
</ul>

子孫要素に基づきスタイルを適用する

has-*を使うことで子孫要素の状態やコンテンツに基づいてスタイルを適用できます!

<label className="has-[:checked]:bg-indigo-50">
  Google Pay
  <input type="radio" />
</label>

[:checked]以外にも[:focus]has-[img]has-[a]で要素セレクタを使用してコンテンツの有無に基づいて要素のスタイルを設定できます。

grouppeerの親や兄弟要素の子孫要素に基づいてスタイルを適用させることも可能!

'group'を利用する場合は親をgroupを付与した上でスタイルを適用させたい要素にgroup-has-[a]:bg-indigo-50のように指定します。
親要素の中にaタグがある場合、バックグラウンドが設定した色になります。

peerも同様で、状態をウォッチしたい兄弟要素に対して'peer'を付与します。
スタイルを適用させたい要素にpeer-has-[:checked]:bg-indigo-50のように利用します。

ドキュメントにも書かれてますがformなどで利用するのが便利だと感じました!

<div>
  <label className="peer">
    <input type="checkbox" checked />
      Create a to do list
  </label>
  <p className="peer-has-[:checked]:bg-indigo-50">hoge</p>
</div>

擬似要素::before::after

下記のように記述すると::before::afterのスタイルを適用できます。

<p className="before:ml-4 before:text-red-500">hoge</p>
<p className="after:mr-4 after:text-red-500">hoge</p>

TailwindCSSではデフォルトでcontent: ''が設定されているため別の値が必要な場合の除いて指定する必要がありません!

content: ''がデフォルトで設定されているのは、TailwindCSSで用意されているpreflightで設定されているからです。
もし、無効にしていた場合はcontent-['']を設定する必要があります。

擬似要素よりもHTMLを利用する方が簡単

ドキュメントには::before::afterを利用するよりもHTMLを利用した方が可読性も上がり,
コードが短くなります。

DOMに表示させたくないなどのSEO的な要件があるかもしれませんが、空の要素が配置されることにSEO的なマイナスはありません。そのほかに::before::afterを必ず利用しなければならない理由がないのであればHTMLで実装した方が無難かと思います!

プレースホルダーテキストにスタイル適用

<input className="placeholder:text-slate-400" />

ファイル入力ボタンにスタイル適用

<input className="file:p-2 "/>

TailwindCSSのpreflightでファイル入力ボタンのborderはリセットされません…。
リセットや追加には明示的に指定する必要があります。

リストマーカーにスタイル適用

<ul role="list" className="marker:text-red-700">
  <li>list item</li>
</ul>

markerは継承可能な設計になっているため、<li>に直接指定できるだけでなく繰り返しを避けるために親で指定することもできます!

選択されたテキストへのスタイル適用

selection:は継承されるので設定した箇所の子要素全てに適用されます。

<div className="selection:bg-fuchsia-300">
  <p>hoge</p>
</div>

image.png

最初の行と最初の文字へスタイル適用

最初の行はfirst-line、最初の文字はfirst-letterを使う

<p className="first-line:uppercase"></p>
<p className="first-letter:text-xl"></p>

ダイアログの背景にスタイルを適用

backdrop:を利用するとdialog要素の背景スタイルを設定できます。

レスポンシブブレークポイントに対するスタイル適用

設定するスタイルの前にmd:lg:を付与することで実現できます。

<div className="p-4 md:p-6 lg:p-8"></div>

ダークモードへのスタイル適用

ライトモードは通常のclassをしようし、ダークモードのみdark:を利用します。

<div className="text-black dark:text-white"></div>

アニメーションの無効設定に対してスタイルを適用

ユーザーがアニメーション削減を要求した場合のスタイルを設定できます。

<svg className="motion-reduce:hidden" />

開発者ツールで「prefers-reduced-motion:reduce」をエミュレートするとスピナーが非表示になります。

エミュレートをするには開発者ツールを開いて、レンダリングタブを探してください。
スクロールしていくと「CSSメディア特製 prefers-contentをエミュレートする」が見つかるはずです!

image.png

motion-safeを利用するとモーションの削減が要求されなかった場合のスタイルを定義できます。

コントラストの増減のスタイルを適用

高いコントラストを要求された場合のスタイルはcontrast-more:、低いコントラストの要求に対してのスタイル適用はcontrast-lessで対応できます。

<p className="contrast-more:opacity-100">hoge</p>
<p className="contrast-less:opacity-100">hoge</p>

強制カラーモードへスタイルを適用

forced-colors:を利用してスタイルを適用させます。

<p className="forced-colors:black">hoge</p>

ビューポートの方向でスタイルを適用

画面が立て向きの場合と横向きの場合でスタイルを分けられます。

<p className="portrait:hidden">hoge</p>
<p className="landscape:hidden">hoge2</p>

ドキュメントが印刷されている時のみスタイルを適用

<p className="print:block">hoge</p>

ブラウザのサポート状況に基づいてスタイルを適用

プロパティがブラウザでサポートされているかどうかをチェックします。

<p className="supports-[display:grid]:grid">hoge</p>

また、tailwind.configでショートカットを設定することが可能です。

module.exports = {
  theme: {
    supports: {
      grid: 'display: grid',
    },
  },
}

- <p className="supports-[display:grid]:grid">hoge</p>
+ <p className="supports-grid:grid">hoge</p>

まとめ

「そんな指定方法があるのか!」とかなり勉強になりました!

細かな仕様を理解しておくことで誤った記述がなくなったり、スタイルが当たらなかったりを防ぐことになると思うので一度確認してみることをオススメします!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?