ナローなビューポートでのポップオーバーのはみ出しを修正
<wa-popover> が狭いビューポートで水平方向にはみ出し、意図しないスクロールを引き起こすバグを修正しました。.body 要素の幅と最大幅の計算式を見直し、ビューポート幅を上限とする制約を追加しています。
背景
<wa-popover> の .body 要素にはこれまで width: max-content が適用されており、コンテンツが要求する幅をそのまま採用していました。ビューポートが十分に広い場合は問題ありませんが、#2333 で報告されたように、幅の狭いモバイル表示(例: 392px)ではポップオーバーがビューポートを超えて拡張し、水平スクロールが発生していました。
問題の根本は max-content が親コンテナやビューポートの制約を無視してコンテンツの自然な幅を優先するCSSキーワードであることにあります。ポップオーバーが表示されると <body> の幅が広げられ、閉じるまでスクロール状態が継続するという挙動が確認されています。Windows・Android を問わず、Chrome・Firefox・Brave のすべてで再現していました。
技術的な変更
.body 要素のCSS定義を2箇所修正することで、ビューポートを超えないよう上限を設けました。
変更前:
.body {
display: flex;
flex-direction: column;
width: max-content;
max-width: var(--max-width);
...
}
変更後:
.body {
display: flex;
flex-direction: column;
width: auto;
max-width: min(var(--max-width), 100vw);
...
}
width を max-content から auto に変更したことで、要素は利用可能なスペースの範囲内で自然に広がるようになりました。max-width には min() 関数を使い、var(--max-width) と 100vw のうち小さい方が適用されます。これにより、ビューポートが十分に広い場合は既存の --max-width カスタムプロパティが機能し続け、狭い画面ではビューポート幅が自動的に上限として機能します。
ドキュメントのサンプルコードにも修正が加えられています。placement の例で使われていたフレックスコンテナに flex-wrap: wrap が追加され、モバイル幅でボタン群が折り返されるようになりました。また、autofocusの例の <wa-textarea> の rows が 3 から 2 に調整されています。
設計判断
min() CSS関数による二重制約が採用された点が本修正の核心です。--max-width カスタムプロパティを廃止したり、JavaScriptでビューポート幅を動的に計算したりするのではなく、CSSの min() 関数を使って既存の設計を維持しつつビューポート制約を追加する形を選んでいます。
ただし、現状の修正では margin 分が考慮されていません。PR本文には「ポップオーバーのマージン分を差し引いた幅に合わせる」という意図が記されており、100vw から余白を引いた値(例: calc(100vw - 2 * var(--margin)))を使う形が理想ですが、今回のdiffでは 100vw がそのまま採用されています。マージンを考慮した場合でも、CSSカスタムプロパティを通じて同様の式で対応できる余地は残っています。
まとめると、CSSのみで完結する変更であるため、JavaScriptのロジックや既存のカスタムプロパティインターフェースへの影響はなく、--max-width を独自に設定しているユーザーにとっても後方互換性が保たれています。
まとめ
width: max-content というビューポートを無視する定義を width: auto に変更し、min() でビューポート幅を上限として追加したことで、ナローな画面でのポップオーバーのオーバーフローが解消されました。CSSの標準機能のみで既存のカスタマイズ性を維持しながら不具合を修正した、シンプルかつ影響範囲の小さい判断です。