問題
Next.jsプロジェクトで、tailwind cssを使っています。
画面最下部に固定の予約ボタンを配置したところ、フッターが予約ボタンの下に隠れてしまいました。
※ 業務プロジェクトのため、スクリーンショットは省略しています
<footer>
{/* 藍色背景エリア(110px) */}
<div className="flex h-[110px] ... bg-primary">
{/* 利用規約、プライバシーポリシーなどのリンク */}
</div>
{/* 白背景エリア(50px) */}
<div className="flex h-[50px] ... bg-white">
{/* ロゴ */}
</div>
</footer>
予約ボタン(問題のあるコード)
<div className="fixed bottom-0 left-0 right-0 z-50 border-t bg-white px-4 py-3"> // この部分を修正
<div className="mx-auto flex max-w-[1000px] items-center justify-between">
<div>
<span className="text-2xl font-bold text-primary">¥{価格データ}</span>
<span className="text-sm text-muted-foreground">/日</span>
</div>
<Button size="lg" className="px-8">
予約する
</Button>
</div>
</div>
fixed bottom-0 を使うと、要素はドキュメントの流れから外れ、常にビューポート(画面)の最下部に固定されます。
そのため、スクロールしてもフッターの上に重なり続けてしまいます。
修正方法
fixed を sticky に変更し、不要なプロパティを削除します。
- <div className="fixed bottom-0 left-0 right-0 z-50 border-t bg-white px-4 py-3">
+ <div className="sticky bottom-0 border-t bg-white px-4 py-3">
※なお、実装では left-0 / right-0 / z-50 などの指定も見直していますが、本記事では「fixed → sticky」の要点に絞るため詳細は省略します。
修正後のコード
<div className="sticky bottom-0 border-t bg-white px-4 py-3"> // この部分を修正
<div className="mx-auto flex max-w-[1000px] items-center justify-between">
<div>
<span className="text-2xl font-bold text-primary">¥{価格データ}</span>
<span className="text-sm text-muted-foreground">/日</span>
</div>
<Button size="lg" className="px-8">
予約する
</Button>
</div>
</div>
なぜ直るのか
| プロパティ | 挙動 |
|---|---|
fixed |
ビューポート(画面)に対して固定。ドキュメントの流れから外れる |
sticky |
親要素内でスクロールに追従し、親要素の境界で止まる |
実際の構造
<body>
├── <main> ← 親要素(コンテンツ領域)
│ ├── 車両情報
│ ├── 予約カレンダー
│ └── 予約ボタン(sticky) ← ここ
│
└── <footer> ← 兄弟要素(親ではない)
└── 利用規約など
sticky の動き
┌─────────────────────┐
│ <main> │ ← 親要素の範囲
│ ┌───────────────┐ │
│ │ コンテンツ │ │
│ │ │ │
│ │ │ │
│ └───────────────┘ │
│ ┌───────────────┐ │
│ │ 予約ボタン │ │ ← sticky: 親(<main>)の中だけで固定
│ └───────────────┘ │
└─────────────────────┘ ← ここが親の境界
┌─────────────────────┐
│ <footer> │ ← 親の外なので、予約ボタンはここに入れない
└─────────────────────┘
- sticky 要素は自分の親要素の中でしか動けない
- 親要素()の下端に達すると、そこで止まる
- フッターは親の外にあるので、重ならない
終わりに
最初はfixedで実装しましたが、フッターとの重なりがなかなか解決できず苦戦しました。
stickyが親要素の境界内でしか動かないという特性を理解したことで解決できました。