`<wa-popover>` のビューポート端マージンをShift Paddingで置き換え

shoelace-style/webawesome

<wa-popover> において、ビューポート端の余白を確保するために使用していたカスタムCSSマージンが shift-padding 属性に置き換えられ、top/bottom-start および top/bottom-end 配置でのポップオーバーとアロー位置ズレのリグレッションが修正されました。

背景

#2379 のモバイル対応修正において、ポップオーバーがビューポート端に近いときに視覚的な余白を確保するため、.body 要素に margin-inline / margin-block を用いたカスタムスタイルが導入されていました。しかし、このアプローチがリグレッションを引き起こしました。top/bottom-starttop/bottom-end のような斜め配置では、余白のためにずらされた .body の位置とアロー(▲)の位置がFloating UI内部で独立して計算されるため、両者が視覚的に乖離する問題が生じていました。

このリグレッションは、#2379のコメント で報告されており、本PRはその修正として作成されています。

技術的な変更

カスタムCSSマージンを削除し、Floating UIが提供する shift-padding 属性を用いてポップオーバーのシフト量を制御するように変更されました。

popover.styles.ts では、配置軸ごとに max-width / max-heightmargin-inline / margin-block を設定していた13行のCSSルールセットが丸ごと削除されています。

変更前:

/* 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);
}

変更後: (当該ルールセットを削除)

一方 popover.ts では、<wa-popup> コンポーネントへの属性として shift-padding="8" が1行追加されています。

変更後:

skidding=${this.skidding}
flip
shift
shift-padding="8"
?arrow=${!this.withoutArrow}
.anchor=${this.anchor}

shift はFloating UIのミドルウェアで、ポップオーバーがビューポートからはみ出さないように要素全体をシフトする処理です。shift-padding はそのシフト計算に使われるビューポート端からの余白値(px)を指定します。これによりシフト計算とアロー位置計算がFloating UIの内部で一貫して行われ、両者がずれなくなります。

設計判断

CSSによる見た目上の制約ではなく、レイアウトエンジン側へのパラメータ渡しという方向で問題が解決されました。

旧来のCSSアプローチは、.bodymargin を加えることで視覚的な余白を表現していました。しかしこの手法では、Floating UIがアローの位置を .body の位置とは独立して算出するため、「見た目のポップオーバー位置」と「アローが指す位置」が一致しないという根本的な矛盾が生じます。shift-padding を使えば、シフトの計算時点でビューポート端の余白がFloating UIに伝わるため、アロー位置も含めてレイアウトが整合します。CSS変数(--wa-space-m)を使った動的な幅計算も不要になり、スタイル定義がシンプルになる利点もあります。

まとめ

この修正は、「CSSでレイアウトを調整する」から「レイアウトエンジンに正しい制約を渡す」への設計修正です。Floating UIが提供する shift-padding を正しく活用することで、ポップオーバーとアローの整合性をフレームワーク側に委ね、手動のCSSハックを排除しています。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
3bbb68c4

この記事は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/コメントへのリンク記法がすべて正しく使用されています。

対象読者への適合性 ✓ PASS

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

Floating UIやWeb Componentsに関する知識を持つエンジニアを対象としており、専門用語を適切に使用し、冗長な説明を省いています。

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

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

各セクションが総論→各論→結論の構造を持ち、各パラグラフはトピックセンテンスで始まるなど、パラグラフ・ライティングの原則が守られており、非常に読みやすいです。

Diff内容との照合 ✓ PASS

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

記事で引用されているコードブロック(CSS削除、属性追加)は、提供されたDiff情報と完全に一致しています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

`shift-padding`, `Floating UI`, `margin-inline`など、関連技術の専門用語が正確かつ文脈に沿って使用されています。

説明の技術的正確性 ✓ PASS

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

CSSマージンによる問題点と`shift-padding`による解決策の説明は、技術的に正確かつ論理的です。

事実の突合 ✓ PASS

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

記事内の主張はすべてPRのDescriptionやDiff内のコード変更によって裏付けられており、ハルシネーションは見られません。「設計判断」はコード変更の意図を的確に解説したもので、推測の域を超えていません。

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

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

PR番号(#2411)、関連PR番号(#2379)、属性値(`shift-padding="8"`)など、記事内の数値や固有名詞はすべて正確です。

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

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

記事のタイトルはPRの主題「パディングバグの修正」を、より具体的に「Shift Paddingでの置き換え」として表現しており、内容を的確に要約しています。

外部知識の正確性 ✓ PASS

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

記事はPR情報とDiffから得られる事実に限定されており、バージョン情報やリリース予定といった外部知識の持ち込みはありません。

時間表現の正確性 ✓ PASS

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

「〜でした」「修正されました」といった時間表現が、過去の経緯と本PRによる変更を正確に反映しています。