ページフッターのビューポートオーバーフローを修正
wa-page の slot="footer" があるページで、コンテンツが短い場合でもフッター分だけビューポートがはみ出し、不要なスクロールバーが表示されていました。今回の PR はレイアウトを CSS 主導に切り替えることで、フッターを正しくビューポート下部に固定し、ページ全体が期待通りに収まるように修正します。
背景
問題の概要: wa-page にフッターが配置されると、コンテンツ領域がヘッダー高さのみで計算され、フッター分が余分に加算されてページ高さがビューポートを超えていました。その結果、コンテンツがほとんど無くても垂直スクロールが常に発生し、ユーザー体験が低下していました。
再現手順: 短いコンテンツを持つ <wa-page> に slot="footer" を設定し、ビューポートよりも高さが小さい画面で表示すると、フッターがビューポート下に隠れず、ページ全体がフッター分だけ長くなります。この挙動は PR が対象とした regression の中心です。
影響範囲: フッターを使用する全ての wa-page インスタンスに対して発生し、レイアウト崩れはデスクトップ・モバイルともに顕在化します。
技術的な変更
CSS レイアウトの見直し: packages/webawesome/src/components/page/page.styles.ts でグリッドボディの配置と高さ計算を修正しました。主な変更点は以下の通りです。
@@
[part~='body'] {
- min-height: 100%;
- align-items: flex-start;
+ min-height: 100%;
+ align-items: start;
}
@@
- height: min(
- var(--main-height, 100dvh),
- calc(100dvh - var(--header-top) - var(--banner-top) - var(--subheader-top))
- );
- max-height: min(
- var(--main-height, 100dvh),
- calc(100dvh - var(--header-top) - var(--banner-top) - var(--subheader-top))
- );
+ min-height: 0;
+ /** Allows the menu / aside to always be 100% of the height of the main content area */
+ align-self: stretch;
+ max-height: calc(100dvh - var(--header-top) - var(--banner-top) - var(--subheader-top));
}
-
align-itemsをflex-startからstartに変更し、グリッド子要素が余分な余白なしで配置されるようにしました。 - 高さ算出に使用していた
min()関数を除去し、min-height: 0とmax-heightの固定計算に置き換えることで、メニュー・サイドバーがメイン領域の高さに自然に追従し、フッター分の余剰が排除されました。
不要になった JavaScript ロジックの削除: packages/webawesome/src/components/page/page.ts からビューポート高さ算出に使用していた updateAsideAndMenuHeights メソッドと、関連するスクロールリスナーの登録・解除が削除されました。
@@
- if (entries.length > 0) {
- this.updateAsideAndMenuHeights();
- }
@@
- document.addEventListener('scroll', this.updateAsideAndMenuHeights, { passive: true });
@@
- updateAsideAndMenuHeights = () => {
- const visiblePixels = this.visiblePixelsInViewport(this.main);
-
- if (visiblePixels == null) {
- return;
- }
-
- this.aside.style.setProperty('--main-height', `${Math.round(visiblePixels)}px`);
- this.menu.style.setProperty('--main-height', `${Math.round(visiblePixels)}px`);
- };
@@
- document.removeEventListener('scroll', this.updateAsideAndMenuHeights);
削除により、ビュー高さの決定は純粋に CSS に委譲され、ランタイム計算のオーバーヘッドが排除されました。
設計判断
CSS 主導へのシフト: 本変更はレイアウトに関わるロジックを CSS に集約し、100dvh を基準にした高さ計算へ統一した点が特徴です。これにより、ブラウザのネイティブビューポート単位に依存し、JavaScript の手動計算による不整合リスクが低減されました。
後方互換性の維持: コンポーネントの公開 API は変更されておらず、wa-page の使用方法に差分はありません。CSS の内部実装が変わっただけなので、既存の実装はそのまま動作し、アップグレード時のリグレッションリスクは最小化されています。
トレードオフ: 高さ計算を CSS のみで行うため、極端に小さなビューポートでの微調整が必要な場合はカスタムプロパティ --main-height を上書きすることで対応可能です。柔軟性は保持しつつ、デフォルト動作はシンプル化されています。
まとめ
今回の PR は CSS によるビューポート基準のレイアウト見直し と 不要な JavaScript ロジックの除去 によって、wa-page のフッターがビューポートからはみ出す regression を根本的に解消しました。フッターは正しくビューポート底部に固定され、余計なスクロールが発生しなくなることで、ユーザー体験と保守性が向上します。