🌙

shadcn/ui を日本語に最適化した UI コンポーネントセット kasumi/ui を作った

に公開

導入

shadcn/ui は素晴らしい。コピペで使えて、カスタマイズも自由。自分もずっと愛用している。

ただ、日本語で UI を組んでいると、微妙に「しっくりこない」瞬間がある。行間が詰まって読みにくかったり、ボタンのテキストが窮屈だったり。英語前提で作られているから当然といえば当然なんだけど、毎回 className で調整するのが地味にストレスだった。

同じことを感じている人は少なくないんじゃないかと思い、日本語向けの調整を入れたコンポーネントセット kasumi/ui を作った。shadcn/ui と同じくコピペで導入でき、日本語の行間やサイズ感があらかじめ調整済みになっている。

この記事では、具体的にどこをどう変えたのかを紹介する。

https://github.com/ashunar0/kasumi-ui
https://kasumi-ui.vercel.app/

具体的な調整ポイント

1. 本文の行間

日本語テキストで一番影響が大きいのが行間(line-height)。

shadcn/ui のデフォルトは leading-normal、つまり line-height: 1.5。英語ならこれで十分だけど、日本語の場合は漢字・ひらがな・カタカナが混在するぶん、1.5 だと行同士がくっついて見えてしまう。

kasumi/ui では、用途に応じて2段階の行間トークンを用意した。

用途 トークン line-height 使いどころ
本文(記事・説明文) text-body ×2.5 長めの文章、説明テキスト
UI文(アプリ内テキスト) text-ui ×2.0 カード内の説明、フォームの補足

参考にしたのは JLREQ(日本語組版処理の要件)。JLREQ では本文の行間として文字サイズの50%〜100%(つまり line-height 1.5〜2.0)が推奨されている。実際にいくつかの値を試してみて、画面上で読みやすいと感じた値に落ち着いた。

見出し(h1〜h4)はデフォルトの行間のまま。見出しは1〜2行で完結するため、広げる必要がない。

2. ボタン

shadcn/ui のデフォルトボタンと比較すると、変更点は3つ。

shadcn/ui kasumi/ui
高さ h-9(36px) h-10(40px)
左右パディング px-4(16px) px-5(20px)
フォントウェイト font-medium(500) font-semibold(600)
角丸 rounded-md(6px) rounded-lg(8px)

日本語は英語に比べて1文字あたりの面積が大きい。同じ text-sm(14px)でも、漢字やひらがなは英字より視覚的に重い。そのため、少し余白を広げて文字が窮屈にならないようにした。

font-mediumfont-semibold にしたのは、日本語テキストのボタンは太めの方がクリッカブルに見えると感じたから。英語だと medium で十分なんだけど、日本語だとやや弱く見える。

3. フォーム入力

shadcn/ui の Input は outline(ボックス型)のみ。kasumi/ui では underline variant を追加した。

// shadcn/ui — outline のみ
<Input placeholder="例:チームランチ" />

// kasumi/ui — underline がデフォルト
<Input placeholder="例:チームランチ" />

// outline も使える
<Input variant="outline" placeholder="例:チームランチ" />

underline スタイルをデフォルトにした理由は、日本語の UI ではボックス型よりもアンダーライン型の方がすっきり見えるケースが多いから。特にフォームフィールドが縦に並ぶ場面では、ボーダーの情報量が減って視線の流れがスムーズになる。

もちろん好みの問題でもあるので、variant="outline" で従来のボックス型も使える。

設計の考え方

フォントサイズは Modular Scale で決める

kasumi/ui のフォントサイズは「なんとなく」ではなく、Minor Third(×1.2) の Modular Scale で決めている。基準サイズ(16px)に 1.2 を掛けていくだけ。

16px × 1.2⁰ = 16px  (本文)
16px × 1.2¹ = 19px  (H4)
16px × 1.2² = 23px  (H3)
16px × 1.2³ = 28px  (H2)
16px × 1.2⁴ = 33px  (H1)

比率の候補はいくつかあったけど、日本語 UI との相性で選んだ。

比率 名前 不採用理由
1.125 Major Second メリハリが弱い
1.2 Minor Third 採用。バランスが良い
1.25 Major Third H1 が大きすぎる
1.333 Perfect Fourth 段階のジャンプが大きすぎる

ポイントは、全段を使う必要がないこと。アプリ UI では H3〜H4 が中心で、H1 は LP やヒーローセクション用。日本語は漢字の画数が多いぶん、大きすぎる見出しは圧迫感が出やすい。1.2 の比率なら H1(33px)でもギリギリ落ち着いて見える。

Tailwind CSS 4 の @theme inline でカスタムトークンとして登録しているので、text-h1text-body のようなユーティリティクラスとしてそのまま使える。

@theme inline {
  --text-body: 1rem;        /* 16px */
  --text-body--line-height: 2.5;
  --text-h1: 2.0625rem;     /* 33px */
  --text-h2: 1.75rem;       /* 28px */
  --text-h3: 1.4375rem;     /* 23px */
  --text-h4: 1.1875rem;     /* 19px */
}

自作 vs Radix UI の使い分け

kasumi/ui の 27 コンポーネントのうち、約半分が自作、残りが Radix UI ベース。使い分けの基準はシンプルで、CSS と HTML だけで完結するものは自作、それ以外は Radix

自作 Radix UI
Button, Input, Badge, Card, Alert, Progress, Separator, Skeleton... Dialog, Select, Tooltip, DropdownMenu, Accordion, Toast, Tabs...

Radix を使うのは、フォーカストラップ、Portal、スクロールロック、キーボードナビゲーションなど、正しく実装するのが難しい振る舞い が必要なとき。見た目は全て自前のデザイントークンで制御して、Radix はヘッドレスとして振る舞いだけを担当している。

逆に、Button や Input のように CSS だけでスタイリングが完結するものにライブラリを入れるのは過剰。依存を減らせるし、自分でコードを持っている方が調整もしやすい。

まとめ

現時点では shadcn/ui をベースに日本語向けの調整を入れた段階で、独自のカラーやモーション、日本語特化コンポーネント(和暦ピッカーなど)はこれから。ただ、行間やサイズ感がトークンとして最初から組み込まれているだけで、毎回 className で微調整するストレスはかなり減る。

shadcn/ui を日本語環境で使っていて同じような違和感を感じている方は、ぜひ試してみてほしい。

https://github.com/ashunar0/kasumi-ui
https://kasumi-ui.vercel.app/

余談:「kasumi」という名前の由来

名前は、月や山にかかる「霞(かすみ)」から取っている。

日本語向けの UI ライブラリを作るにあたって、名前も日本に昔からあるものにしたかった。そして目指しているのは Notion や shadcn/ui のようなミニマルでスタイリッシュな方向性。日本語の UI というと大きなフォントで余白もかなり広くとって、というアプローチもあるけど、そうではなく、ミニマルでありながら日本語に最適化されているというラインを狙っている。

霞はまさにそのイメージに近い。白くて、薄くて、控えめだけど、ちゃんとそこにある。ロゴもモノトーンでシンプルに仕上げた。イメージを抽象的に落とし込めて、個人的にかなり気に入っている。

Discussion