sticky-and-fixed-elements について
fixedとstickyの使い分けや、重なり合うUI要素の管理を案内するデザインスキルです。ナビゲーションヘッダー、モバイルの下部ツールバー、テーブル見出し、z-indexトークン、固定レイヤー数を扱います。
主な機能
- 01fixedとstickyの使い分けを比較
- 02グローバルヘッダーとモバイルツールバーの指針
- 03スクロール中もテーブル見出しを表示
- 04名前付きトークンでz-indexを管理
- 05固定要素の重なりを抑制
活用シーン
- 01常時表示するナビゲーションを設計
- 02テーブルの列見出しをスクロール中も表示
- 03モバイルツールバーのセーフエリアを確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dembrandt/ dembrandt-skills --skill sticky-and-fixed-elementsインストール後、Claude Code で/sticky-and-fixed-elementsを入力して読み込まれたか確認します。
詳細
固定要素と追従要素
position: fixed と position: sticky
| プロパティ | 動作 | 用途 |
|---|---|---|
position: fixed | ドキュメントフローから除外されます。スクロールや親要素に関係なく、常に同じビューポート位置に留まります。 | グローバルナビゲーションヘッダー、下部ツールバー、フローティングアクションボタン |
position: sticky | スクロールしきい値に達するまではドキュメントフロー内に留まり、達するとその位置に固定されます。親要素がスクロールして通り過ぎると、フローに戻ります。 | テーブルの列ヘッダー、長いリスト内のセクション見出し、スクロールコンテナー内のページ内ツールバー |
要素が特定のセクションやスクロールコンテキストに属する場合は、fixed より sticky を優先してください。固定要素はすべての要素より手前に表示され、ビューポート全体に影響するため、本当にグローバルな UI にのみ使用してください。
上部 — ナビゲーションヘッダー
グローバルナビゲーションヘッダーは、最も一般的な固定要素です。次の点に留意してください。
- ユーザーがいつでも別の場所に移動できるよう、常に表示しておきます
- コンテンツ領域を最大限に確保できるよう、できる限り薄くします。一般的な高さは 48〜64px です
- 背景とシャドウを付け、下をスクロールするコンテンツが透けないようにします
- スクロール時には、控えめなシャドウ(
--shadow-sm)で背後にコンテンツがあることを示します
.site-header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: var(--header-height);
background: var(--color-surface);
box-shadow: var(--shadow-sm);
z-index: var(--z-header);
}
固定ヘッダーの高さに合わせた上部パディングをページ本文に設定して調整します。
body { padding-top: var(--header-height); }
下部 — モバイルのツールバー
モバイルでは、画面下部が片手の親指で最も操作しやすい領域です。常時表示する下部ツールバーは、次の用途に適しています。
- 主要なナビゲーション(iOS と Android で一般的な下部タブバー)
- 現在のビューに応じたアクション(編集、共有、削除)
- 最も重要なアクションを 1 つだけ配置するフローティングアクションボタン(FAB)
下部ツールバーでは、次の点に留意してください。
- ホームインジケーターのあるデバイスでは、セーフエリアのインセットを考慮します:
padding-bottom: env(safe-area-inset-bottom) - 背景色、上部の境界線、シャドウなどを使って、コンテンツと視覚的に区別します
- 項目は最大 3〜5 個にします。5 個を超える場合は、メニューまたは別のパターンに移します
- ナビゲーションタブにはラベル付きアイコンを、コンテキストツールバーにはアイコンのみ(ツールチップ付き)を使用します
デスクトップでは、下部ツールバーは一般的ではありません。ステータスバー、エディターツールバー、コマンドパレットがデスクトップでの同等の UI で、通常は下部に position: fixed を指定するか、スクロールコンテナー内で position: sticky を指定します。
スティッキーテーブルヘッダー
スクロールコンテナー内のデータテーブルでは、列ヘッダーを固定することで、各列の意味を見失わないようにできます。
thead th {
position: sticky;
top: 0;
background: var(--color-surface);
z-index: 1;
}
行識別子のためにテーブルの最初の列も固定する場合、左上のセルには top: 0 と left: 0 の両方が必要です。また、ヘッダー行と固定列の両方より手前に表示するため、より高い z-index を設定します。
重なり順と Z-index
スティッキー要素と固定要素はスタッキングコンテキストを作成します。任意の数値ではなく、名前付きトークンとして z-index を定義してください。
--z-base: 0;
--z-dropdown: 100;
--z-sticky: 200;
--z-header: 300;
--z-modal: 400;
--z-toast: 500;
固定要素またはスティッキー要素にはすべて、トークンを使って z-index を明示的に指定する必要があります。z-index: 9999 のような場当たり的な値は避けてください。これはスタッキングコンテキストが適切に管理されていないことを示し、いずれ競合の原因になります。
固定レイヤーはいくつまでならよいか
固定レイヤーが増えるたびにコンテンツ領域が狭くなり、視覚的な複雑さも増します。1 ページに必要な固定要素は、通常、次の数を超えないようにします。
- 固定ヘッダー 1 つ(上部)
- 固定ツールバーまたは下部ナビゲーション 1 つ(下部、モバイル)
- フローティングアクションボタンまたはコンテキストオーバーレイ 1 つ
固定ヘッダー、固定下部ツールバー、フローティングボタン、スティッキーサイドバー、スティッキーテーブルヘッダーをすべて同時に使うのは、レイヤーが多すぎます。可能な場合は統合してください。
レビューチェックリスト
- セクションに属する要素には
stickyを使い、本当にグローバルな UI にのみfixedを使っていますか? - 固定ヘッダーの高さに合わせて、本文のパディングで調整していますか?
- モバイルの下部ツールバーで
env(safe-area-inset-bottom)を考慮していますか? - すべての z-index 値を任意の数値ではなく、名前付きトークンとして定義していますか?
- 同時に使用する固定レイヤーの数を最小限にしていますか?ほとんどの場合、ヘッダーと下部要素 1 つまでにしていますか?
- 固定要素の背景とシャドウにより、その背後をスクロールするコンテンツが透けて見えないようになっていますか?