ポップオーバーの配置方向別ビューポート制約を追加

shoelace-style/webawesome

モバイル端末などの狭い画面でポップオーバーがビューポートからはみ出す問題を、配置方向ごとに適切なサイズ制約とマージンを設けることで解決しました。

背景

狭い画面でポップオーバーが正しく収まらない問題が #2333 で報告されていました。先行する #2375 で初期対応が行われたものの、コメント中の議論で残課題が確認され、本PR #2379 がその追加修正として作成されました。

問題の核心は、ポップオーバーが上下に配置される場合は横幅がビューポートを超えうること、左右に配置される場合は縦高さがビューポートを超えうることです。これらは配置軸が異なるため、単一のルールでは対処できません。

配置方向の違いに応じた制約を個別に定義することで、両ケースを正しくカバーできる設計に落ち着いています。

技術的な変更

popover.styles.ts に、data-current-placement 属性の値に基づいて配置方向を判定し、方向ごとに異なる制約を適用するCSSルールが追加されました。

上下配置(top / bottom)の場合、ポップオーバーが水平方向にシフトする可能性があるため、横幅と水平マージンを制御します。

+  /* Reserve a small visual gap between the popover and the viewport edge on the axis where the popup can shift. */
+  .popover[data-current-placement^='top'] .body,
+  .popover[data-current-placement^='bottom'] .body {
+    max-width: min(var(--max-width), 100vw - (var(--wa-space-m) * 2));
+    margin-inline: var(--wa-space-m);
+  }
+
+  .popover[data-current-placement^='left'] .body,
+  .popover[data-current-placement^='right'] .body {
+    max-height: calc(100vh - (var(--wa-space-m) * 2));
+    margin-block: var(--wa-space-m);
+  }

上下配置の max-width には min(var(--max-width), 100vw - (var(--wa-space-m) * 2)) が使われています。min() 関数により、--max-width カスタムプロパティで指定された幅と、ビューポート幅からマージン両側分(--wa-space-m * 2)を引いた値の小さい方が採用されます。画面が十分広い場合は --max-width が、狭い場合はビューポート基準の制約が自動的に有効になる仕組みです。

左右配置(left / right)では、ポップオーバーが垂直方向にシフトするため、対象軸は高さになります。max-heightcalc(100vh - (var(--wa-space-m) * 2)) を設定し、margin-block で上下に余白を確保しています。

設計判断

配置軸に応じて制約対象(幅 vs 高さ)を切り替える方式 が採用されています。

ポップオーバーの位置調整(シフト)はアンカー要素に対して配置軸と垂直な方向に行われます。上下配置なら水平シフト、左右配置なら垂直シフトです。制約を掛けるべきは「シフトが発生する軸」であり、本変更はこの関係を正確に反映した実装になっています。

data-current-placement の属性セレクタで前方一致(^=)を使用している点も重要です。top-starttop-end といったバリアントを個別に列挙せず、top で始まる全パターンをまとめて捕捉することで、ルールを簡潔に保っています。

また、--max-width カスタムプロパティは上書きしておらず、min() による比較に留めることでユーザー定義の最大幅指定を尊重しています。この設計は #2375 で確立された方針を踏襲するものです。

まとめ

本変更は、配置方向という文脈に応じて制約軸を切り替えるという明快な原則のもと、最小限のCSSで上下・左右すべての配置パターンを網羅しています。min() と前方一致セレクタを組み合わせることで、カスタムプロパティとの後方互換性を保ちつつ、狭いビューポートでのポップオーバー表示の堅牢性が高まりました。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
05bbabbd

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

総論(リード文)→各論(背景、技術詳細、設計判断)→結論(まとめ)の構成が明確で、すべての必須要素が揃っており、理想的な構成です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト、GitHubのPR/Issueへのリンク記法がすべて正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

専門用語が適切に使用されており、過度な説明がなく、専門知識を持つエンジニアという対象読者に適合しています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論→各論の構成になっており、各段落はトピックセンテンスで始まり、1段落1トピックの原則が守られています。非常に読みやすいです。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事で引用されているコードブロックは、提供されたDiffの内容と完全に一致しており、ファイル名も正確です。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「ポップオーバー」「ビューポート」「属性セレクタ」「カスタムプロパティ」などの技術用語が、文脈に沿って正確に使用されています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

min()関数の動作や前方一致セレクタの意図など、コード変更に関する技術的な説明は論理的かつ正確です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

すべての主張はPRのDiffやDescription、および関連PRの文脈で裏付けられています。情報が少ないPRから背景を的確に補足しており、ハルシネーションは見られません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#2379)、関連PR番号(#2375)、Issue番号(#2333)など、すべての数値と固有名詞は正確です。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトル「ポップオーバーの配置方向別ビューポート制約を追加」は、PRの技術的な内容を抽象的なPRタイトルよりも具体的に、かつ正確に表現しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事の内容はPRとその関連情報に限定されており、LTSやEOLといったPR外の知識の追加はありません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

PR間の前後関係を示す「先行する」などの表現は、事実に基づいており正確です。