Tailwind系のユーティリティCSSに慣れてくると、ある日ふと思います。
「もっと速くならないのか」「設定の自由度がもう少し欲しい」「使うクラスだけ生成してくれればいいのに」。 この欲が出てきたタイミングで候補に上がるのがUnoCSSです。
UnoCSSは、いわゆるAtomic CSSエンジンです。プリセットを組み合わせてルールを用意し、実際に使われたユーティリティだけを生成して配布するのが基本の考え方です。公式でも軽量さやビルドツールとの統合が強みとして説明されています。:contentReference[oaicite:0]{index=0}
この記事では、フロントエンドを勉強中の人が「何が便利で何が危ないか」を最短で掴めるように、そして実務の人が「導入後の事故」を避けられるように、導入手順から設計のコツ、メリットデメリット、さらに「やめるべき場面」までまとめます。 流し読みでも要点が拾える構成にしています。
先に結論 UnoCSSは誰に向くか
向く人
- ユーティリティCSSで開発速度を上げたい
- 使った分だけCSSを生成して成果物を軽くしたい
- プロジェクトに合わせてルールや記法を拡張したい
- ViteやNuxtなどモダンな環境で開発している
向かない人
- クラス名を動的に組み立てるUIが多く、静的解析が難しい
- チームがユーティリティCSSに不慣れで、運用ルールを決める時間がない
- 既存のBEM運用やデザイントークン運用が安定しており、変更コストが重い
UnoCSSは便利ですが、魔法の杖ではありません。ハマりどころもはっきりしています。そこを先に見せておくのが、現場の優しさです。
UnoCSSとは何か ざっくり理解
UnoCSSはフレームワークではなくエンジン
UnoCSSはReactでもVueでもありません。ユーティリティCSSを生成するエンジンです。 特徴は「プリセットでルールを足す」「使われた分だけ生成する」「ビルドツール統合が強い」。 公式でもTailwindがPostCSSプラグイン中心なのに対し、UnoCSSは複数の統合口を持つ点が説明されています。:contentReference[oaicite:1]{index=1}
プリセットで世界観を決める
UnoCSSは本体が軽く、実際のユーティリティはプリセットで供給されます。代表例として、デフォルトのpreset-uno、最小構成のpreset-mini、Tailwindライクなpreset-wind、属性モードのpreset-attributify、アイコンのpreset-iconsなどが公式に整理されています。:contentReference[oaicite:2]{index=2}
つまり、チームに合う味付けを選べるのが強みで、逆に言うと「何を採用するか」を決めないとブレます。
なぜUnoCSSを導入する必要があるのか
1 生成するCSSを必要最小限にしたい
ユーティリティCSSは便利ですが、全部入りを読み込むと成果物が増えがちです。 UnoCSSは使われた分だけ生成する思想なので、不要なCSSを抱えにくくなります。
2 開発体験を良くしたい
UnoCSSはビルドツールとの統合が深く、開発中の更新体験を重視しています。公式でもHMRや開発者体験に触れています。:contentReference[oaicite:3]{index=3}
3 Tailwindっぽさを保ちつつ、もっと自由にしたい
Tailwindのルールに乗るのが速い一方で、プロジェクト固有の都合が出ると回り道も増えます。 UnoCSSはルールやプリセットの組み合わせで、プロジェクトに寄せた設計がしやすいのが売りです。
UnoCSSで出来ること
ユーティリティCSSをオンデマンド生成
HTMLやJSXなどからクラスを抽出して、必要なスタイルだけ生成します。 この基本動作はUnoCSSの中核です。
Attributifyモードで属性スタイルが書ける
preset-attributifyを使うと、classではなく属性でユーティリティを指定できます。 例えば、classが長くなりすぎる問題を軽減できます。公式プリセットとして提供されています。:contentReference[oaicite:4]{index=4}
Iconsプリセットでアイコンをクラス一つで扱える
preset-iconsを使うと、アイコンを単一クラスのように扱えます。これも公式プリセットです。:contentReference[oaicite:5]{index=5}
Shortcutsでクラスの別名やセットを作れる
よく使う組み合わせをショートカットとして定義できます。 ユーティリティCSSの「長くなる問題」への現実的な解決策として強いです。
Transformerで記法を拡張できる
variant groupやディレクティブなど、書き味を拡張するTransformerがあります。コミュニティの一覧にも整理されています。:contentReference[oaicite:6]{index=6}
UnoCSSで出来ないこと ここで詰まる
動的に生成されたクラスは基本的に検出されない
UnoCSSはビルド時に抽出してCSSを生成します。つまり、コード上に静的に現れないクラスは検出されない可能性があります。 公式の抽出ガイドでも、この制約が明確に説明されています。:contentReference[oaicite:7]{index=7}
例として、次のようにクラス名を文字列結合するパターンは危険です。
// 危険な例(抽出が漏れる可能性)
const size = "12"
const cls = `text-${size}`
この場合はsafelistを使うか、動的でも抽出できる別の書き方に寄せる必要があります。 safelistは公式に設定項目として用意されています。:contentReference[oaicite:8]{index=8}
運用ルールなしだと、クラスの統一感が崩れる
自由度が高いのは長所ですが、裏を返すとプロジェクト全体の統一をルールで担保しないと崩れます。 ショートカットやプリセットの縛りを決めずに始めると、同じ見た目を別の書き方で実装する人が増えます。
CSS設計そのものが不要になるわけではない
ユーティリティCSSで書くと、BEMのような命名設計は薄くなります。 ただし、デザイントークン、スペーシング、カラー、タイポグラフィの設計が消えるわけではありません。 消えるのは「考えるコスト」ではなく「悩む場所が変わる」だけです。
導入方法 Viteで始める最短手順
1 ViteプロジェクトにUnoCSSプラグインを入れる
UnoCSSはVite統合が公式に用意されています。Viteプラグインはglobalモードがデフォルトで、エントリでuno.cssをimportする形が説明されています。:contentReference[oaicite:9]{index=9}
基本の流れはこうです。
npm i -D unocss
Vite設定でプラグインを追加します。
// vite.config.ts の例
import { defineConfig } from "vite"
import UnoCSS from "unocss/vite"
export default defineConfig({
plugins: [
UnoCSS(),
],
})
そしてエントリでCSSを読み込みます。globalモードではこれが必要です。:contentReference[oaicite:10]{index=10}
// main.ts など
import "uno.css"
2 uno.config.tsを作ってプリセットを決める
UnoCSSは専用の設定ファイルとしてuno.config.tsを推奨しています。IDE連携など体験が良くなるためです。:contentReference[oaicite:11]{index=11}
// uno.config.ts の例
import { defineConfig, presetUno, presetAttributify, presetIcons } from "unocss"
export default defineConfig({
presets: [
presetUno(),
presetAttributify(),
presetIcons(),
],
})
ここで何を入れるかが、プロジェクトの書き味を決めます。 最初はpreset-unoだけでもOKです。必要になったら足す方が安全です。
導入後にまずやること 運用を固める
ルール1 ショートカットの方針を決める
同じUIで毎回同じユーティリティを並べ始めたら、ショートカット化のタイミングです。
例えば、ボタンを毎回書くのが面倒ならこうします。
// uno.config.ts の例
export default defineConfig({
shortcuts: {
"btn": "px-4 py-2 rounded inline-flex items-center gap-2",
"btn-primary": "btn bg-blue-600 text-white hover:bg-blue-700",
},
})
ショートカットが増えすぎると、結局コンポーネントCSSと変わらない世界に戻ります。 おすすめは「頻出かつ意味が安定しているものだけ」です。
ルール2 動的クラスの扱いを決める
ReactやVueでは、状態によってクラスを切り替えるのが普通です。 ここで文字列結合をし始めると抽出漏れが起きます。UnoCSSの抽出制約として公式に説明があります。:contentReference[oaicite:12]{index=12}
対策の基本は次のどれかです。
- 候補を列挙して静的に書く
- safelistに入れる
- 動的でも抽出できる仕組みに寄せる
safelistは公式機能で、常に含めたいクラスを指定できます。:contentReference[oaicite:13]{index=13}
// uno.config.ts の例
export default defineConfig({
safelist: [
"text-12px",
"text-14px",
"text-16px",
],
})
safelistは便利ですが、増やしすぎると結局CSSが膨らみます。 「どうしても動的が必要な箇所だけ」に絞るのが実務的です。
ルール3 Inspectorや補助ツールを使うか決める
UnoCSSは開発者体験を重視しており、統合機能で便利に使えます。:contentReference[oaicite:14]{index=14}
ただ、チームの文化によっては補助ツールを増やしすぎると混乱します。 最初は最低限で始め、必要になったら足すが安全です。
メリット 使って分かる強み
必要な分だけ生成されるので成果物が読みやすい
本番で配布されるCSSが、実際に使ったユーティリティ中心になります。 不要な分を抱えにくいのは素直に強いです。
プリセットの組み合わせで設計を寄せられる
Tailwind風に寄せることも、最小構成にすることも、属性モードを採用することもできます。 公式プリセット群が揃っているので、選びやすいです。:contentReference[oaicite:15]{index=15}
Viteなどの統合が強く、開発中が快適
Vite統合ではHMRを含めた開発向けの仕組みが提供されています。:contentReference[oaicite:16]{index=16}
デメリット ここを知らないと現場で転ぶ
動的クラスの罠でスタイルが当たらない
抽出はビルド時。静的に見えないユーティリティは生成されません。公式の制約として明記されています。:contentReference[oaicite:17]{index=17}
この手のバグは厄介で、ローカルではたまたま当たっていたのに本番で崩れることもあります。 原因が「CSSが無い」ので、見た目の差分だけ出て調査が長引きます。
書き方が自由なので、レビューが弱いと統一感が崩れる
UnoCSSは柔らかい分、チームルールがないと、同じUIが別のクラス列で実装されます。 結果として保守が難しくなります。 ショートカット運用を早めに決めるのがおすすめです。
既存CSS資産が大きい現場は移行コストが高い
既にBEMや設計ルールが固まっている現場では、段階導入の計画がないとつらいです。 部分的な導入や、新規ページだけ導入など、逃げ道を用意すると成功率が上がります。
なぜ止める必要があるのか つまりUnoCSSをやめるべきケース
ここは大事なので正面から書きます。 UnoCSSは良い道具ですが、やめた方が速い場面があります。
1 動的クラスが多すぎてsafelistが増殖する
抽出の制約を回避するためにsafelistを大量に抱えると、オンデマンド生成の利点が薄れます。safelistは公式機能ですが、増えすぎると運用が重くなります。:contentReference[oaicite:18]{index=18}
2 チームがクラス直書き文化に合わない
ユーティリティ直書きはスピードが出ますが、好みが分かれます。 「HTMLが汚く見える」「デザインの責務が散る」という意見が強いチームだと、摩擦の方がコストになります。
3 デザインシステムが成熟しており、既存運用が安定している
既にコンポーネント単位でトークン化され、CSSやスタイル層が安定しているなら、無理に乗り換える理由は薄いです。 UnoCSSは新規や再設計のタイミングで輝きやすいです。
実務でのおすすめ構成 迷ったらこの形
まずはpreset-unoだけで始める
最初から全部盛りにすると、便利ですが運用が固まる前に選択肢が多すぎて迷います。 まずはpreset-unoで開始し、問題が見えたらpresetsやtransformerを足す。 この順番が失敗しにくいです。公式プリセットとしてpreset-unoが位置付けられています。:contentReference[oaicite:19]{index=19}
ショートカットはUI単位ではなく意味単位で
btn-primaryのように意味が安定するものは良いです。 一方で、card-23みたいな見た目由来のショートカットは増えると破綻しがちです。 コンポーネントの寿命に引きずられます。
動的クラスは列挙を基本にする
状態によってクラスを切り替えるなら、候補を配列や条件分岐で列挙する方が安全です。 safelistは最後の手段として使う。 このくらいの運用だと安定します。
最後に 読者に有益な関連情報
UnoCSSを選ぶ前に確認したいチェックリスト
- クラス名は動的生成が多いか 少ないか
- チームはユーティリティ直書きに抵抗がないか
- デザインのルールはトークン化されているか
- 既存CSS資産はどれくらいあるか
- ViteやNuxtなど統合しやすい環境か
Tailwindと比較して悩む人へ
Tailwindは完成度が高く、迷ったらまずTailwindでも十分に勝てます。 一方で、より自由な拡張や、プリセット設計でプロジェクト色を出したいならUnoCSSが効いてきます。 公式でも、Tailwindとの違いとして統合の柔軟性や開発体験の方向性が説明されています。:contentReference[oaicite:20]{index=20}
動的クラス問題は最初に潰すと後が楽
UnoCSS導入で最も多い事故は「本番でスタイルが当たらない」です。 原因は抽出漏れ。公式でも静的に現れないユーティリティは検出されない可能性があると明記されています。:contentReference[oaicite:21]{index=21}
だからこそ、導入初期に動的クラスの方針を決める。 これだけで成功率が上がります。
まとめ UnoCSSは速さと自由度が魅力 ただし運用設計が勝負
UnoCSSは、軽量なコアにプリセットを足していくAtomic CSSエンジンです。公式でもプリセットや統合の強みが整理されています。:contentReference[oaicite:22]{index=22}
メリットは、必要な分だけ生成できること、拡張が柔らかいこと、ビルド統合が強いこと。 デメリットは、動的クラスが苦手で抽出漏れが起きやすいこと、運用ルールがないと統一感が崩れること。
導入するなら、まずは小さく始める。 preset-unoで走り、ショートカットの方針を決め、動的クラスの扱いを固定し、必要になったら拡張する。 この順番で進めれば、UnoCSSは現場の味方になります。
そして最後に一言。 道具は強さより相性です。 UnoCSSが合う現場では、ちゃんと速いです。合わない現場では、ちゃんと重いです。 その見極めが出来たら、あなたはもう一段レベルが上がっています。

