CSS レイアウトとソース順序の切り離しを解決する

そこで、ドキュメントのソースから切断された順序でアイテムを配置するレイアウト メソッドの問題に対するソリューション案について、フィードバックをお待ちしています。

CSS Working Group は、レイアウト メソッドで、ソースから(つまりドキュメントの読み取りとフォーカスの順序から)切断された順序でアイテムを配置できる状況のソリューションに取り組んでいます。この記事では、そうした問題とその解決策についてご説明します。ぜひフィードバックをお寄せください。

問題

HTML ドキュメントの読み取り順序は、ソースの順序に従います。つまり、スクリーン リーダーはドキュメントがソースに表示されているとおりに読み上げられ、キーボードでドキュメントをタブで移動するユーザーもソースの順序に従います。通常はこれは理にかなっています。また、コンテンツの読み上げモード、スクリーン リーダー、CSS が限られているデバイスなどの場合、ドキュメントの適切なソース順序が不可欠です。ただし、CSS、特に Flexbox、グリッドは、基となるソースとは異なる視覚的な読み取り順序をレイアウトで定義するレイアウトを作成できます。

たとえば、Flex アイテムで order プロパティを使用すると、レイアウトの順序は変更されますが、ソース内の順序は変更されません。

サンプルをクリックしてタブに移動し、「order」プロパティを使用して、タブオーダーとレイアウト順序の関連付けを解除する方法を確認してください。

グリッド レイアウトを使用すると、選択したレイアウト メソッドでタブ順序が乱雑になる可能性があります。たとえば、grid-auto-flow: dense を使用してアイテムのランダム レイアウト順序を作成する場合などです。

サンプルをクリックして移動し、タブでレイアウトの順序とタブ順序がどのように切り離されるのかを確認します。今回は、アイテムを順不同でグリッド配置しています。

また、ソースで指定されているのと違う順序でアイテムをグリッドに配置することで、このような接続の切断が発生することもあります。

例をクリックしてタブを表示し、グリッドの配置プロパティを使用して、タブの順序とレイアウトの順序をどのように切り離すかを確認してください。

提案するソリューション

CSS ワーキング グループは、この問題に対するソリューションを提案しており、デベロッパーやユーザー補助コミュニティからのフィードバックをお待ちしています。

reading-order: auto でランダムなレイアウトに従う

グリッド レイアウトで高密度パッキングを使用する場合など、ランダム化されたレイアウト順序を作成する状況では、ソースの順序ではなくブラウザがレイアウトに従うようにすることをおすすめします。これを実現するには、Flex アイテムまたはグリッド アイテムに、値が autoreading-order プロパティが必要です。

次の CSS では、grid-auto-flow: dense が原因で高密度に詰め込まれたアイテムが、読み順に配置されます。

.cards {
  display: grid;
  grid-auto-flow: dense;
}

.cards li {
  grid-column: auto / span 2;
  reading-order: auto;
}

reading-order-items によるランダム化されていないレイアウトのフォロー

グリッド レイアウトや Flex レイアウトによっては、レイアウトの順序がわかりやすい場合があります。たとえば、order プロパティを使用してアイテムを並べ替える Flex レイアウトでは、order プロパティによって明確なレイアウト順序が規定されます。他のレイアウトでは、理想的なレイアウト順序が明確ではなく、複数の選択肢が存在する可能性があります。したがって、ランダム化されていないレイアウトに従う場合は、grid-order-items プロパティをコンテナに追加して、レイアウトの順序の意図を説明するキーワード値を指定する必要があります。

次の例は、row-reverse を使用した Flex レイアウトを示しています。Flex アイテムには reading-order: auto と、Flex コンテナ reading-order-items: flex flow があり、読み取り順序も(flex visual で示す)視覚的な順序ではなく、flex-flow 方向に従うよう指示します。

.cards {
  display: flex;
  flex-flow: row-reverse;
  reading-order-items: flex flow;
}

.cards li {
  reading-order: auto;
}

次の例では、grid-template-areas を使用してグリッド レイアウトを作成し、ソースの順序とは異なるレイアウト順序でアイテムを配置しています。reading-order-items プロパティは、レイアウトの順序に従い、各行を走査して次に進むことを示すために使用されます。(grid column は反対方向を示します)。

.wrapper {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  grid-template-areas:
    "a a b b b b"
    "c c d d e e"
    "f f g g h h";
  reading-order-items: grid rows;
}

.a {
  grid-area: a;
  reading-order: auto;
}

ソースの順序は重要でないということですか?

いいえ、ソースの順序は引き続き重要です。この機能は、読み上げの順序が情報源と異なる特定の状況でのみ使用してください。たとえば、密集度グリッド パッキングなど、このような切断を引き起こす可能性があるレイアウト メソッドを使用している場合や、特定のブレークポイントで異なるレイアウト順序が妥当である場合などです。

これらのプロパティを使用する場合は、CSS なしでページがレンダリングされた場合に合理的な順序でソース ドキュメントを作成します。これらのプロパティは、プロパティを必要とする場所とブレークポイントにのみ追加します。

作成ツールでこれらのプロパティを適用する必要があるか

要素をドラッグ&ドロップしてグリッド レイアウトを作成できる作成ツールであっても、適切なソース ドキュメントを作成することを奨励する必要があります。そのため、ほとんどの場合、接続解除に対処するための遅延方法としてこれらのプロパティを使用するよりも、レイアウトの順序に基づいてソースを並べ替える方が適切な場合があります。

この提案についてご意見をお聞かせください

この点について、ぜひフィードバックをお寄せください。特に、この方法では解決できないと思われるユースケースがある場合、またはアプローチに関してユーザー補助に懸念がある場合は、CSS ワーキング グループにお知らせください。

進行中のスレッドに、アプローチに関するさまざまなユースケースや考えが掲載されています。このスレッドは、この提案に関するコメントを追加したり、潜在的な問題点を特定したりするのに最適な場所です。なお、現在の提案は、スレッドを開始した最初の提案とは大きく異なります。ご興味をお持ちの皆様は、Google の現状に至った会話をすべてお楽しみいただけるかと思います。これは、CSS ワーキング グループにおける提案がどのように行われ、ブラウザに実装できるものになったかを示す良い例です。

Patrick Tomasso さんのサムネイル画像フィードバックとレビューに協力してくれた Chris Harrelson、Tab Atkins、Ian Kilpatrick に感謝します。