UIデザインが一段上がる 2025年版「最新CSS」完全ガイド― text-autospace から scroll-state(), dialog の新仕様まで実務目線で解説

はじめに:2025年のCSSは「情報収集」から「実戦投入」の段階へ

ここ数年、CSS は「ちょっとした新機能」どころではなく、UIデザインそのものを組み替えるレベルで進化しています。

2025年の MTDDC Meetup Tokyo で公開された「UIデザインに役立つ 2025年の最新CSS」は、その変化をぎゅっとまとめた内容でした。

特徴的なのは、

  • かつては Chrome だけの実験機能だったものが、2025年現在は Safari・Firefox を含む主要ブラウザでかなり使える状態になってきた
  • しかも「UIデザインで頻出するパターン」を、CSS だけで綺麗に解決できるようになってきた

という点です。

この記事では、そのスライドのエッセンスをかみ砕きつつ、

  • 実務でどう使うとおいしいか
  • どこまで本番投入してよいか
  • フロントエンド学習者がどこから触り始めるべきか

を、現場目線で解説していきます。


2025年のCSSの全体像と「Interop」という追い風

最近よく聞く「Interop 20xx」という取り組みは、ブラウザ vendor が足並みをそろえて特定の機能セットを優先的に実装しよう、という共同プロジェクトです。

2025年版の Interop でも、

  • タイポグラフィ関連(text-autospace, text-box)
  • コンテナクエリやスクロール状態のクエリ(scroll-state)
  • 動画や写真の HDR 表示(dynamic-range-limit)

といった、今回紹介する機能群が重点的に改善されています。

つまり「どのブラウザなら動くのか…」と毎回悩み続けるフェーズから、「条件付きで実務に採用できる」フェーズに入ってきた、ということです。


1. すでに“前提知識”になりつつある最新CSS

今回のスライドでは、すでに普及した CSS として次のような機能はさらっと流されています。

  • :has() セレクタ
  • ネスト構文(CSS Nesting)
  • コンテナクエリ(サイズ・スタイル)
  • サブグリッド
  • @starting-style
  • @property
  • 相対カラー構文(color-mix() など)

これらは「これから学ぶ」ではなく、「もう使える前提で、その先に進もう」という扱いです。

この記事の本題はここから先ですが、

  • まだ触っていないものがある
  • サポート状況が不安

という方は、MDN や Chrome for Developers の解説を一通り読んでおくと、この先の内容もすっと入ってきます。


2. タイポグラフィを変える最新CSS

Section 2 では「タイポグラフィ」がテーマ。

特に日本語と英数字が混ざる UI で、見た目のクオリティを底上げしてくれる機能が揃っています。

2-1. text-autospace で和欧混植の“変な空き”問題を解決

text-autospace は、CJK(日本語・中国語・韓国語)と英数字の間に自動で小さなスペースを入れるかどうかを制御するプロパティです。

ざっくりいうと、

  • text-autospace: no-autospace;
    • 何もしない(従来どおり)
  • text-autospace: normal;
    • 「日本語と英数字の間がくっつきすぎて読みにくい」問題を、いい感じに補正してくれる

という挙動です。

body {
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Noto Sans JP",
    sans-serif;
  text-autospace: normal;
}

これを全体に適用すると、

  • 「CSS」「2025」などの英数と日本語の間に、ほんの少しスペースが入る
  • 文章全体が「紙の組版」に近い読みやすさになる

一方で、仕様はまだ Experimental 扱いであり、ブラウザによってデフォルト値が異なる(Chrome は normal, Safari は no-autospace)といった差もあります。

そのため、現時点では

  • Web アプリ全体に一括で適用するより、
  • 長文を読ませるブログ・記事・ヘルプセンターなどで段階的に適用する

といった、安全寄りの採用が現実的です。

2-2. Windows に Noto Sans JP 標準搭載時代のフォント指定

2025年4月の Windows Update で、Windows 10/11 に Noto Sans JP / Noto Serif JP が標準搭載されました。

さらに Chrome / Edge のデフォルトフォントも Noto 系に切り替わり、

  • font-family: sans-serif;
    • → Noto Sans JP が採用される
  • Windows 11 の font-family: serif;
    • → Noto Serif JP が採用される

という挙動になりつつあります。

これにより、

  • 「メイリオ前提でピクセルパーフェクトに組んでいた UI」が、突然 Noto に変わる
  • 行間や字幅が変わり、ボタン内の改行やヘッダー高さが崩れる

という現象が発生しています。

スライドでは、これに対する実務的な対策として、

<!-- Google Fonts で読み込みつつ -->
<link
  href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@100;900&display=swap"
  rel="stylesheet"
/>

<style>
  /* まず OS ネイティブの Noto を探す */
  @font-face {
    font-family: "Local Noto Sans JP";
    src: local("Noto Sans JP");
  }

  body {
    font-family: "Local Noto Sans JP", "Noto Sans JP", sans-serif;
  }
</style>

のように、

  1. ローカルに Noto があればそれを使う
  2. なければ Google Fonts の Web フォント版を使う

という二段構えを紹介しています。

これにより、

  • Windows でも macOS でも「ほぼ同じ」字形で表示でき、
  • 文字組の差による崩れを最小限に抑えられる

という、非常に実務的な恩恵が得られます。

2-3. text-box / text-box-trim で行ボックスの上下をきっちり揃える

見出しやボタンを作るとき、「フォントによって上下の余白が微妙に違う」「アイコンとテキストが上下でずれて見える」という問題は古くからありました。

これを CSS レベルで解決してくれるのが text-box-trim と text-box-edge、そしてそのショートハンドである text-box です。

よく出てくるのが次の指定。

.text {
  text-box: trim-both cap alphabetic;
}

意味としては、

  • trim-both
    • 行ボックスの上下両方の余白を削る
  • cap alphabetic
    • 上を大文字の上端(cap)、下をベースライン(alphabetic)で揃える

という指定で、「行の上下余白をフォントの骨格に合わせて揃える」イメージです。

この効果が特に効くのは、

  • アイコン+テキストの水平並び
  • ボタンラベル
  • カードコンポーネントのタイトル行

など。「ピクセル微調整のための謎の padding-top: 3px」を量産しなくて済むようになります。

注意点としては、

  • 現時点では Chrome 系が中心で、他ブラウザは実装途上
  • 日本語フォントでは効果が小さい場合もあり、デザインと要件を見ながら導入する

といったあたりです。

2-4. contrast-color() で「読める色」を自動で選ぶ

contrast-color() は、背景色と良好なコントラストになる前景色(テキスト色)を自動で選ぶ関数です。

最低限の使い方は次のとおり。

button {
  --button-color: #0053ff;
  background-color: var(--button-color);
  color: contrast-color(var(--button-color));
}

このように書くと、

  • 背景色が明るければ、文字色は自動で黒
  • 背景色が暗ければ、文字色は自動で白

といった具合に、ブラウザが読みやすい方を選んでくれます。

特に効いてくるのは、

  • 管理画面やダッシュボードで「状態別バッジ」をテーマカラーから自動生成したい
  • ランダムに生成されるタグカラーに対して、毎回手で color: #fff; を指定したくない

といった場面です。

なお、仕様上は「コントラスト比をチェックしてくれる」というより、

黒か白のどちらか、よりコントラストの高い方を返す

という挙動に近い点には注意が必要です。


3. UI体験を底上げする新機能たち

続く Section 3 では、スクロールやページ遷移など、「UIの気持ちよさ」を決める要素を CSS で扱いやすくする機能が紹介されています。

3-1. scroll-state() コンテナクエリで「スクロール済み」を CSS だけで検知

@container scroll-state() は、スクロール状態を元にスタイルを切り替えられるコンテナクエリです。

例えば、スクロールに合わせてヘッダーに影を付ける場合、従来は JS でスクロール位置を監視してクラスを付け替える必要がありました。

これが CSS だけで書けるようになります。

/* スクロール状態を監視したい要素にコンテナを指定 */
header {
  position: sticky;
  top: 0;
  @container scroll-state(--stuck: sticky) {
    & {
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
      backdrop-filter: blur(8px);
    }
  }
}

イメージとしては、

  • コンテナ(ここではヘッダー)のスクロール状態をブラウザが管理
  • 「sticky で張り付いている」「スクロール中」などの状態を、クエリで拾ってスタイルを変える

という仕組みです。

これだけで、

  • sticky ヘッダーに境界線や影を付ける
  • 横スクロール可能なリストに「スクロールできます」ヒントを出す

といった UI を、ノー JavaScript で実現できます。

3-2. View Transitions API で MPA でも SPA でもなめらかな画面遷移

View Transitions API は、DOM の状態遷移やページ遷移に対して、ブラウザが「前の状態」と「次の状態」をうまくつなぐアニメーションを提供してくれる API です。

しかも、

  • SPA(React や Vue のルーター)
  • MPA(普通の複数 HTML ファイル)

どちらでも利用できます。

MPA の場合の最低限のセットアップは、

<!-- 遷移元・遷移先の両方に -->
<meta name="view-transition" content="same-origin" />

といったメタタグを入れたうえで、リンクを普通に書くだけ。あとはブラウザが、前後ページの DOM を比較して、共通要素をなめらかにクロスフェードしてくれます。

SPA では、document.startViewTransition() を使って、状態変更の前後をラップする形で利用します。

document.startViewTransition(() => {
  // ここでルーターの状態を変更する
  router.push("/detail");
});

これに CSS を組み合わせることで、

  • ページ全体のフェード
  • 特定のカードだけスライドさせる
  • サムネイルから詳細ビューへのズーム

など、これまで GSAP や自前アニメーションで頑張っていた表現が、かなり楽に書けるようになります。

3-3. interpolate-size で「auto のアニメーション問題」を解決

FAQ のアコーディオンなどで「高さ height を 0 → auto にアニメーションしたい」というのは、フロントエンドの定番お悩みでした。

interpolate-size は、auto と具体的な長さ値の間のトランジションを許可することで、この問題を解決してくれるプロパティです。

スライドの例でも、<details> を利用した FAQ UI をなめらかに開閉させるコードが紹介されています。

:root {
  interpolate-size: allow-keywords;
}

details {
  transition: height 0.4s, content-visibility 0.4s allow-discrete;
  height: 0;
  overflow: clip;

  &[open] {
    height: auto;
  }
}

ポイントは、

  • interpolate-size: allow-keywords;
    • height: 0 と height: auto の間の補間を有効にする
  • content-visibility に allow-discrete を組み合わせる
    • レイアウトと描画コストをうまく抑えながら、表示・非表示を切り替える

という組み合わせになっている点です。

まだ Experimental 扱いなので、本番で使う場合は

  • 古いブラウザ向けには JS でフォールバック実装を用意する
  • アニメーションは「あると気持ちいい」程度にとどめる

くらいがちょうど良いラインです。

3-4. sibling-index() で「n番目」を値として使い倒す

sibling-index() は、その要素が兄弟要素の中で何番目かを整数で返す関数です。

nth-child() のようなセレクタではなく、「値」として使えるのが最大の特徴。

例えば、リストアイテムの幅を段階的に広げたいときは、

li {
  width: calc(sibling-index() * 40px);
}

とするだけで、

  • 1番目は 40px
  • 2番目は 80px
  • 3番目は 120px

のように、自動で階段状のレイアウトになります。

アニメーションと組み合わせて、

li {
  animation: fade-in 0.6s ease-out backwards;
  animation-delay: calc(0.08s * sibling-index());
}

とすれば、「1番目から順番にふわっと表示される」インタラクションも CSS だけで実現可能です。

「ループの index を JS で出して data 属性に埋める」といったお約束の実装が不要になるので、コンポーネントコードがかなりすっきりします。

3-5. dynamic-range-limit で HDR コンテンツのまぶしさをコントロール

写真や動画の HDR 対応が進み、ブラウザでも HDR コンテンツを扱えるようになってきました。

そこで登場するのが dynamic-range-limit プロパティです。

役割は一言でいうと、

HDR コンテンツの「最大輝度」を CSS から制限する

ことです。

主な値は以下の通り。

  • standard
    • HDR でも「CSS の white と同程度」までに抑える
  • no-limit
    • 限界まで明るくしてよい(デフォルト)
  • constrained
    • SDR と HDR が混在しても眩しすぎない程度に抑える

ギャラリー UI での典型的な使い方は次のような感じです。

/* 一覧のサムネイルは眩しすぎないように制限 */
.thumb img {
  dynamic-range-limit: standard;
}

/* 詳細ビューだけ HDR をフルに活かす */
.detail img {
  dynamic-range-limit: no-limit;
}

これにより、

  • サムネ一覧では「そこまで眩しくない」落ち着いた見た目
  • 詳細ページでクリックしたときだけ「おおっ」と感じるメリハリ

を演出できます。

HDR 対応ディスプレイが増えるほど、デザイン側での「明るさコントロール」は UX の一部という扱いになっていくでしょう。


4. dialog 要素の進化でモーダル実装が変わる

Section 4 は、HTML の <dialog> 要素と、それを取り巻く新仕様がテーマです。

「モーダルダイアログ」の実装をこれからどう書くべきか、方向性を示してくれています。

4-1. closedby 属性で「どの操作で閉じるか」を宣言する

<dialog closedby=”…”> は、ユーザーがどの操作をしたときにダイアログを閉じるかを宣言できる属性です。

指定できる代表的な値は次の 3 つ。

  • any
    • Esc キー、外側のクリック、requestClose() など、あらゆる close リクエストを受け付ける
  • closerequest
    • requestClose() など、明示的な close リクエストのみ受け付ける(背景クリックでは閉じない)
  • none
    • どの close リクエストも受け付けない(完全ロック)

例えば、「外側クリックで閉じられると困る重要な確認ダイアログ」は、

<dialog id="danger-dialog" closedby="closerequest">
  ...
</dialog>

と書くだけで、

  • Esc キーや背景クリックでは閉じず、
  • 「キャンセル」「OK」ボタンからの requestClose() のみを受け付ける

といった挙動にできます。

従来はこれを JS で毎回実装していましたが、仕様として「どう閉じるべきか」を HTML 側に宣言できるようになった、というのがポイントです。

4-2. command / commandfor で JS なしダイアログ制御

もう一つの大きな変化が、command / commandfor 属性です。

これは Invoker Commands API の一部で、ボタンからダイアログやポップオーバーを「宣言的に」制御できる仕組みです。

もっともシンプルな例は次のような記述です。

<!-- ダイアログを開くボタン -->
<button commandfor="my-dialog" command="show-modal">
  ダイアログを開く
</button>

<dialog id="my-dialog">
  <p>内容...</p>

  <!-- 閉じるボタン -->
  <button commandfor="my-dialog" command="close">
    閉じる
  </button>
</dialog>

これだけで、

  • JavaScript なしで .showModal() / .close() 相当の挙動
  • ARIA 属性やフォーカス制御など、アクセシビリティの面倒をブラウザ側がよしなに処理

といったメリットが得られます。

ビルトインの command 値には、例えば次のようなものがあります。

  • show-modal / close / request-close(dialog 用)
  • show-popover / hide-popover / toggle-popover(popover 用)

いままでフレームワークや UI ライブラリに任せていた「トリガーと対象のひも付け」を、素の HTML でスッキリ書けるようになったわけです。


5. 実務でどう使うか:サポート状況とフォールバック戦略

ここまで見てきたように、2025 年の CSS / HTML はかなり攻めた機能が増えていますが、ブラウザサポートは機能ごとにバラバラです。

ざっくりとした分類イメージはこんな感じです(2025 年末時点)。

  • 比較的安心して本番投入できるレベル
    • text-autospace(ただし挙動差あり)
    • Noto Sans JP 周りのフォント戦略(OS レベル)
    • View Transitions API(Chrome / Edge / Safari の最新版)
    • dialog 要素+ command / commandfor(主に Chromium)
  • かなり新しいので、徐々に検証しながら
    • text-box-trim / text-box 
    • scroll-state() コンテナクエリ 
    • interpolate-size 
    • sibling-index() 
    • dynamic-range-limit(HDR 環境でのみ恩恵)

実務に導入する際の基本戦略は、

  1. まずはコンポーネント単位で A/B 的に試す
    • 例: FAQ セクションだけ interpolate-size を使ってみる
  2. サポートされていない環境でも壊れない書き方を徹底する
    • 新機能は「あるとリッチになる」程度にとどめ、未対応ブラウザでは単に地味な見た目になる程度にする
  3. MDN や Can I use を必ず確認する
    • Baseline かどうか、Experimental フラグが必要かを毎回チェックする

この 3 点を守っておけば、「最新 CSS を試したら地獄を見た…」ということにはなりにくいはずです。


6. これからキャッチアップする人へのロードマップ

この記事で紹介した機能は、どれも UI デザインを一段引き上げてくれるものばかりですが、一気に全部覚える必要はありません。

フロントエンド学習者・実務者それぞれに向けて、段階的なロードマップをまとめておきます。

6-1. 学習者向け:まずはタイポグラフィと小さな UI から

  1. text-autospace をブログや記事コンテンツに適用してみる
  2. text-box: trim-both cap alphabetic; を見出し・ボタンに試してみる
  3. contrast-color() を使って、ランダムカラーのタグやボタンの可読性を上げる

このあたりは既存の HTML / CSS の延長で試しやすく、「見た目の変化」が分かりやすいのでモチベーションも上がります。

6-2. 実務者向け:UI コンポーネントを CSS だけで賢くする

  1. sticky ヘッダーに scroll-state() を導入し、JS 依存を減らす
  2. FAQ やアコーディオンで interpolate-size を試し、JS アニメーションの置き換えを検討する
  3. 列挙 UI のアニメーションに sibling-index() を使い、ループ変数依存のコードを削減する
  4. 写真サイトや映像系プロジェクトでは、HDR 環境を意識して dynamic-range-limit の設計をしてみる

このあたりまで来ると、もう「従来の CSS」とは別物の体験になってきます。

6-3. dialog 周りを 2025 年仕様にアップデートする

モーダル UI を刷新するプロジェクトでは、

  • <dialog> 要素を前提にする
  • closedby で閉じ方ポリシーを定義
  • ボタンは command / commandfor で制御

という流れで、一度 UI 設計を見直してみると効果的です。

JS で頑張っていた頃に比べて、

  • フォーカス制御や ARIA 周りのバグが減る
  • 初期表示まで JS を待たなくても、最低限のインタラクションは動く

といった、パフォーマンス面・アクセシビリティ面のメリットも大きくなります。


7. 関連リソースと今後のキャッチアップ方法

最後に、このスライドと相性が良い情報源をいくつか挙げておきます。

  • ICS.media の各種記事
    • text-box, scroll-state, Noto Sans JP, dialog など、今回のトピックの詳細記事が揃っています。
  • MDN Web Docs
    • text-autospace, interpolate-size, sibling-index, dynamic-range-limit など、新機能の仕様とブラウザサポートを確認するのに最適です。
  • Chrome for Developers / WebKit Blog
    • scroll-state() や View Transitions, contrast-color など、実装者視点の記事が豊富です。

おわりに:CSS は「見た目の指定」から「体験のエンジン」へ

2025 年の最新 CSS を眺めていると、

  • 文字の組み方
  • 要素が現れるタイミング
  • スクロール中や遷移中の状態
  • HDR ディスプレイでの輝度

といった「これまで JS や OS にお任せだった領域」が、どんどん CSS の守備範囲に入ってきているのが分かります。

言い換えると、

CSS は単なる「見た目の指定」ではなく、UI 体験そのものをデザインするためのエンジン

になりつつある、ということです。

この記事をきっかけに、

  • まずは一つ、小さなコンポーネントで
  • 次にプロジェクト単位で

段階的に最新 CSS を取り入れてみてください。

「同じデザイン comp」でも、CSS の力を借りることで、体験はまだまだ良くできます。

(Visited 1 times, 1 visits today)