Tailwind CSS ✖️ data属性 スタイルの動的変更をスッキリ書きたい🛁
はじめに
tailwindを数ヶ月使ってみました。
・jsファイルにそのまま書ける
・クラス名を考えなくていい
・デザインシステムとしても機能する
等々、個人的には大きく恩恵を感じています。
対して難点といえば、
やはり記述が長くなって見辛くなりやすいところでしょうか。
そこで、少しでも綺麗なコードになるのでは!というカスタマイズをご紹介します。
条件付きのスタイル適用
tailwindの記述方法でdata属性
に基づいた条件でスタイルの切り替えがあります。
data属性とは
HTML5 (en-US) は、特定の要素に関連付ける必要があるが、定義済みの意味を持つ必要のないデータに対する拡張性を念頭に置いて設計されています。 data-* 属性により、標準外の属性やDOM の追加プロパティなどの特殊な方法に頼らずに、標準的な意味のある HTML 要素に追加情報を格納することができます。
通常だとクラス名の中に条件分岐を記述することになるかと思います。
<input className={errors != null ? 'border-red' : '' } />
data属性
を使用すると、下記のように判定ロジックとスタイル設定を切り離すことができます!
(疑似要素・擬似クラスなどと同様の記述方法ですね。)
<input data-error={errors != null} className="data-error:border-red" />
書き方
パターン① 直接条件式を記述
- 任意の
data属性
を設定 - クラス名に
data-[条件]:スタイル
を記述
// bg-blueが適用される
<button data-color="blue" className="bg-red data-[color=blue]:bg-blue">
push
</button>
// 条件がfalseの場合、もしくは指定なしの場合、bg-blueは適用されない
<button data-color="red" className="bg-red data-[color=blue]:bg-blue">
push
</button>
<button className="bg-red data-[color=blue]:bg-blue">
push
</button>
パターン② data属性のセレクターを作成
上記のようにclassName
に直接条件式を記述することもできますが、
エラー時のスタイル変更など汎用的な条件がある場合は、ショートカットを作成すると便利です。
例えば、data-error
というdata属性
のセレクターを作成してみます。
tailwind.config.jsの設定
-
theme.data
セクションにerror
を作成
module.exports = {
theme: {
data: {
error: 'error=true'
},
},
}
使用箇所
- クラス名に
data-error:スタイル
を記述
// data-error属性がtrueの時、data-error:*のスタイルが適用される
<input data-error={errors != null} className="data-error:border-red data-error:text-red " />
さらにまとめる
@apply
でdata属性
適用時のスタイルをまとめると、さらにすっきりしますね✨
@tailwind components;
@layer components {
.error {
@apply font-semibold text-red border-red ;
}
}
<input data-error={errors != null} className="data-error:error" />
ここでは詳細は省きますが、group-*
やarea-*
なんかも同じ感覚で使えます!
組み合わせ
擬似要素・擬似クラスや別のdata属性
同士の組み合わせでもできます。(AND条件で判定されます)
// data-sundayがtrue、かつdata-currentMonthがtrueのとき、bg-pinkが適用される
<div
data-sunday={weekday === 0}
data-currentMonth={month === currntMonth}
className="data-[sunday=true]:data-[currentMonth=true]:bg-pink data-[sunday=true]:red" >
{day}
</div>
注意点
data属性
は文字列になるので、number
型をそのまま判定すると反映されません。
判定箇所にてダブルクォーテーション(シングルクォーテーションでも可)で囲ってあげる必要があります。
// statusはnumber型
// bgは反映されない
<div
data-status={status}
className={`rounded data-[status=0]:bg-gray data-[status=1]:bg-red data-[status=2]:bg-green`} >
{label}
</div>
// statusはnumber型
// classNameをテンプレートリテラルにして、ダブルクォーテーションを記述すると、bgが反映される
<div
data-status={status}
className={`rounded data-[status="0"]:bg-gray data-[status="1"]:bg-red data-[status="2"]:bg-green`} >
{label}
</div>
さいごに
いかがでしたでしょうか。
すこしでも誰かの役に立てれば幸いです。
これからも見やすいコーディングを心がけていきたいと思います💪🏻
Discussion