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

レイアウト方法によって、ドキュメントのソースから切り離された順序でアイテムが配置される問題に対する提案された解決策について、フィードバックをお寄せください。

CSS Working Group は、レイアウト方法によって、ソースから切り離された順序でアイテムが配置され、ドキュメントの読み取り順序やフォーカス順序から切り離される状況に対する解決策に取り組んでいます。この記事では、問題と提案されている解決策について説明します。フィードバックをお待ちしております。

問題

HTML ドキュメントの読み順は、ソースの順序に従います。つまり、スクリーン リーダーはソースにレイアウトされている順序でドキュメントを読み上げ、キーボードを使用してドキュメント内をタブ移動するユーザーも、そのソースの順序に従って移動します。通常、これは理にかなっています。コンテンツのリーディング モードの表示、スクリーン リーダー、CSS が制限されているデバイスでは、ドキュメントのソース順序が適切であることが重要です。ただし、CSS、特に flexbox と grid では、レイアウトで、基盤となるソースとは異なる視覚的な読み順を定義できます。

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

例をクリックしてタブを押すと、order プロパティを使用してタブ順序がレイアウト順序から分離されていることがわかります。

グリッド レイアウトを使用すると、選択したレイアウト方法によってタブ順序が乱れる可能性があります。たとえば、grid-auto-flow: dense を使用すると、アイテムのレイアウト順序がランダムに作成されます。

例をクリックしてタブをクリックすると、タブの順序がレイアウトの順序から切り離されていることがわかります。今回は、アイテムを順不同で配置することで、タブの順序を示しています。

ソースで指定された順序とは異なる順序でアイテムをグリッドに配置することで、この不一致が発生することもあります。

例をクリックしてタブキーを押すと、グリッド プレースメント プロパティを使用してタブ順序がレイアウト順序から分離されていることがわかります。

提案するソリューション

CSS ワーキング グループでは、この問題の解決策を提案しています。このアプローチについて、デベロッパーとユーザー補助コミュニティからフィードバックをお待ちしています。

reading-order: auto を使用してランダムなレイアウトに従う

グリッド レイアウトで密集型の配置を使用する場合など、レイアウト順序がランダムに作成される状況では、ソース順序ではなくレイアウト順序に従うようにブラウザに指示する必要があります。これを実現するには、フレックスまたはグリッドのアイテムに reading-order プロパティを設定し、値を auto にする必要があります。

次の 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 の項目には reading-order: auto があり、Flex コンテナの reading-order-items: flex flow は、読み取り順序も視覚的な順序に従うのではなく、flex-flow の方向も従うように指示しています(flex visual で示すことができます)。

.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 ワーキング グループにお知らせください。

進行中のスレッドがあります。このスレッドには、アプローチに関する多くのユースケースや考えが掲載されています。このスレッドでは、コメントを追加したり、この提案に関する潜在的な問題を指摘したりできます。現在の提案は、スレッドを開始した最初の提案とは大きく異なることに注意してください。興味をお持ちの方は、今日の状況に至るまでのすべての会話をご覧になることをおすすめします。これは、CSS ワーキング グループで提案がどのように検討され、ブラウザに実装されるものになるかについての良い例です。

サムネイル画像: Patrick Tomasso。フィードバックとレビューをいただいた Chris Harrelson、Tab Atkins、Ian Kilpatrick に感謝いたします。