タグアーカイブ Chrome

CSSスクロールトリガーアニメーション入門、Chrome 146で実装

CSSスクロールトリガーアニメーション入門、Chrome 146で実装

Chrome 146で、CSSによるスクロールトリガーアニメーションが実装された。これは要素がビューポート内に入ったことをきっかけに、指定した時間だけアニメーションを再生する仕組みだ。従来のスクロール駆動アニメーションとは動作原理が異なる。

スクロール駆動アニメーションが「スクロール位置に合わせてアニメーションの進行度が変化する」のに対し、スクロールトリガーアニメーションは「特定のスクロール地点でアニメーションを発火させる」点が特徴だ。JavaScriptのIntersection Observer APIをCSSで再現したような動きになる。

この記事では、両者の違いを比較したうえで、スクロールトリガーアニメーションの基本的な使い方から応用的なテクニックまでを解説する。複数要素の連動やタイムライン範囲の調整など、実践で役立つ手法をまとめた。

スクロールトリガーアニメーションとスクロール駆動アニメーションの違い

スクロールトリガーアニメーションとスクロール駆動アニメーションの違い

まず、両者の動作の違いを明確にしておく。混同しやすい概念だが、設計思想が根本的に異なる。

スクロール駆動アニメーションの基本動作

スクロール駆動アニメーションは、animation-timeline: view()animation-timeline: scroll() を使って、スクロール量や要素の交差度合いにアニメーションの進行を同期させる。スクロールが進むほどアニメーションも進み、戻せばアニメーションも戻る。再生時間という概念はなく、ユーザーのスクロール操作がそのままタイムラインになる。

たとえば、画面下から現れた要素が完全に見えるまでフェードインする、といった表現が得意だ。スクロールに吸い付くような動きで、ユーザーに自然なフィードバックを返せる。

スクロールトリガーアニメーションの基本動作

一方、スクロールトリガーアニメーションは、要素が特定のスクロール位置に達した瞬間にアニメーションを開始する。キーになるのは timeline-trigger: view() プロパティだ。これは「要素がビューポート内にどの程度入っているか」を監視し、指定したしきい値を超えた時点でアニメーションを発火させる。

重要なのは、アニメーションが固定の再生時間を持つことだ。たとえば300msかけて背景色を変える、といった指定ができる。スクロール量に進行が左右されないため、発火後の動きは常に一定になる。これにより、スクロール駆動アニメーションでは実現が難しかった「要素が現れた瞬間に一瞬だけフラッシュさせる」といった演出も容易になる。

スクロール駆動アニメーション
スクロール量 アニメーション進行度
スクロールに比例して0%〜100%まで連続的に変化。時間の概念はない。
スクロールトリガーアニメーション
しきい値到達 アニメーション発火 固定時間で再生
指定したしきい値を超えたら300msなどの固定時間でアニメーションを再生。スクロール量に比例しない。

この概念図では、両者のトリガー条件と進行方法の違いを示している。スクロール駆動は連続的、スクロールトリガーは離散的という理解で問題ない。

基本構文とアニメーションアクション

基本構文とアニメーションアクション

スクロールトリガーアニメーションの最小構成は、@keyframes でアニメーションを定義し、timeline-triggeranimation-trigger で発火条件を指定する、という流れになる。

基本例とプロパティの役割

たとえば、正方形の要素が完全にビューポートに入った瞬間に、背景色が300msかけてフェードインするアニメーションを考える。コードの基本形は以下のようになる。

/* アニメーションの定義 */
@keyframes fade-bg-in {
  to {
    background: currentColor;
  }
}

.square {
  /* アニメーションの宣言 */
  animation: fade-bg-in 300ms;

  /* 発火条件の定義 */
  timeline-trigger: --trigger view() entry 100% exit 0%;

  /* 発火時の動作設定 */
  animation-trigger: --trigger play-forwards;
}

timeline-trigger の値で指定している entry 100% exit 0% はタイムライン範囲と呼ばれる。これは「要素の下端がビューポートに入った瞬間(entry 100%)から、上端がビューポートから出るまで(exit 0%)を発火可能な範囲とする」という意味だ。この範囲内に要素が入っているあいだ、アニメーションの再生が許可される。

animation-trigger に指定した play-forwards は、要素が完全に見えるたびにアニメーションを順方向(0%→100%)で再生するキーワードだ。ただし、このままではアニメーション終了後に背景色が元に戻ってしまう。スタイルを保持するには animation-fill-mode を併用する必要がある。

fill-mode と action の組み合わせ

CSS-Tricksの著者Carlo Daniele氏によると、fill-modeとアニメーションアクションの組み合わせが、スクロールトリガーアニメーションの挙動を大きく左右する。主な選択肢は以下の3パターンだ。

① フラッシュ型(fill-modeなし)
最初のデモのように、アニメーション終了後に元に戻る。一瞬の強調表示に向く。
animation: fade-bg-in 300ms;
② ロックイン型(forwards + play-once)
アニメーションが一度だけ再生され、その後スタイルが保持される。要素が出入りしても再発火しない。
animation: fade-bg-in 300ms forwards;
animation-trigger: --trigger play-once;
③ 往復型(forwards + play-forwards play-backwards)
要素が見えている間は順方向、見えなくなったら逆方向にアニメーション。チラつきなく自然な切り替えが可能。
animation: fade-bg-in 300ms forwards;
animation-trigger: --trigger play-forwards play-backwards;
フラッシュ型  ロックイン型  往復型

往復型の play-forwards play-backwards は特に実用的だ。要素がビューポート外に出る際にアニメーションが逆再生されるため、ちらつきが発生しない。fill-modeを forwards にしていても、最終キーフレームが0%でも100%でも「完了時のスタイルを保持する」というルールが適用されるため、自然に動作する。

アクションキーワード一覧

animation-trigger に指定できるアクションキーワードは以下の表にまとめた。設計の幅を広げるために把握しておきたい。

アクション
効果
play-forwards
アニメーションを順方向(0%→100%)で再生
play-backwards
逆方向(100%→0%)で再生
play-once
順方向または逆方向のどちらか最初の一度だけ再生
play
最後に指定された方向で再生(未指定時は順方向)
pause
アニメーションを一時停止
reset
一時停止し、進行度を0にリセット
replay
進行度を0にリセットするが、一時停止はしない

これらのアクションを組み合わせることで、「スクロールに応じてアニメーションを途中で反転させる」「一度だけ発火させて二度と動かさない」といった細かな制御が可能になる。

複数要素への適用とスタッガー効果

複数要素への適用とスタッガー効果

スクロールトリガーアニメーションの真価は、複数要素を連動させた演出で発揮される。アクションやfill-modeが独立しているため、共通のトリガー設定を使い回しながら個別のアニメーションを割り当てられる。

CSSカスタムプロパティで設定を再利用する

たとえば、3つの正方形が順番に回転しながら拡大・背景変化する例を考える。各要素に個別のスタイルを書くのではなく、カスタムプロパティで共通設定をまとめると保守性が高まる。

.square {
  scale: 70%;
  --base-animation: intensify;
  animation: var(--base-animation) 300ms forwards;
  --animation-trigger: --trigger play-forwards play-backwards;
  animation-trigger: var(--animation-trigger), var(--animation-trigger);
  timeline-trigger: --trigger view();
  timeline-trigger-active-range-end: normal;
}

.square.rotate-left {
  animation-name: var(--base-animation), rotate-left;
}

.square.rotate-right {
  animation-name: var(--base-animation), rotate-right;
}

このコードでは、--animation-triggerplay-forwards play-backwards を格納し、animation-trigger でカンマ区切りによって2つのアニメーションに同じトリガー設定を適用している。これにより、メインのアニメーション(intensify)と回転アニメーションの両方が同じタイミングで発火する。

sibling-index() と sibling-count() による自動スタッガー

スクロールトリガーアニメーションでは、sibling-index()sibling-count() という2つのCSS関数を使って、兄弟要素のインデックスと数を動的に取得できる。これを利用すると、各要素の発火タイミングを自動的にずらす「スタッガー」が実装可能だ。

.square {
  --stagger-interval: calc(100% / sibling-count());
  --entry: calc(sibling-index() * var(--stagger-interval));
  timeline-trigger: --trigger view() entry var(--entry) exit 0%;
}

sibling-count() で親要素内の.squareの数を取得し、それを100%で割ることで1要素あたりの間隔を算出する。次に sibling-index() で現在の要素が何番目かを取得し、間隔を掛け算して各要素の entry 値を動的に決定する。この仕組みがあれば、HTMLの要素数が変わっても手作業で値を調整する必要はない。

ただし、sibling-index()sibling-count() はFirefoxで未サポートの点に注意が必要だ。プロダクションで使う場合は、フォールバックの指定を検討したい。

特定の要素をトリガーとして他を連動させる

さらに高度な使い方として、最初の要素だけをトリガーにして、残りの要素はアニメーション遅延で続けて発火させる方法がある。トリガー条件を1箇所に集約できるため、管理がしやすくなる。

.square:first-child {
  timeline-trigger: --trigger view() entry 50%;
  timeline-trigger-active-range-end: normal;
}

.square {
  --stagger-interval: calc(300ms / sibling-count());
  --animation-delay: calc(sibling-index() * var(--stagger-interval));
  animation: var(--base-animation) 300ms var(--animation-delay) forwards;
}

最初の要素がビューポートに50%入った時点でトリガーが発火し、残りの要素は animation-delay で順番にアニメーションを開始する。この方法なら、トリガー設定は最初の要素にだけ書けばよい。

ただし、CSS-Tricksの記事では play-backwards 状態のときに遅延が意図通り動作しない可能性が指摘されている。逆再生時にはdelayが含まれてしまい、スタッガーが崩れるようだ。今後のブラウザ実装の改善が待たれる。

タイムライン範囲の理解とカスタマイズ

タイムライン範囲の理解とカスタマイズ

スクロールトリガーアニメーションには、アクティベーション範囲(発火可能な範囲)とアクティブ範囲(発火後に有効であり続ける範囲)という2つのタイムライン範囲が存在する。この概念を理解しておくと、より精密なトリガー制御が可能になる。

アクティベーション範囲とアクティブ範囲の違い

アクティベーション範囲は「アニメーションが発火できるスクロール区間」を定義する。例えば entry 100% exit 0% は、要素が完全に見えてから完全に隠れるまでを発火可能区間とする。アクティブ範囲は「一度発火したアニメーションが、たとえアクティベーション範囲を外れても有効であり続ける区間」を指す。

アクティベーション範囲(発火可能区間)
アニメーションのトリガーが許可されるスクロール範囲。
例: entry 100% exit 0% は、要素の下端が入ってから上端が出るまで。
アクティブ範囲(有効区間)
アニメーションが発火したあとに、その状態が保持されるスクロール範囲。
timeline-trigger-active-range-end: normal; で制御可能。
発火可能区間  有効区間

実際のところ、大半のユースケースでは view() entry 100% exit 0%(要素が完全に見える間)か view() contain(要素がビューポートより大きい場合も含めて交差している間)で十分だ。タイムライン範囲の詳細な制御が必要になるのは、特殊な演出や複雑なレイアウトに限られる。

view() 関数とオフセットの調整

view() 関数はビューポートを基準にしたタイムライン範囲を定義する関数だ。固定ヘッダーなどでビューポートの実質的な領域が狭まっている場合、view(y 0 5rem) のようにオフセットを指定できる。これにより、ヘッダーに隠れる部分を除いた「実際に見えている領域」を基準にできる。

たとえば、上部に高さ5remの固定ヘッダーがあるページでは、view(y 0 5rem) と書くことで、ヘッダーの裏に入った要素はまだトリガー範囲内と見なされない。この調整は、UIコンポーネントとスクロール演出を正確に同期させる際に役立つ。

この記事のポイント

  • スクロールトリガーアニメーションは、スクロール駆動アニメーションと異なり、固定時間のアニメーションを特定のスクロール地点で発火させる仕組みである
  • fill-modeとanimation-actionの組み合わせで、往復・ロックイン・フラッシュなど多彩な演出が可能
  • sibling-index()とsibling-count()を使えば、要素数に依存しない自動スタッガーを実装できる
  • 実用上はview() entry 100% exit 0%の指定で十分だが、固定ヘッダーがある場合はview()のオフセット調整を検討する
Chromeが同意なく4GBのAIモデルをダウンロードする問題

Chromeが同意なく4GBのAIモデルをダウンロードする問題

Google Chromeがユーザーの明示的な許可なく、約4GBに及ぶGemini Nanoのモデルデータをダウンロードしている事実が明らかになった。このデータは「Prompt API」と呼ばれる新機能のためのものだが、その配信方法と利用規約をめぐって、Web標準の専門家から強い懸念が示されている。

CSS-Tricksの記事によれば、このダウンロードはChromeの標準アップデートの一部として扱われ、ユーザーが削除してもブラウザが自動的に再ダウンロードする仕様だという。2025年5月現在、すでに多くのユーザーのデバイスに配信済みの状態だ。

Chromeが密かにダウンロードするGemini Nanoとは

Chromeが密かにダウンロードするGemini Nanoとは

Gemini NanoはGoogleが開発した軽量AIモデルで、デバイス上で直接テキスト生成や要約などのタスクを実行する。クラウドにデータを送信せず、端末のCPUやGPUのみで推論を行うため、プライバシー保護の観点では優れた設計といえる。

問題はその配信方法だ。CSS-Tricksの著者であるMat Marquis氏が指摘したところによれば、この約4GBのデータはChromeの通常アップデートの一部として、ユーザーに何の通知もなく転送される。U2のアルバムがiTunesライブラリに強制的に追加された過去の事例になぞらえ、同意なき配信の奇妙さを強調している。

従来のブラウザアップデート
セキュリティパッチ
バグ修正
新機能の追加
ユーザーの期待する範囲の更新
今回のChromeアップデート
セキュリティパッチ
バグ修正
新機能の追加
4GBのAIモデルデータ
Gemini Nano(同意なし・通知なし)
ブラウザの更新とは別物の大規模データが混入
問題のダウンロード  通常のアップデート

削除してもChromeが再ダウンロードを実行するため、ユーザーに実質的な拒否権はない。Chromeの内部機能として扱われているが、実際にはブラウザに統合されたわけではなく、独立した製品が同梱されている状態に近い。Mat Marquis氏は、かつてスパイウェアとして批判されたBonzi Buddyがブラウザに同梱されていた事例を引き合いに出し、その類似性を指摘している。

Prompt APIの仕組みとGoogleの利用制限

Prompt APIの仕組みとGoogleの利用制限

Prompt APIは、Web開発者がChromeの組み込みAIモデルに直接アクセスできるJavaScript APIだ。ユーザーのデバイス上でテキストの要約、文章の言い換え、質問応答といった処理を実行できる。Chromeの開発者向けドキュメントでは、すでに1年以上前から公開されている。

このAPIを利用するには、Googleが定める「Generative AI Prohibited Uses Policy」への同意が必須となる。Mozillaが公式に懸念を表明したのは、この利用ポリシーの内容がWeb標準の原則と相容れないからだ。

Web APIに付随する利用ポリシーの問題点

MozillaのGitHub上のコメントによれば、Googleの禁止事項ポリシーは法律の範囲を超えた制限を含んでいる。具体的には、性的に露骨なコンテンツの生成や配布の禁止、誤情報や政府・民主的プロセスに関する誤解を招く主張の促進禁止などが盛り込まれている。

これらの制限はWebプラットフォームのAPIとしては異例だ。通常、ブラウザAPIは技術的な仕様のみを定義し、その使途を特定企業のポリシーで制限することはない。Mozillaは「これはWebプラットフォームにとって悪しき方向性であり、UA(ユーザーエージェント)固有の使用ルールを持つAPIが増える前例となる」と警告している。

従来のWeb API
技術仕様のみを定義
使途は開発者の自由(法律の範囲内)
ブラウザベンダーによる制限なし
Google Prompt API
技術仕様の提供
Googleの利用ポリシーへの同意が必須
企業固有のコンテンツポリシーでAPI利用を制限
Prompt API特有の制限  従来のWeb APIの標準的なあり方

この構造は、Webのオープン性を損なう可能性がある。特定のブラウザベンダーがAPIの利用条件を自由に設定できるなら、Webの相互運用性は徐々に崩れていく。Mozillaの反対表明は、単なる競合他社の立場表明ではなく、Web標準の基本原則を守るための警鐘と受け止めるべきだ。

Web標準プロセスにおけるGoogleの影響力

Web標準プロセスにおけるGoogleの影響力

Mat Marquis氏は、GoogleのWeb標準への関与姿勢を痛烈に批判している。同氏の比喩によれば「GoogleのWeb標準プロセスへの参加は、クマがキャンプに参加するようなものだ」という。つまり、表面上は協調しているように見えても、実質的には自社の都合でプロセスを支配しているという指摘だ。

Googleは「開発者のポジティブな感情」を根拠にPrompt APIの推進を正当化しようとしたが、実際に引用された場所にはポジティブな感情など存在しなかった。この矛盾した説明は、同社がWeb標準を「不可避なもの」として語る際の常套句と重なる。

ブラウザAPIとWeb APIの混同が生むリスク

ここで重要なのは、すべてのブラウザAPIがWeb APIではないという事実だ。Chromeだけが実装するAPIは、事実上の標準として扱われるリスクをはらむ。MicrosoftのIEが独自拡張で市場を支配した過去の過ちを、形を変えて繰り返す可能性がある。

Alex Russell氏が繰り返し指摘しているように、ブラウザの選択肢が限られている現状はすでに問題含みだ。その状況下でGoogleがChrome限定のAI APIを推進することは、Webの多様性をさらに損なう。ブラウザの多様性が生態系に与える影響について、CSS-Tricksでも過去に取り上げられているテーマだ。

ユーザーが取るべき対応と無効化手順

ユーザーが取るべき対応と無効化手順

この問題に対して、現時点でユーザーが取れる対応は限られている。Chromeの設定画面で「オンデバイスAI」の項目をオフにすることは可能だが、すでにダウンロードされた4GBのモデルデータを完全に削除し、再ダウンロードを防ぐ方法は提供されていない。

Chrome設定での確認手順
1. Chromeの設定メニューを開く
2. 「システム」セクションに移動
3. 「オンデバイスAI」の項目を探す
4. トグルをオフにする(デフォルトはオフの場合もあり)
※オフにしても、すでにダウンロードされたモデルデータが削除されるわけではない。Chromeの再起動やアップデートで自動的に再有効化される可能性も指摘されている。

この問題に関する報道は複数のメディアで取り上げられている。Engadgetは「Chromeがユーザーの同意なく4GBのAIファイルをダウンロード」と報じ、Cybernewsは「Chromeが我々のデバイスに静かに4GBのAIモデルをインストールしている」と警告した。Android Authorityでは、このダウンロードがスパイウェアに該当するかどうかの議論まで展開されている。

この記事のポイント

  • Google Chromeがユーザーの同意なく約4GBのGemini Nanoモデルをダウンロードしている
  • 削除しても自動的に再ダウンロードされ、実質的な拒否手段が提供されていない
  • Prompt APIの利用にはGoogle独自のコンテンツポリシーへの同意が必須で、MozillaがWeb標準の観点から反対を表明
  • ブラウザベンダー固有のAPI利用制限は、オープンなWebの原則を損なう前例となる危険性がある
  • Chrome設定の「オンデバイスAI」から機能自体はオフにできるが、データ削除の確実な方法は提供されていない
CSS段組みレイアウトの革命!column-wrapで横スクロール問題を解消する

CSS段組みレイアウトの革命!column-wrapで横スクロール問題を解消する

CSSのMulti-column Layout(マルチカラムレイアウト)は、長い文章を新聞のように複数の列に分割して表示する仕組みだ。これまでWeb制作の現場では、コンテンツが溢れた際に強制的に横スクロールが発生してしまうという致命的な課題があり、利用シーンが限られていた。しかし、Chrome 145から導入された新しいプロパティによって、この状況が劇的に変わろうとしている。

最新のアップデートでは、column-wrap(カラム・ラップ)とcolumn-height(カラム・ハイト)という2つのプロパティが追加された。これにより、指定した高さを超えたコンテンツを次の「行」へと折り返して表示する、いわゆる「2Dフロー」が可能になった。これはWebにおけるテキスト表現の幅を大きく広げる重要な進化といえる。

本記事では、CSS-Tricksが報じた最新情報を基に、新しい段組みレイアウトの仕組みや具体的な活用方法、そして既存のCSS GridやFlexboxとの使い分けについて詳しく解説する。新しいプロパティがどのようにWebのユーザー体験を改善するのか、その全容を紐解いていこう。

従来のCSS段組みレイアウトが抱えていた大きな課題

従来のCSS段組みレイアウトが抱えていた大きな課題

CSSの段組みレイアウトは、古くから存在する仕様でありながら、現代のWebデザインでは主役になりきれなかった。その最大の理由は、コンテンツの量が増えたときの挙動がWebの閲覧スタイルに合っていなかったからだ。ここでは、なぜ従来の段組みが使いにくかったのかを振り返る。

横スクロールというUX上の壁

従来の段組みレイアウトでは、column-count(列の数)やcolumn-width(列の幅)を指定して文章を流し込む。しかし、親要素に高さを設定している場合、テキストがその高さを超えると、ブラウザは右側に新しい列を勝手に追加していく。その結果、ユーザーはページを横にスクロールしなければ最後まで読めないという状態に陥る。

Webサイトの基本は垂直(縦)スクロールだ。スマートフォンの普及により、縦に指を動かす操作が標準となった現代において、突如として現れる横スクロールはユーザーに混乱を与える。これが「UX(ユーザーエクスペリエンス)上の禁じ手」とみなされ、多くのデザイナーが段組みの使用を避ける原因となっていた。

レスポンシブ対応の難しさ

また、従来の段組みは「1次元的」な流れしか持っていなかった。コンテンツは常に左から右へと流れるだけで、画面の下に回り込むことはない。画面幅が狭いモバイル端末では、列を1つにするなどの調整が必要だが、高さの制限がある中でコンテンツを適切に収めるには、複雑な計算やJavaScriptによる制御が不可欠だった。CSSだけで完結できない点が、開発のハードルを上げていたのだ。

Chrome 145で登場した「column-wrap」と「column-height」

Chrome 145で登場した「column-wrap」と「column-height」

2026年4月にリリースされたChrome 145では、これらの問題を一挙に解決する新機能が実装された。それがcolumn-wrapプロパティだ。このプロパティの登場により、段組みレイアウトは「横に伸び続ける」仕組みから「縦に折り返す」仕組みへと進化した。

2Dフローを実現する新しい仕組み

新しく導入されたcolumn-wrap: wrapを指定すると、コンテンツが指定された高さを超えた際、右に新しい列を作るのではなく、下に新しい「段組みの行」を作成する。これにより、コンテンツ全体を縦スクロールの中で完結させることができるようになる。これは、Flexboxがflex-wrap: wrapで要素を次の行に送る挙動に近いが、段組みレイアウト独自の「テキストの分割」機能を保持している点が異なる。

具体的なコードの書き方と挙動の変化

新しいプロパティを使用する場合、基本的には対象の要素にcolumn-countcolumn-wrap、そして基準となる高さを指定する。以下のコード例を見てほしい。column-wrap: wrapを加えるだけで、横への溢れが解消される。

.article {
  column-count: 3;
  column-gap: 20px;
  column-wrap: wrap; /* 新プロパティ */
  height: 400px;
}
従来の段組み(Before / column-wrap なし)
列 1
列 2
列 3
列 4 (横溢れ)
※コンテンツが横に突き抜け、横スクロールが必要になる。
新しい段組み(After / column-wrap: wrap)
列 1
列 2
列 3
列 4 (折り返し)
※高さを超えた分が下の行に回り込み、縦スクロールで閲覧可能。
通常の列  横に溢れた列  下に折り返した列

上記のデモが示すように、column-wrap: wrapを適用することで、コンテンツは親要素の幅の中で適切に折り返される。これは単なる見た目の変化ではなく、Webサイト全体のアクセシビリティとユーザビリティを向上させる大きな一歩だ。

新しい段組みプロパティが活躍する3つの具体的な場面

新しい段組みプロパティが活躍する3つの具体的な場面

この新機能は、どのようなWebサイトで威力を発揮するのだろうか。CSS-Tricksの記事では、いくつかの実用的なユースケースが紹介されている。特に「固定の高さ」を扱うデザインにおいて、そのメリットは顕著だ。

高さが決まっているカード型レイアウト

もっとも身近な例は、ブログの記一覧や製品紹介などのカード型レイアウトだ。各カードの最大高さが決まっている場合、段組みレイアウトを使うことで、要素を美しく並べることができる。column-wrap: wrapを使えば、カードの数が増えてもレイアウトが崩れず、シームレスに次の行へと流れていく。Flexboxでも同様のことは可能だが、段組みレイアウトは「要素の途中で改行させない」といった制御(break-inside: avoidなど)が容易であるため、より洗練されたカード配置が可能になる。

雑誌や新聞のような本格的なマガジン形式

オンラインマガジンやニュースサイトにおいて、新聞のような多段組みデザインを採用したいケースは多い。これまでは、画面サイズに合わせて手動でコンテンツを分割するか、横スクロールを許容するしかなかった。新しいプロパティを使えば、デバイスの高さに合わせて自動的に段を折り返すことができるため、どの端末で見ても「読みやすい新聞スタイル」を維持できる。これは、コンテンツの連続性を保ちつつ、視覚的なリズムを生み出すのに最適だ。

垂直スクロールを活用したフルスクリーン・カルーセル

個人的に興味深い活用法として挙げられているのが、垂直方向のページめくり体験だ。column-heightをビューポート(画面の表示領域)いっぱいの高さ(100dvhなど)に設定し、CSSのscroll-snap-typeと組み合わせる。すると、コンテンツが画面の高さに合わせて自動的に「ページ」として分割され、ユーザーは縦にフリックするだけで雑誌をめくるように記事を読み進めることができる。JavaScriptを使わずに、CSSだけでこのような高度なインタラクションが実現できるのは驚きだ。

既存のCSSレイアウト手法と新機能の使い分け

既存のCSSレイアウト手法と新機能の使い分け

新しい段組みレイアウトが登場したからといって、CSS GridやFlexboxが不要になるわけではない。むしろ、それぞれの特性を理解し、適切に使い分けることが重要だ。ここでは、それぞれの設計思想の違いを整理する。

CSS GridやFlexboxとの決定的な違い

CSS GridやFlexboxは、基本的に「個別の要素(子要素)」をどのように配置するかを管理するシステムだ。対して、段組みレイアウト(Multi-column)は「単一の連続したコンテンツ」をどのように分割するかを管理する。この違いは大きい。

例えば、1つの長い長文を途中で切り離すことなく複数の列に流し込みたい場合、GridやFlexboxでは文章を物理的に分割して複数のHTML要素に分ける必要がある。しかし、段組みレイアウトなら1つの<p>タグの中身をそのまま分割できる。構造を壊さずにレイアウトを変更できるのは、段組みレイアウトだけの特権だ。

注目が集まるCSS Masonryとの比較

現在、CSSの仕様策定が進んでいる「Masonry(メーソンリー)レイアウト」とも比較されることが多い。Masonryは高さの異なる要素を隙間なく敷き詰める手法だが、段組みレイアウトもcolumn-countを使えば似たような見た目を作ることができる。ただし、Masonryが「要素の順序」を重視するのに対し、段組みレイアウトはあくまで「コンテンツの流れ」を重視する。情報の優先順位が重要なニュース記事などでは段組みが適しており、ビジュアル重視のギャラリーサイトなどではMasonryが適しているといえるだろう。

導入時に注意すべき制限事項とブラウザ対応状況

導入時に注意すべき制限事項とブラウザ対応状況

非常に便利な新機能だが、実務で採用する際にはいくつか注意点がある。まず、2026年4月時点でのブラウザ対応状況だ。このプロパティは現在、Chrome 145以降でのみサポートされている。FirefoxやSafari、Edgeではまだ利用できないため、現時点では「プログレッシブ・エンハンスメント」の考え方で導入するのが現実的だ。

プログレッシブ・エンハンスメントとは、基本の機能はすべてのブラウザで提供しつつ、最新ブラウザではより良い体験を提供する設計手法を指す。未対応ブラウザでは従来の1カラム表示やシンプルな段組みにし、Chromeユーザーには進化した2Dフローを提供するという構成が望ましい。

また、動的なコンテンツへの対応も課題だ。ユーザーが投稿するコメントやCMSから配信される記事など、高さが予測できないコンテンツの場合、column-heightを固定してしまうと、不自然な余白ができたり、意図しない場所で折り返されたりする可能性がある。完全にレスポンシブな設計にするには、依然としてメディアクエリを駆使して、画面サイズごとに最適な列数や高さを微調整する作業が必要になるだろう。

この記事のポイント

  • Chrome 145で導入されたcolumn-wrap: wrapにより、段組みの横スクロール問題が解消された。
  • コンテンツが高さを超えた際に「下の行」へ折り返す2Dフローが実現可能になった。
  • 固定高のカードレイアウトや、新聞スタイルのデザイン、垂直カルーセルなどで特に威力を発揮する。
  • GridやFlexboxが「要素の配置」を得意とするのに対し、段組みは「単一コンテンツの分割」に特化している。
  • 現時点ではブラウザ対応が限定的なため、未対応環境へのフォールバックを考慮した設計が不可欠だ。