CSS positionプロパティジェネレーター

static・relative・absolute・fixed・stickyの5種類のpositionをGUIで切り替え、top/right/bottom/left・z-indexの効果をリアルタイムのプレビューで確認しながらCSSコードを生成できる無料ツール。

positionの5つの値を見比べる

`position` は要素をどこに置くかを決めるプロパティで、`static`・`relative`・`absolute`・`fixed`・`sticky` の5つの値を取ります。このツールでは値を切り替えながら `top`/`right`/`bottom`/`left` と `z-index` の効き方をその場で確かめ、CSSを生成できます。

**`absolute` で要素が思わぬ場所へ飛ぶ原因は、ほぼ1つに絞られます。基準になるのは「最も近い、`position` が `static` でない祖先」だからです。** 該当する祖先が1つも無ければ、要素はページ全体を基準にしてしまいます。**親に `position: relative` を付け忘れている**のが、この現象のほとんどの正体です。**`sticky` にもよく知られた落とし穴があり、祖先のどこかに `overflow: hidden` や `overflow: auto` があると、貼り付きが働きません。** また `z-index` は「重なり合いコンテキスト」という入れ子の中で閉じるため、**外側の要素より小さいコンテキストにいる限り、いくら値を大きくしても外側の上へは出られません。**

使い方

  1. positionの値を切り替える 5つの値を順に試すと、それぞれの基準の違いが見えます。
  2. オフセットを動かす **`static` のときだけ `top` などが一切効かないことを確かめてください。**
  3. z-indexを変える 重なり順がどう変わるかを確認できます。
  4. 生成されたCSSをコピーする 狙った配置になったら、そのままコードへ貼り付けられます。

使いこなすためのヒント

  • position: relativeにしてtop/leftを設定すると、Box Bが本来の位置から見た目だけずれます。Box C(後の要素)の位置は変わらない点に注目してください。
  • position: absoluteまたはfixedに切り替えると、Box Bが通常のフローから完全に外れるため、直後のBox Cがその分だけ詰めて配置される様子が確認できます。
  • z-indexは複数の要素が重なったときの重なり順を決めますが、position: staticの要素には効果がありません。「z-indexを指定する」を試す前にpositionを変えてみてください。
  • position: stickyはスクロール可能なコンテナの中でのみ効果を発揮します。プレビュー枠を実際にスクロールして、途中で固定される様子を確認してください。
  • 生成されたCSSコードはコピーしてそのまま自分のスタイルシートに貼り付けられます。実際のページでも同じ見た目になるか確認してみましょう。

活用シーン

見出しを画面上部に貼り付ける

**`sticky` を使えば、スクロールしても見出しが残ります。**

バッジやアイコンを角に重ねる

親に `relative`、子に `absolute` という組み合わせが基本形です。

固定のボタンを置く

`fixed` は画面に対して位置が決まるため、スクロールしても動きません。

重なり順の不具合を調べる

**要素が別の要素の下に隠れるとき、重なり合いコンテキストを疑えます。**

positionの用語

static
初期値です。**この値のあいだは `top` などのオフセットも `z-index` も効きません。**
relative
**元の位置を基準にずらす**指定です。自分は動いても、周囲は元の場所を空けたままにします。
absolute
**最も近い、`position` が `static` でない祖先を基準に配置します。** 該当が無ければページ全体が基準になります。
fixed
画面(ビューポート)を基準に配置します。スクロールしても位置が変わりません。
sticky
通常の位置に置かれ、指定の位置まで来ると貼り付きます。**祖先に `overflow` が指定されていると働きません。**
重なり合いコンテキスト
重なり順が閉じる入れ子の単位です。**この中の `z-index` は、外の要素とは直接比べられません。**

よくある質問

absoluteは「最も近い位置指定された祖先要素(position: static以外の親)」を基準に配置され、祖先がなければ最終的にページ全体(初期包含ブロック)が基準になります。一方fixedは常にブラウザのビューポートを基準に配置されるため、ページをスクロールしても画面上の同じ位置に留まり続けます。

stickyが効かない主な原因は、親要素に overflow: hidden や overflow: auto が指定されている、親要素の高さがsticky要素とほぼ同じで固定される余地がない、またはtop/bottom等のオフセットが1つも指定されていないことです。加えてstickyの効果は親コンテナの範囲内でしか発揮されないため、親要素自体をスクロール領域として設計する必要があります。

relativeは要素自身がposition: staticだった場合の本来の位置を基準に、top/right/bottom/leftの指定分だけ見た目上ずらします。要素が占めるスペース(他の要素への影響)は元の位置のまま確保され続ける点がabsoluteとの大きな違いです。

z-indexはposition: static以外(relative・absolute・fixed・sticky)の要素にしか効果がありません。また、親要素にz-indexとposition以外のスタイル(transformやopacityなど)が指定されていると独自の重なり文脈(stacking context)が作られ、子要素のz-indexが期待通りに働かないことがあります。

基準にしたい親要素にposition: relativeを指定するのが定番の方法です。offsetの値を指定しなくても、position: relativeを付けるだけで「位置指定された要素」となり、その子孫のabsolute要素はその要素の内側を基準に配置されるようになります。
ツールくん

余談ですが ― position: stickyが標準化されるまでの道のり

CSSのposition プロパティは古くからstatic・relative・absolute・fixedの4種類が存在していましたが、「スクロールに応じて途中から固定される」ヘッダーやサイドバーを実現するには、長らくJavaScriptでスクロールイベントを監視し、position: fixedへの切り替えを手動で行うしかありませんでした。CSSだけで完結する仕組みは存在しなかったのです。

position: stickyの構想自体は2012年頃からCSSの仕様(CSS Positioned Layout Module Level 3)に盛り込まれていましたが、実装が難しく、SafariがWebKitのベンダープレフィックス付き(-webkit-sticky)で先行実装したのが2013年頃でした。Chromeが標準のstickyキーワードに対応したのは2017年で、Firefoxを含む主要ブラウザで安心して使える状態になったのはさらに数年後の2020年前後のことです。

position: stickyの「途中で固定される」挙動は、実装上はrelativeとfixedのハイブリッドとして説明されます。通常はrelativeとして通常のフローに従い、スクロール位置が指定したオフセットに達すると、その場でfixedに切り替わったかのように振る舞います。この切り替えが親要素のスクロール範囲内でしか発生しない点が、意図せずstickyが「効かない」と感じる原因の多くを占めています。

現在ではテーブルの見出し行を固定する・目次をスクロールに追従させるなど、stickyはWebデザインの定番テクニックとして広く使われています。JavaScriptによるスクロール監視が不要になったことは、パフォーマンスとコードの単純さの両面で大きな進歩でした。