dev TailwindCSS

Tailwind CSS Inline Styles 完全ガイド - いつインラインスタイルを使うべきか

Tailwind CSS inline styles(インラインスタイル)を実践的に学ぶ完全ガイド。動的な値の扱い方、CSS変数との組み合わせ、ReactなどのフレームワークでのインラインスタイルとTailwindの使い分けまで、実際のコード例で詳しく解説します。

読者がこの記事から得られる知識

この記事では、Tailwind CSS inline styles(インラインスタイル)を使うべき場面と使い分けの判断基準を実践的に学びます。

この記事で学べること:

  • Tailwind CSSプロジェクトでインラインスタイルを使うべき3つの主要なケース
  • 動的な値(データベース、API、ユーザー入力)をスタイルに反映する正しい方法
  • CSS変数とTailwindクラスを組み合わせる高度なパターン
  • ReactなどのフレームワークでのインラインスタイルとTailwindの使い分け
  • 任意の値(arbitrary values)とインラインスタイルの違いと使い分け

実際にコードを書いて、ブラウザで結果を確認しながら学習を進めていきます。「APIから取得した色をどう適用するのか?」「なぜclassName={bg-[${color}]}は動かないのか?」といった疑問が解消されます。

今回ハンズオンした内容

今回は、Tailwind CSS公式ドキュメントの「When to use inline styles」セクション(https://tailwindcss.com/docs/styling-with-utility-classes#when-to-use-inline-styles)を参照しながら、inline styles(インラインスタイル)の使い方を実践しました。CSS フレームワークであるTailwind CSSでは、ユーティリティクラスが基本ですが、動的な値が必要な場合など、インラインスタイルが適切な場面があります。

ファイル構造

tailwindcss/
├── src/
│   ├── index.html
│   ├── input.css
│   └── output.css
├── package.json
├── package-lock.json
└── README.md

ステップ1: インラインスタイルを使ったサンプルコードの追加

実行する操作:

src/index.html に、インラインスタイルの使用例を追加します。

  <!-- Complex selectors サンプル -->
  <div class="mt-8 mx-auto max-w-sm">
    <!-- 既存のコード -->
  </div>

<!-- ↓ ここから追加 --> <!-- When to use inline styles サンプル --> <div class="mt-8 mx-auto max-w-sm"> <h2 class="text-2xl font-bold mb-4 text-gray-900 dark:text-white">When to Use Inline Styles</h2>

<!-- 1. 動的な色(インラインスタイルを使用) --> <div class="mb-6"> <p class="text-sm font-semibold mb-2 text-gray-700 dark:text-gray-300">1. Dynamic Colors</p> <!-- ユーザーが選んだ色をインラインスタイルで適用 --> <button style="background-color: #ff6b6b; color: white;" class="px-6 py-3 rounded-lg font-semibold hover:opacity-90" > User's Custom Color </button> </div>

<!-- 2. 複雑な任意の値(インラインスタイルの方が読みやすい) --> <div class="mb-6"> <p class="text-sm font-semibold mb-2 text-gray-700 dark:text-gray-300">2. Complex Grid (Inline Style)</p> <div style="display: grid; grid-template-columns: 2fr max(0, 1rem) calc(1rem + 10px); gap: 1rem;" class="bg-white dark:bg-slate-800 p-4 rounded-lg" > <div class="bg-blue-500 text-white p-2 rounded text-center text-sm">2fr</div> <div class="bg-green-500 text-white p-2 rounded text-center text-sm">max</div> <div class="bg-red-500 text-white p-2 rounded text-center text-sm">calc</div> </div> </div>

<!-- 3. CSS変数とTailwindの組み合わせ --> <div class="mb-6"> <p class="text-sm font-semibold mb-2 text-gray-700 dark:text-gray-300">3. CSS Variables + Tailwind</p>

<!-- 修正版:CSS変数をstyle属性で直接使う --> <button style="background-color: var(--btn-bg); color: var(--btn-text); --btn-bg: #4ecdc4; --btn-bg-hover: #45b7af; --btn-text: white;" class="mb-2 w-full px-6 py-3 rounded-lg font-semibold transition-colors hover:opacity-90" onmouseover="this.style.backgroundColor='#45b7af'" onmouseout="this.style.backgroundColor='#4ecdc4'" > Teal Theme (CSS Vars) </button>

<!-- シンプルな方法:インラインスタイルだけで --> <button style="background-color: #f7b731; color: white;" class="w-full px-6 py-3 rounded-lg font-semibold transition-colors hover:opacity-90" > Orange Theme (Inline Style) </button> </div>

<!-- 4. 実務での使用例シミュレーション --> <div class="mb-6"> <p class="text-sm font-semibold mb-2 text-gray-700 dark:text-gray-300">4. Real-world Example</p> <div class="bg-white dark:bg-slate-800 p-4 rounded-lg"> <p class="text-xs text-gray-500 dark:text-gray-400 mb-2"> ※ 実際はJavaScriptでAPIから取得した色を設定 </p> <!-- シンプルな方法で表示 --> <div class="space-y-2"> <button style="background-color: #1da1f2; color: white;" class="w-full px-4 py-2 rounded-lg font-medium hover:opacity-90" > Primary Action </button> <button style="background-color: #14171a; color: white;" class="w-full px-4 py-2 rounded-lg font-medium hover:opacity-90" > Secondary Action </button> </div> </div> </div> </div> <!-- ↑ ここまで追加 -->

</body> </html>

操作の意味:

4つの異なるインラインスタイルの使用例を追加しています:

  • 動的な色:ユーザーが選んだカスタムカラー
  • 複雑なグリッド:読みやすさのためのインラインスタイル
  • CSS変数との組み合わせ:動的なテーマカラー
  • 実務での使用例:APIから取得したブランドカラー

操作を実行する意図:

Tailwind CSSプロジェクトでも、インラインスタイルが適切な場面があることを実証します。特に動的な値(データベース、API、ユーザー入力)には、必ずインラインスタイルを使う必要があります。

実行結果:

ブラウザで表示すると、以下のように4つの例が表示されます。

4つの異なるインラインスタイルの使用した画像

実行結果の解説:

期待通り、すべてのインラインスタイルが正しく適用されています:

  1. Dynamic Colors - #ff6b6bのカスタムカラーが適用されています。ホバーすると少し透明になります
  2. Complex Grid - 複雑なgrid-template-columnsがインラインスタイルで指定され、3つの列が異なる幅で表示されています
  3. CSS Variables + Tailwind - Teal Theme(青緑)とOrange Theme(オレンジ)のボタンが表示され、ホバーで変化します
  4. Real-world Example - Primary(青)とSecondary(黒)のボタンが表示され、APIから取得したブランドカラーを想定しています

これらすべてが、インラインスタイルを使って実現されています。

ステップ2: ReactでのインラインスタイルとTailwindの使い分けを理解する

実行する操作:

Reactでの正しい書き方を理解します。

誤った例:

// これは動かない
const userColor = "#ff6b6b";
<button className={`bg-[${userColor}]`}>

正しい例:

// インラインスタイルを使う
const userColor = "#ff6b6b";
<button style={{ backgroundColor: userColor }}>

操作の意味:

動的な値には、Tailwindの任意の値(bg-[${userColor}])ではなく、インラインスタイル(style={{ backgroundColor: userColor }})を使う必要があります。

操作を実行する意図:

よくある間違いを理解し、正しい方法を身につけることが重要です。Tailwindはビルド時にクラスをスキャンするため、実行時に生成される文字列は検出できません。

実行結果の解説:

なぜbg-[${userColor}]は動かないのか:

  1. Tailwindはビルド時にクラスをスキャン
  2. bg-[${userColor}]は実行時に文字列として生成される
  3. ビルド時には存在しないため、CSSが生成されない
  4. 結果として、スタイルが適用されない

正しい方法:

動的な値(API、データベース、ユーザー入力)には、必ずインラインスタイルを使います。

// 動的な値 → インラインスタイル
<button style={{ backgroundColor: userColor }}>

// 静的な値 → Tailwindクラス
<button className="bg-blue-500">

// 静的な任意の値 → Tailwindの任意の値
<button className="bg-[#1877f2]">

ハンズオンの中で私が疑問に感じた点や失敗した点

よくある疑問

疑問1: Reactの場合、<button style="background-color: ${userColor}">と書けば動的な値を使えますか?

解決手段:

いいえ、これは動きません。HTMLの書き方とReactの書き方は異なります。

HTMLの書き方:

<!-- これはただのテキスト。変数として動かない -->
<button style="background-color: ${userColor}">

→ JavaScriptで後から設定する必要がある

Reactの正しい書き方:

<!-- これが正しい!変数が展開される -->
<button style={{ backgroundColor: userColor }}>

なぜ二重の波括弧?

style={{ backgroundColor: userColor }}
      ↑                              ↑
      |                              |
   外側の {} → JSXの中でJavaScriptを使う
         内側の {} → JavaScriptのオブジェクト

重要なポイント:

  • HTMLのstyle属性:文字列を指定(style="color: red;"
  • Reactのstyle属性:オブジェクトを指定(style={{ color: 'red' }}
  • プロパティ名はキャメルケース(backgroundColor

疑問2: インラインスタイルとTailwindの任意の値(arbitrary values)の違いは何ですか?

解決手段:

両者は似ていますが、使える場面が異なります。

任意の値(Arbitrary values):

<button class="bg-[#1877f2]">
  • ビルド時に決まる静的な値にのみ使える
  • ブランドカラーなど、変更されない固定値に適している

インラインスタイル:

<button style={{ backgroundColor: userColor }}>
  • 実行時に決まる動的な値に使える
  • API、データベース、ユーザー入力など、変化する値に適している

使い分けの判断基準:

値の種類使うべき方法
静的な値(テーマにある)Tailwindのテーマ値(bg-blue-500
静的な値(テーマにない)任意の値(bg-[#1877f2]
動的な値インラインスタイル(style={{ backgroundColor: userColor }}

疑問3: CSS変数をインラインスタイルで設定して、Tailwindクラスで参照できますか?

解決手段:

理論的には可能ですが、Tailwind v4では構文が変更され、実務では確実性を考えてインラインスタイルだけで完結させる方が安全です。

公式ドキュメントの例(理論的には可能):

<button
  style={{
    "--bg-color": buttonColor,
    "--bg-color-hover": buttonColorHover,
    "--text-color": textColor,
  }}
  className="bg-(--bg-color) text-(--text-color) hover:bg-(--bg-color-hover)"
>
  {children}
</button>

実務で推奨される方法:

<button
  style={{
    backgroundColor: buttonColor,
    color: textColor,
  }}
  className="px-6 py-3 rounded-lg font-semibold hover:opacity-90"
>
  {children}
</button>

理由:

  • Tailwind v4でのCSS変数参照の構文(bg-(--変数名))は、実装が不安定な可能性がある
  • インラインスタイルだけで完結させれば、確実に動作する
  • Tailwindクラスは、レイアウトや間隔など、動的でない部分に使う

よくある失敗

失敗1: 動的な値に任意の値を使おうとする

誤った例:

const userColor = "#ff6b6b";
<button className={`bg-[${userColor}]`}>  // これは動かない!

エラーメッセージ/結果:
ボタンの背景色が適用されません。Tailwindはビルド時にクラスをスキャンするため、実行時に生成される文字列は検出できません。

模範例:

const userColor = "#ff6b6b";
<button style={{ backgroundColor: userColor }}>  // これが正しい

ポイント:
動的な値(データベース、API、ユーザー入力など)には、必ずインラインスタイルを使います。任意の値はビルド時に決まる静的な値にのみ使えます。

失敗2: Reactでstyle属性に文字列を渡す

誤った例:

const styleString = "background-color: #ff6b6b; color: white;";
<button style={styleString}>  // これは動かない

エラーメッセージ/結果:
Reactエラー:「style prop expects a mapping from style properties to values, not a string.」

Reactのstyle属性は文字列ではなく、オブジェクトを期待します。

模範例:

<button style={{ backgroundColor: '#ff6b6b', color: 'white' }}>

ポイント:
ReactのstyleはHTMLとは異なり、オブジェクト形式で指定します。プロパティ名はキャメルケース(backgroundColor)を使います。

失敗3: インラインスタイルでhover状態を指定しようとする

誤った例:

<button style={{ backgroundColor: '#ff6b6b', ':hover': { backgroundColor: '#ff5252' } }}>

エラーメッセージ/結果:
ホバー時のスタイルが適用されません。インラインスタイルでは疑似クラス(:hoverなど)を使えません。

模範例1: Tailwindクラスを使う

<button 
  style={{ backgroundColor: '#ff6b6b' }}
  className="hover:opacity-90"
>

模範例2: JavaScriptでイベントハンドラを使う

<button 
  style={{ backgroundColor: buttonColor }}
  onMouseOver={(e) => e.target.style.backgroundColor = hoverColor}
  onMouseOut={(e) => e.target.style.backgroundColor = buttonColor}
>

ポイント:
インラインスタイルでは疑似クラスを使えません。ホバー状態は、Tailwindクラス(hover:opacity-90)またはJavaScriptのイベントハンドラで対応します。

失敗4: すべてのスタイルをインラインで書く

誤った例:

<button style={{
  backgroundColor: '#ff6b6b',
  color: 'white',
  padding: '0.75rem 1.5rem',
  borderRadius: '0.5rem',
  fontWeight: '600',
}}>

エラーメッセージ/結果:
動作はしますが、Tailwindを使う意味がなくなります。レイアウトや間隔など、動的でない部分はTailwindクラスを使うべきです。

模範例:

<button 
  style={{ backgroundColor: userColor, color: textColor }}
  className="px-6 py-3 rounded-lg font-semibold"
>

ポイント:
動的な部分(色など)はインラインスタイル、静的な部分(レイアウト、間隔、角丸など)はTailwindクラスを使います。これにより、両方の利点を活かせます。

失敗5: .NET MAUIでHTMLの書き方をそのまま使う

誤った例:

// HTMLの書き方をそのまま使おうとする
string html = "<button style='background-color: ${userColor}'>Click me</button>";

エラーメッセージ/結果:
${userColor}はただのテキストとして表示され、変数として認識されません。

模範例:

// C#の文字列補間を使う
string userColor = "#ff6b6b";
string html = $"<button style='background-color: {userColor}'>Click me</button>";

// またはXAMLを使う
var button = new Button
{
    Text = "Click me",
    BackgroundColor = Color.FromArgb(userColor)
};

ポイント:
各言語・フレームワークに応じた正しい構文を使います。C#では${}ではなく、{}で変数を埋め込みます。

記載内容の翻訳

公式ドキュメント(https://tailwindcss.com/docs/styling-with-utility-classes#when-to-use-inline-styles)の内容を日本語で読み取れるようにします。

When to use inline styles

Tailwind CSSプロジェクトでは、インラインスタイルは依然として非常に有用です。特に、値が動的なソース(データベースやAPIなど)から来る場合に役立ちます:

branded-button.jsx

export function BrandedButton({ buttonColor, textColor, children }) {
  return (
    <button
      style={{
        backgroundColor: buttonColor,
        color: textColor,
      }}
      className="rounded-md px-3 py-1.5 font-medium"
    >
      {children}
    </button>
  );
}

非常に複雑な任意の値の場合、クラス名として整形すると読みづらくなる場合にもインラインスタイルを使うことがあります:

<div class="grid-[2fr_max(0,var(--gutter-width))_calc(var(--gutter-width)+10px)]">
<div style="grid-template-columns: 2fr max(0, var(--gutter-width)) calc(var(--gutter-width) + 10px)">
  <!-- ... -->
</div>

別の便利なパターンは、インラインスタイルを使って動的なソースに基づいてCSS変数を設定し、その後ユーティリティクラスでその変数を参照することです:

branded-button.jsx

export function BrandedButton({ buttonColor, buttonColorHover, textColor, children }) {
  return (
    <button
      style={{
        "--bg-color": buttonColor,
        "--bg-color-hover": buttonColorHover,
        "--text-color": textColor,
      }}
      className="bg-(--bg-color) text-(--text-color) hover:bg-(--bg-color-hover) ..."
    >
      {children}
    </button>
  );
}

今回のまとめ

お疲れさまでした!今回は、Tailwind CSS inline styles(インラインスタイル)について実践的に学習しました。

今回学習したこと:

  • Tailwind CSS inline styles(インラインスタイル)は、動的な値(データベース、API、ユーザー入力)を扱う場合に必須で、任意の値(arbitrary values)はビルド時に決まる静的な値にのみ使える
  • Reactなどのフレームワークでは、style={{ backgroundColor: userColor }}のようにオブジェクト形式でインラインスタイルを指定し、プロパティ名はキャメルケースを使う
  • 実務では、動的な部分(色など)はインラインスタイル、静的な部分(レイアウト、間隔など)はTailwindクラスを使い分けることで、両方の利点を活かせる

これで「Styling with Utility Classes」の主要セクションの学習が完了しました。お疲れさまでした!また別の記事でお会いしましょう!

-dev, TailwindCSS