【第22回】見た目の希望をAIに伝わる形で書く|Tailwind CSS(嫁子が教えるTS講座)
今回のゴール
className="p-4 text-lg"のような書き方が読める- スマホ対応と、押したときの見た目を書ける
- 見た目の希望を、AIに伝わる言葉で言えるようになる
第4部の最後です。前回(フォーム)まで機能を作ってきたので、今回は見た目を整えます。全体の流れは講座の目次へ。
嫁子: 見た目の話って後回しにされがちだけど、AIに指示を出すうえでは意外と大事なところなの。
「もうちょっといい感じにして」で伝わらないのは、こっちの言葉が曖昧だからでしょ。今日はその言葉を持つ回だと思って。
① クラス名を並べて書く
第18回で作ったプロジェクトには、Tailwindが最初から入っています。使い方は className にクラス名を並べるだけです。
<button className="bg-blue-600 text-white px-4 py-2 rounded">
追加
</button>
読み方は、慣れると英語のままです。
| クラス | 意味 |
|---|---|
bg-blue-600 |
背景を青(600は濃さ) |
text-white |
文字を白 |
px-4 |
左右の内側の余白 |
py-2 |
上下の内側の余白 |
rounded |
角を丸く |
数字は「4px」ではなく目盛りです。p-4 は p-2 の倍の余白、という相対的な関係で覚えてください。
よく使うものだけ挙げておきます。
| 種類 | 例 |
|---|---|
| 余白(内側) | p-4 px-2 pt-8 |
| 余白(外側) | m-4 mt-2 |
| 文字 | text-sm text-2xl font-bold |
| 色 | text-gray-500 bg-white |
| 並べる | flex gap-2 items-center |
| 幅 | w-full max-w-md |
② なぜHTMLに直接書くのか
CSSファイルを分ける従来のやり方と比べると、これは逆行に見えます。実際、好き嫌いが分かれる方式です。
| CSSファイルを分ける | Tailwind | |
|---|---|---|
| 見た目を変える | ファイルを行き来する | その場で直す |
| クラス名を考える | 必要 | 不要 |
| 名前の衝突 | 起きうる | 起きない |
| コードの見た目 | すっきり | 長い |
「クラス名を考えなくていい」が、いちばん効きます。.item-row__name--done のような名前を考える作業が丸ごと消えます。
AIと組む場合の利点も大きいです。部品のファイルを見るだけで見た目が分かるので、AIも人も「どこを直せばいいか」を探さずに済みます。
嫁子: 長くなるのは事実だよ。1行に10個くらいクラスが並ぶこともあるからね。
ただ、CSSファイルを開いて該当箇所を探す時間と比べたら、こっちのほうが速いと思う。慣れの問題で、好みも分かれるってことは正直に言っておくね。
③ スマホ対応
画面幅で切り替えるときは、クラスの前に接頭辞を付けます。
<div className="text-sm md:text-base lg:text-lg">
接頭辞なしがスマホ、md: から先が広い画面です。小さい画面を既定として書き、大きくなったら上書きする、という順番になります。
<div className="flex flex-col md:flex-row gap-4">
これは「スマホでは縦積み、タブレット以上では横並び」です。
押したときや乗せたときの見た目も同じ形で書けます。
<button className="bg-blue-600 hover:bg-blue-700 disabled:opacity-50">
| 接頭辞 | いつ効くか |
|---|---|
md: lg: |
画面幅がその大きさ以上のとき |
hover: |
マウスを乗せたとき |
focus: |
入力欄を選択中 |
disabled: |
ボタンが無効のとき |
④ 条件で切り替える
第19回でやった書き方を、そのまま使います。
<li className={done ? "line-through text-gray-400" : ""}>
{item.name}
</li>
固定部分と切り替え部分を混ぜるときは、テンプレート文字列(バッククォート)を使います。
<li className={`py-2 ${done ? "line-through text-gray-400" : ""}`}>
買い物メモの打ち消し線は、これで実現できます。第10回でCSSクラスを付け外ししていた処理が、この1行に収まります。
⑤ 見た目をAIに頼むときの言葉
ここが今日の本題です。同じ依頼でも、言い方で結果が変わります。
| 曖昧な頼み方 | 伝わる頼み方 |
|---|---|
| もっと見やすくして | 行間を広げて、文字を少し大きくして |
| いい感じの余白にして | 内側の余白を p-4 にして |
| スマホでも崩れないように | スマホは縦積み、md: から横並びにして |
| ボタンを目立たせて | 背景を濃い青、文字を白、角を丸く |
「どうなってほしいか」を言えば十分です。クラス名まで指定できればより正確ですが、そこまでは要りません。
大事なのは方向を示すことです。「いい感じ」には方向がないので、AIは無難な既定値を選ぶしかなくなります。
嫁子: これ、第1回で言った「ディレクターになる」の話そのものだね。
自分で描けなくていいの。「そこ、もう少し余白を空けて」と言えれば。それが言えるようになったなら、今日の目的は達成だよ。
⑥ 設定ファイルの話(読み飛ばし可)
Tailwindは以前、tailwind.config.js という設定ファイルを作って色や余白を定義していました。現在の版(4系)では、CSSファイル側で設定します。
app/globals.css の先頭にこう書いてあるはずです。
@import "tailwindcss";
色を足したいときも、この近くに書きます。
ネットの記事に tailwind.config.js を作る手順が出てきたら、古い世代のものです。第18回で書いた通り、AIも古い書き方を混ぜることがあります。
嫁子: 手順どおりにやったのに動かない、っていう場面のかなりの割合がこれなの。世代違い。
「その手順は何年ごろのものですか」って聞いてみるのもアリだよ。古い前提で書いてないか確認するのは、こっちの仕事だからね。
つまずきポイント
クラス名を変数で組み立てると効かないことがあります。
const color = "blue";
<div className={`bg-${color}-600`}> // ✕ 効かない
Tailwindは書かれた文字列を探してCSSを作るので、組み立てられた名前は見つけられません。条件分岐で丸ごと書いてください。
<div className={isActive ? "bg-blue-600" : "bg-gray-300"}> // ○
スタイルが当たらないときは className の綴りを疑ってください。第19回で触れた通り、class と書いても静かに無視されます。
今回のまとめ
classNameにクラス名を並べる。数字は目盛り(p-4はp-2の倍)- 接頭辞なしがスマホ、
md:から先が広い画面。hover:も同じ形 - 条件による切り替えは、第19回の三項演算子がそのまま使える
- 見た目の依頼は方向を示す。「いい感じ」では伝わらない
- 設定ファイルは世代で変わる。
tailwind.config.jsが出てきたら古い記事
次にやること
第4部(フロントエンド)はこれで終わりです。次回から第5部・バックエンドとデータに入り、まずはサーバーサイドとは何をする場所かからです。
ここまでで作った買い物メモには、まだ大きな穴があります。ページを閉じると全部消えます。stateはブラウザのメモリ上にあるだけだからです。次の部では、それをどこかに保存する話に入ります。
今回の宿題:買い物メモの見た目を、Tailwindで整えてみてください。うまくいかなかったら、そのコードをAIに見せて「余白と文字サイズを整えて」と頼むのもアリです。返ってきたクラス名を読んで意味が分かれば、今日の内容は身についています。
嫁子: 第4部おつかれさま。ここまでで「画面を作る」側は一通り終わったよ。
次からは見えない側だから、また地味になる。でもページを閉じたら消えるアプリのままじゃ、使ってもらえないからね。もうひと息だよ。