CSSのreading-flowプロパティが便利! CSS GridやFlexboxで見た目とDOMツリー内の順序を一致させることができます

CSS GridやFlexboxは便利でよく使用していると思います、ただし、見た目の順序とDOMツリー内の順序が一致しないことがあります。これはキーボードやアクセシビリティツールで操作するユーザーにとって非常に問題です。

この問題は、CSSのreading-flowreading-orderプロパティを使用すると解決します。CSS GridやFlexbox、さらにはブロックコンテナの各アイテムの順序をCSSで設定する方法を紹介します。

CSS GridやFlexboxで見た目の順序とDOMツリー内の順序を一致させるreading-flowプロパティ

Use CSS reading-flow for logical sequential focus navigation

下記は各ポイントを意訳したものです。
※元サイト様のライセンスに基づいて翻訳しています。基づいてというのは、貢献部分に関して同ライセンスも含みます。

はじめに -新しいプロパティを設計した経緯

CSSの新しいプロパティreading-flowreading-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-visualflex-flowで、グリッドコンテナで使用する場合の値はgrid-rowsgrid-columnsgrid-orderです。

reading-orderプロパティとは

CSSのreading-orderプロパティは、読み取りフローコンテナのアイテムの順序を手動で上書きできます。CSS GridやFleboxまたはブロックコンテナでこのプロパティを使用するには、コンテナのreading-flow値をsource-orderに設定し、個々のアイテムにreading-orderプロパティで整数値を設定します。

Flexboxでコンテンツの順序を設定する方法

まずは、HTMLで3個の要素を配置します。

CSS Flexboxで3個の要素を逆順で行に並べ、orderプロパティで順序を入れ替えたいとします。

これで右端に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プロパティです。

これだけで、見た目通りの順序になります。
tabキーによるフォーカスの順序は、1, 3, 2になります。これは英語で左から右に読む場合の視覚的順序と同じです。

See the Pen
Flex reading-flow example (reading-flow: flex-visual;あり)
by coliss (@coliss)
on CodePen.

また、フォーカスの順序を本来の意図通りに逆順にしたい場合は、下記のように設定します。

これで逆順(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個の要素を配置します。

CSS Gridで12個の要素を含むレイアウトを作成します。
5番目の要素を一番上に最大のスペースを確保し、2番目の要素を中央付近に配置します。他の要素は列のテンプレートに従ってグリッド内に自動的に配置します。

前述と同様に、キーボードのtabキーでフォーカス可能な要素を探し、tab+shiftキーで前のフォーカス可能な要素を探して、これらの要素をナビゲートしてみてください。
下記のデモではコードの順序に従ってフォーカスします(1から12の順で)。

See the Pen
Grid reading-flow example (reading-flowなし)
by coliss (@coliss)
on CodePen.

前述と同様に、この挙動はエンドユーザーの視点から見ると非常に混乱する可能性があります。アクセシビリティツールを使用しても同じことが起こります。
この問題を解決するのが、reading-flowプロパティです。

これだけで、見た目通りの順序になります。
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値を使用します。

これで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でない場合のみ、有効な読み取りフローのコンテナで有効になります。

ブロックコンテナには、5個の要素があります。要素の順序をコードの順序から並べ替えるレイアウトルールはありませんが、最初に訪問されるべきフロー外アイテムが1個あります。

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と同じ結果を得るには、下記のように記述します。

しかし、このコンテナ内以外にある別の要素もtabindex1が設定されていたらどうなるでしょうか? その場合、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

top of page

©2025 coliss