CSSのreading-flowプロパティが便利! CSS GridやFlexboxで見た目とDOMツリー内の順序を一致させることができます
Post on:2025年6月12日
sponsors
CSS GridやFlexboxは便利でよく使用していると思います、ただし、見た目の順序とDOMツリー内の順序が一致しないことがあります。これはキーボードやアクセシビリティツールで操作するユーザーにとって非常に問題です。
この問題は、CSSのreading-flow
とreading-order
プロパティを使用すると解決します。CSS GridやFlexbox、さらにはブロックコンテナの各アイテムの順序をCSSで設定する方法を紹介します。

Use CSS reading-flow for logical sequential focus navigation
下記は各ポイントを意訳したものです。
※元サイト様のライセンスに基づいて翻訳しています。基づいてというのは、貢献部分に関して同ライセンスも含みます。
- はじめに -新しいプロパティを設計した経緯
- reading-flowプロパティとは
- reading-orderプロパティとは
- Flexboxでコンテンツの順序を設定する方法
- CSS Gridでコンテンツの順序を設定する方法
- ブロックコンテナでコンテンツの順序を設定する方法
- tabindexとのインタラクション
- 終わりに
はじめに -新しいプロパティを設計した経緯
CSSの新しいプロパティreading-flow
とreading-order
は、5月にリリースされたChrome 137でサポートされました。この記事ではこのプロパティを設計した経緯、使い始めるために必要な知識を解説します。
CSS GridやFlexboxといったレイアウト手法は、フロントエンド開発を大きく変革させました。しかし、その柔軟性が一部のユーザーに問題を引き起こすことがあります。視覚的な順序がDOMツリー内の順序と一致しない状況が簡単に発生してしまいます。キーボードを使用してWebページをナビゲートする場合、ブラウザはソースコードに従ってページ内を移動するため、ページ内を移動する際に予期せぬジャンプが発生してしまうことがあります。
reading-flow
プロパティとreading-order
プロパティは、この長年の問題を解決するために設計され、CSS Display Module Level 4に追加されました。
reading-flowプロパティとは
CSSのreading-flow
プロパティは、CSS GridやFleboxまたはブロックレイアウトの要素がアクセシビリティツールに表示される順序、線形シーケンシャルナビゲーションメソッドを使用してフォーカスを当てる方法を制御します。
このプロパティの値は1つのキーワード値で、デフォルトはnormal
で要素の順序はDOMの順序に従います。Flexコンテナで使用する場合の値はflex-visual
とflex-flow
で、グリッドコンテナで使用する場合の値はgrid-rows
とgrid-columns
とgrid-order
です。
reading-orderプロパティとは
CSSのreading-order
プロパティは、読み取りフローコンテナのアイテムの順序を手動で上書きできます。CSS GridやFleboxまたはブロックコンテナでこのプロパティを使用するには、コンテナのreading-flow
値をsource-order
に設定し、個々のアイテムにreading-order
プロパティで整数値を設定します。
Flexboxでコンテンツの順序を設定する方法
まずは、HTMLで3個の要素を配置します。
1 2 3 4 5 |
<div class="box"> <a href="#">1</a> <a href="#">2</a> <a href="#">3</a> </div> |
CSS Flexboxで3個の要素を逆順で行に並べ、order
プロパティで順序を入れ替えたいとします。
1 2 3 4 5 6 7 8 |
.box { display: flex; flex-direction: row-reverse; } .box :nth-child(1) { order: 2; } |
これで右端に3個の要素が配置されました。
See the Pen
Flex reading-flow example (reading-flowなし) by coliss (@coliss)
on CodePen.
この3つの要素をキーボードのtabキーで操作してみます。まずは、tabキーでフォーカス可能な要素を探し、tab+shiftキーで前のフォーカス可能な要素を探して、3個の要素をナビゲートしてみてください。
コードと同じ順序で、各要素をフォーカスします(1, 2, 3の順で)。
しかしこの挙動はエンドユーザーの視点から見ると非常に混乱する可能性があります。アクセシビリティツールを使用しても同じことが起こります。
この問題を解決するのが、reading-flow
プロパティです。
1 2 3 |
.box { reading-flow: flex-visual; } |
これだけで、見た目通りの順序になります。
tabキーによるフォーカスの順序は、1, 3, 2になります。これは英語で左から右に読む場合の視覚的順序と同じです。
See the Pen
Flex reading-flow example (reading-flow: flex-visual;あり) by coliss (@coliss)
on CodePen.
また、フォーカスの順序を本来の意図通りに逆順にしたい場合は、下記のように設定します。
1 2 3 |
.box { reading-flow: flex-flow; } |
これで逆順(2, 3, 1)になります。どちらの場合もCSSのorder
プロパティが考慮されています。
See the Pen
Flex reading-flow example (reading-flow: flex-flow;あり) by coliss (@coliss)
on CodePen.
CSS Gridでコンテンツの順序を設定する方法
CSS Gridの例はすこし複雑にしてみましょう。
HTMLで12個の要素を配置します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<div class="wrapper"> <a href="#">1</a> <a href="#">2</a> <a href="#">3</a> <a href="#">4</a> <a href="#">5</a> <a href="#">6</a> <a href="#">7</a> <a href="#">8</a> <a href="#">9</a> <a href="#">10</a> <a href="#">11</a> <a href="#">12</a> </div> |
CSS Gridで12個の要素を含むレイアウトを作成します。
5番目の要素を一番上に最大のスペースを確保し、2番目の要素を中央付近に配置します。他の要素は列のテンプレートに従ってグリッド内に自動的に配置します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
.wrapper { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 100px; } .wrapper a:nth-child(2) { grid-column: 3; grid-row: 2 / 4; } .wrapper a:nth-child(5) { grid-column: 1 / 3; grid-row: 1 / 3; } |
前述と同様に、キーボードのtabキーでフォーカス可能な要素を探し、tab+shiftキーで前のフォーカス可能な要素を探して、これらの要素をナビゲートしてみてください。
下記のデモではコードの順序に従ってフォーカスします(1から12の順で)。
See the Pen
Grid reading-flow example (reading-flowなし) by coliss (@coliss)
on CodePen.
前述と同様に、この挙動はエンドユーザーの視点から見ると非常に混乱する可能性があります。アクセシビリティツールを使用しても同じことが起こります。
この問題を解決するのが、reading-flow
プロパティです。
1 2 3 |
.wrapper { reading-flow: grid-rows; } |
これだけで、見た目通りの順序になります。
tabキーによるフォーカスの順序は、5, 1, 3, 2, 4, 6, 7, 8, 9, 10, 11, 12になります。これは視覚的な順序に従ったものです。
See the Pen
Grid reading-flow example (reading-flow: grid-rows;あり) by coliss (@coliss)
on CodePen.
列の順序に従って読み進めたい場合は、grid-columns
値を使用します。
1 2 3 |
.wrapper { reading-flow: grid-columns; } |
これでtabキーによるフォーカスの順序は、5, 6, 9, 7, 10, 1, 2, 11, 3, 4, 8, 12になります。
See the Pen
Grid reading-flow example (reading-flow: grid-columns;あり) by coliss (@coliss)
on CodePen.
ちなみに、grid-order
値を使用すると、フォーカスの順序は1から12のままです。これはどの要素にもCSSでorder
が設定されていないためです。
ブロックコンテナでコンテンツの順序を設定する方法
reading-order
プロパティは、アイテムを読み取りフローのどの時点で訪問するかを設定できます。これによりreading-flow
プロパティで設定された順序は上書きされます。reading-flow
プロパティの値がnormal
でない場合のみ、有効な読み取りフローのコンテナで有効になります。
1 2 3 4 5 6 7 8 9 10 |
.wrapper { display: block; reading-flow: source-order; } .top { reading-order: -1; inset-inline-start: 50px; inset-block-start: 50px; } |
ブロックコンテナには、5個の要素があります。要素の順序をコードの順序から並べ替えるレイアウトルールはありませんが、最初に訪問されるべきフロー外アイテムが1個あります。
1 2 3 4 5 6 7 |
<div class="wrapper"> <a href="#">Item 1</a> <a href="#">Item 2</a> <a href="#">Item 3</a> <a href="#">Item 4</a> <a class="top" href="#">Item 5</a> </div> |
reading-order
プロパティの値を-1
に設定することで、フォーカス順序は最初にこのアイテムを訪問してから、残りの読み取りフローアイテムのコードの順序に戻ります。
See the Pen
ブロックコンテナ内のreading-flowとreading-order by coliss (@coliss)
on CodePen.
tabindexとのインタラクション
これまで、デベロッパーはHTMLのtabindex
属性を使用してHTML要素をフォーカス可能にし、ナビゲーションのフォーカス順序を設定してきました。しかし、この属性は多くの欠点とアクセシビリティ上の懸念があります。主な懸念としては、正のtabindex
を使用したときにtabindex順のフォーカスがアクセシビリティツリーで認識されないことです。間違った使い方をするとスクリーンリーダーでのエクスペリエンスと一致しない不安定なフォーカス順序になってしまいます。
これを修正するには、aria-owns
属性を使用して順序付けをします。
前述のFlexboxの例で使用したreading-flow: flex-visual
と同じ結果を得るには、下記のように記述します。
1 2 3 4 5 |
<div class="box" aria-owns="one three two"> <a href="#" tabindex="1" id="one">One</a> <a href="#" tabindex="3" id="two">Two</a> <a href="#" tabindex="2" id="three">Three</a> </div> |
しかし、このコンテナ内以外にある別の要素もtabindex
の1
が設定されていたらどうなるでしょうか? その場合、1
の要素はすべて一緒に訪問され、次のtabindex
に移動します。このような飛び飛びのナビゲーションは、ユーザーエクスペリエンスに悪影響を及ぼします。従ってアクセシビリティの専門家は正のtabinde
を避けることを推奨しています。そして、わたし達はreading-flow
を設計する際にこの問題を解決しようと試みました。
reading-flow
プロパティが設定されたコンテナは、フォーカススコープの所有者になります。つまり、コンテナ内のすべての要素を順次参照してから次のフォーカス可能な要素に移動するようにスコープを設定します。さらに、コンテナ直下の子要素はreading-flow
に基づいて順序付けされ、正のtabindex
は順序付けの際に無視されます。reading-flow
アイテムの子孫要素に正のtabindex
を設定することは可能です。
display: contents;
要素がレイアウトの親からreading-flow
プロパティを継承している場合、これも有効なリーディングフローコンテンツになります。サイトを実装する場合には、この点にご注意ください。詳しくは、reading-flowとdisplay: contentsに関するフィードバックのお願いをご覧ください。
終わりに
これらの新しいプロパティについてフィードバックがありましたら、CSS Working Group GitHubにIssueとしてご報告ください。tabindex
とフォーカススコープについてのフィードバックはHTML WHATNOT GitHubにIssueとしてご報告ください。
ここで解説した機能についてのフィードバックをお待ちしています。
sponsors