← アーカイブ

公開済みの記事を元のURLで保管しています。過去の記事には執筆時の技術と見解が含まれます。

400%拡大が残す画面領域を実測したら、固定ピクセルという通行料が見つかった

320pxのリフローに合格したページでも、短いビューポートでは本文に残る縦方向の空間が118pxまで減っていた。損失は割合ではなく82pxの固定ピクセル通行料で、その大半はアプリケーションCSSの外側にあるサードパーティの固定コンテナから生じていた。測定手順と回帰ゲートの設計、閾値の置き方まで記録する。

400%拡大が残す画面領域を実測したら、固定ピクセルという通行料が見つかった

400%ズームに相当する幅320pxの短いビューポートで、記事本文の閲覧スペースがどれだけ残るかを調べた。ビューポートの高さ、スクロール状態、ページ種別、画面上の付随要素の有無を変化させながら、article や main に実際に到達する縦方向ピクセルを計測した。ページは横方向のリフロー判定をすべて通過したにもかかわらず、320x200の最上部状態では記事の可読領域が118pxしか残らず、さらにスクロール中盤では固定コンテナの影響により110pxまで圧縮された。

この結果が重要なのは、アクセシビリティ適合性の判定に合格していても、実際の閲覧体験は運用上きわめて脆弱になり得るという点だ。私の提案は明快だ。WCAGの適合証明レポートはそのまま維持し、リリース時の回帰検知指標として有効な縦ピクセル数を別軸で導入することだ。

横方向リフローの合格は閲覧体験を保証しない

大規模なリニューアル事業において、アクセシビリティの報告は往々にして簡潔にまとめられる。「自動テストでの違反0件、リフロー適合、リリース承認」という具合だ。この報告自体は有用だ。しかし、ロービジョンのユーザーが縦に狭いビューポートでページを操作している現場では、これだけでは情報として不完全だ。一つ目の項目がどこまでを守備範囲にしているかは、正解付き1,213件で自動チェックを測った記録で別に確かめてある。ここで見るのは二つ目の項目だ。

WCAG 2.2の達成基準 1.4.10 は、縦スクロールコンテンツに対して320 CSSピクセル相当の幅で動作することを要求している。しかし、そのコンテンツに対して残るべき縦方向の閲覧高さまでは規定していない。

Content can be presented without loss of information or functionality, and without requiring scrolling in two dimensions for: Vertical scrolling content at a width equivalent to 320 CSS pixels; Horizontal scrolling content at a height equivalent to 256 CSS pixels.

— Web Content Accessibility Guidelines (WCAG) 2.2 — SC 1.4.10 Reflow

この境界線は実測結果にはっきりと現れた。検証した8行のページおよび高さの組み合わせすべてで横方向の判定に合格した。clientWidth と scrollWidth はともに320であり、ドキュメントレベルの横スクロールは0だった。それと同時に、320x200の最上部状態で確保された記事の有効スペースは118pxにとどまり、実測したline-height換算でわずか4.2行分しかなかった。

CTOの立場から見れば、これは達成基準自体への異論ではない。本来検知するように設計されていない連続的な体験の劣化を、二値の適合判定シグナルに無理に検知させようとすることへの警鐘だ。

400%ズームでは高さも幅と同時に縮小する

監査の現場で驚くほど頻繁に見られる誤りは、幅だけを狭く設定しながら、デスクトップ並みの十分な高さを残してしまうことだ。それでは拡大条件の半分しか再現できていない。幅だけで測ると半分しか測れないという前回の測定が、まさにこの点を扱っている。

It should be noted that 400% applies to the dimension, not the area. It means four times the default zoom level viewport width and four times the default zoom level height.

— Understanding Success Criterion 1.4.10: Reflow

幅を320pxに固定し、高さを844、400、256、200の4段階で検証した。スクロール最上部の状態において、記事の有効スペースはそれぞれ762px、318px、174px、118pxとなった。すべての高さにおいて、損失した領域は正確に82pxだった。

これこそがアーキテクチャ上の核心的な知見だ。この損失は、ビューポートが狭くなるにつれてレスポンシブに縮小する割合ベースの値ではない。絶対的な固定ピクセルの通行料だった。分子である損失ピクセルが一定のまま、分母であるビューポートの高さだけが小さくなるため、画面の高さが低くなるほど相対的な打撃が急激に跳ね上がる。

高さ844pxのとき、82pxの損失は軽微に見える。だが高さ200pxでは、ビューポート全体の41.0%を奪い去る。通常のデスクトップ環境でのレビューでは無害に見えるコンポーネントが、拡大ユーザーが実際に直面するビューポート環境では致命的な閲覧障害と化す。

ヘッダーは疑っていた真犯人ではなかった

このような調査において、エンジニアが最初に疑うのはスティッキーヘッダーだ。その直感自体は妥当だ。W3Cの解説文書でも、スティッキー領域が小さなビューポートやズーム環境で画面の大きな割合を占有するリスクについて明確に警告している。

Sticky regions always stay visible in the viewport while the other content will disappear underneath when scrolling. In terms of content visibility, this is often not a problem on the desktop and on mobile devices in portrait orientation. However, when using mobile devices in landscape orientation or when zooming in on the desktop, sticky regions may block a big portion of the screen: the height of the sticky region may leave only a small part of the screen for the display of page content.

— C34: Using media queries to un-fixing sticky headers / footers

しかし、実測データは損失のメカニズムを明確に分流した。

ページ最上部において、高さ82pxのヘッダーは低いビューポート条件下でも通常のドキュメントフロー内に収まっていた。fixedでもstickyでもなくstatic配置となっていたため、ヒットテストの結果においても画面を覆い隠すブロッキング領域としては現れなかった。ユーザーが一度スクロールすれば、ヘッダーはドキュメントとともに上方へ流れ去り、ビューポート領域を消費しなくなった。

この挙動は、制約の厳しいビューポートサイズに対してW3Cが推奨している実装方針と正確に一致している。

It is strongly suggested that at smaller viewport sizes that such components are modified to have static positioning, or their display can be toggled by the user.

— Understanding Success Criterion 1.4.10: Reflow

要するに、自社チームが管理するヘッダーはすでに正しく設計されていたのだ。低いビューポートにおけるスクロール中盤のコストは0pxだった。この事実は運用上きわめて重い。開発チームが手元で修正できるUIコンポーネントばかりを調整し続ける一方で、実際の画面予算の毀損はランタイムに別の要因によって引き起こされているケースが多いためだ。

サードパーティの固定コンテナがスクロール中の画面予算を侵食していた

320x200のスクロール中盤状態において、有効なコンテンツ領域は110pxまで低下した。そこで画面上の付随要素を1つずつ除去しながら回復するピクセル数を計測した。

ヘッダーの除去による回復は0pxだった。読了進捗バー(#reading-progress)の除去による回復も0pxだった。トップへ戻るボタン(#back-to-top)の除去による回復も0pxだった。一方、最下部に固定された広告コンテナ(#fixed_container_bottom)を除去すると90pxが回復し、有効スペースは110pxから200pxへと拡大した。すべての付随要素を一括で除去した際の回復量も同じく90pxであり、個別回復量の総和(0 + 0 + 0 + 90 = 90)と完全に一致した。要素間の重複は存在しなかった。

このコンテナ自体は、ビューポートの高さが844pxであろうと200pxであろうと、実測値として400pxの高さを固定で持っていた。コンテナのスタイルには pointer-events: none が指定されていたが、ランタイムに挿入された内部領域のうち90px分が実際にコンテンツの到達を阻害していた。その90pxの遮蔽を引き起こしている具体的な子要素の正体は未特定であり、スクロール中盤で可視化されていたトップへ戻るボタン単体での回復効果は今回の検証では確認されなかった。

ここで注目すべきはDOMの詳細よりもビジネスへの影響だ。自社のリポジトリに存在しない外部タグが、ユーザーに記事が読める画面が残るかどうかを最終決定してしまう。外部アナリティクス、広告タグ、チャットウィジェット、同意バナー、ABテストなどの依存関係を抱えるWebサービスやデータプラットフォームを運営するチームなら、この構造に見覚えがあるはずだ。ソースコードの所有権を持っていることと、実際に提供される体験を掌握できていることは同義ではない。

高さ844pxのとき、同じ90pxの影響は画面全体の10.7%に過ぎない。しかし高さ200pxでは45.0%に達する。固定ピクセルのコストは、狭いビューポートに対して過酷な逆進税として作用する。

曖昧な不満を再現性のあるエンジニアリングの仕組みに落とし込む

有効な指標はあえて極限まで絞り込んだ。

usable_px = ヒットテストで article または main に実際に到達する縦方向ピクセル数

これはアクセシビリティ監査の代替ではない。リリースプロセスに組み込んで自前で運用できる計測指標だ。

テスト基盤には Playwright 1.58.2 と Chromium 145.0.7632.6 を使用し、本番サイトを対象に実行した。横方向3箇所(幅の25%、50%、75%)において2px刻みで走査し、到達した要素に基づいて各縦ピクセルを分類した。4つの高さ、2つのスクロール状態、3つの付随要素条件、5つのページ種別を組み合わせ、主要測定セット全体で計27回の実行を行った。

この指標を採用するにあたり、経営陣向けの報告に新たな体験指標を導入する際と同等の3つの検証プロセスを課した。

第一に、付随要素を一切持たないローカルのテキスト対照ページを検証した。すべての条件下で比率1.0を記録し、有効スペースはビューポートの高さと完全に一致した。計測機器自体が勝手に損失を作り出していないことを証明した。

第二に、反証の閾値を事前に定めた。320x200のスクロール中盤において、付随要素をすべて剥がしても回復量が10px未満であった場合、「固定要素が画面予算を奪っている」という仮説を破棄すると決めていた。実際の回復量は3回の検証すべてで90pxに達し、仮説は棄却されなかった。

第三に、不安定なものを結論から外すことだ。最下部コンテナによる遮蔽効果は、高さが大きなビューポートや一部のページ種別において散発的な発生傾向を示した。低い高さでは一貫して再現されたものの、あらゆる条件下で一律の絶対基準を支えるほどの安定性は確認できなかった。

これこそが、有用な内部指標を形骸化したダッシュボードの飾りにしないための手法だ。数値を1つに絞り込むこと。測定器自体に問題がないことを証明すること。データを見る前に仮説が棄却される基準を定めておくこと。そして、再現性のあるシグナルと未解明の変動要因を峻別することだ。

設けるべきは全社共通スコアではなく回帰検知ゲートだ

すべてのページに対して「最低何ピクセルの縦領域を残さなければならない」という絶対的な基準を一律に義務付けるべきではない。実測データはそのような万能の閾値を支持していないし、外部スクリプトの散発的な挙動によってCIが無駄に失敗するノイズを生むだけだ。

代わりに、代表的なページを対象として320x200の最上部状態でベースラインを記録する。そして、そのベースラインから usable_px が10%以上悪化した際にリリースを差し止める回帰ゲートを設けるのが合理的だ。

最上部状態を最初の防衛ラインとすべき理由は、その計測値が極めて安定しているからだ。四つの高さすべてで6ランの実行結果が完全にバイト単位で一致し、118pxという測定値は過去の監査結果とも再現性が取れていた。スクロール中盤の状態については、サードパーティのロード挙動の因果関係が完全に解明されるまでは、レポート専用の診断項目にとどめるのが現実的だ。今回の実測でも、ビューポートやページ種別によって遮蔽の発生頻度が3/6から6/6まで揺れていた。この状態に厳格なCIゲートをかけると、エンジニアのリソースが誤検知の対応にすり減ってしまう。

この分離は、ユニットエコノミクスの観点からも直接的な価値を持つ。1つのCIジョブで、サンプルのページを2つの条件下でテストできる。その測定コストは、リリース後に収益化タグ、同意バナー、サポートツールなどの外部依存が、ユーザーがまさに読もうとしている画面の主コンテンツを押し出していたと発覚する損失に比べれば取るに足らない。さらに重要なのは、この指標がコードレビューでの議論に価格表を提示することだ。ヘッダーの高さを12px広げる決定は、単なるデザインの好みの問題ではなく、制約されたビューポート予算に対する明確な消費として扱われるようになる。レイアウトのずれを数値に置き換えるとレビューの議論が変わることは、CLS 0.559を0.014まで下げた記録でも確認している。

適合性判定において反論は正しい

118pxしか有効な高さが残っていない状態を指して、WCAG 1.4.10の不適合だと主張するのは誤りだ。

通常の縦スクロールコンテンツに対する規範的な要求事項は、320 CSSピクセル相当の幅で閲覧できることだ。今回の対象サイトは、実測された横方向リフローの検査をすべて通過している。この達成基準は、残されるべき縦の閲覧高さの最小値を定めていない。この内部計測指標を契約、調達、法的な適合証明の根拠として持ち出すことは、公開基準の枠組みを逸脱した過剰な要求を生むことになる。

監査リソースが有限である以上、この境界線は厳格に守らなければならない。あらゆる望ましくない体験パターンを一律に規格違反として扱えば、真の不適合項目の修正優先度が下がり、修復タスクへの信頼が失われ、経営陣には法的リスクと製品品質上のリスクが混同されたレポートが届くことになる。

ただし、この反論を拡大解釈しすぎると危険だ。「基準違反ではない」ということは、「運用上の欠陥ではない」ことを意味しない。320pxの横リフローを維持していても、ランタイムに挿入された固定コンテナのせいで狭い画面での閲覧が著しく困難、あるいは不可能になる事態は現実に起きる。W3Cの解説文書自体も、ズーム時における固定コンテンツの体験上のリスクを明確に認めている。

Such sticky or fixed content can pose significant issues for those who would benefit from Reflow, as aside from obscuring keyboard focus, such sticky or fixed content can make reading content difficult if not impossible.

— Understanding Success Criterion 1.4.10: Reflow

正しいガバナンスモデルは、両者を分離して運用することだ。法的適合性の証明にはWCAGの基準を用い、リリースごとの体験悪化の管理にはビューポート予算の指標を用いる。両者を混ぜてはならない。前者はコンプライアンス報告の厳密性を担保し、後者はコンプライアンス報告では捉えきれない体験の劣化を検知する。

次のリリースサイクルで経営陣と技術リーダーが変えるべきこと

全面的なデザイン刷新から始める必要はない。まずは現状の棚卸しから着手する。ヘッダー、フッター、告知バナー、チャットの起動ボタン、同意確認UI、読了進捗バー、フローティングアクション、外部から挿入されるコンテナなど、ビューポートに吸着するあらゆる要素を洗い出す。実装が外部ベンダーによるものであっても、社内の責任者を必ず割り当てる。

次に、代表的な数ページの320x200最上部状態を測定し、その数値をベースラインとして記録する。その数値を、パフォーマンス、エラー率、アクセシビリティの適合状況と並べてデプロイレポートに記載する。ベースラインが確定する前にリリースゲート化を急いではならない。

自社で管理しているスティッキー領域には、画面の高さに応じた制御を導入する。C34が提示している手法、すなわち利用可能なビューポートの高さに応じてスティッキーを解除するパターンを適用する。

Define the first sticky regions using media query min-height properties, so they get fixed or un-fixed depending on the available space

— C34: Using media queries to un-fixing sticky headers / footers

サードパーティのコンテナについては、アプリケーションコードの実行後にコストが持ち込まれるため、CSSだけで解決できない場合がある。縦方向の占有ピクセル数を、外部ベンダーの受け入れ基準やデプロイ検証項目に明記する。「このタグを追加してよいか」という導入可否の議論を、「厳しい表示条件下で何ピクセルを消費し、問題発生時のロールバック権限は誰にあるのか」という議論へ転換する。それがコンバージョン効率とアクセシビリティ体験の双方を防衛する。

明日実行すべき実践的な一歩は、自社の代表的なページで320x200最上部のベースラインを測定することだ。もしそのベースラインが維持されているにもかかわらず、ユーザーから画面が塞がれているという指摘が続くなら、この固定ピクセル予算モデルの前提を見直せばよい。

参考資料

  1. Web Content Accessibility Guidelines (WCAG) 2.2 — SC 1.4.10 Reflow
  2. Understanding Success Criterion 1.4.10: Reflow
  3. C34: Using media queries to un-fixing sticky headers / footers
  4. CSS Text Module Level 3
アーカイブ