Menu

CSS position の使い方: absolute、relative、fixed、sticky

position: absolute は、一番近い位置指定された祖先の中で、要素を正確な座標に置きます。absolute と position: relative の組み合わせ方、fixed と sticky、top/right/bottom/left と inset、sticky が効かないときの原因を解説します。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

position: absolute を 1 つの例で

absolute で配置した要素は通常のフローから取り出され、top、right、bottom、left で配置されます。これらの位置は、position が static 以外の一番近い祖先から測られます。親に position: relative を付けるのはこのためです:

.card から position: relative を消すと、位置指定された祖先がなくなるので、バッジはページ全体の右上に飛びます。「position absolute が効かない」という疑問のほとんどは、この 1 行で説明できます。

absolute の要素について知っておきたいこと:

  • 場所を取りません。 見出しと段落は、バッジがないかのように配置されます。
  • 幅は内容に合わせて縮みます。 width か、left と right の両方を指定した場合は別です。
  • 位置は包含ブロックの padding の端、つまり border の内側から測られます。

position の 5 つの値

値フローに残るか位置の基準主な使い道
static (初期値)残る位置の指定は無視される普通の要素
relative残る。元の場所も確保される本来の自分の位置absolute の子の基準、少しだけずらす
absolute残らない一番近い位置指定された祖先 (なければページ)バッジ、ツールチップ、オーバーレイ、閉じるボタン
fixed残らないビューポートヘッダー、チャットボタン、Cookie バー
sticky残る指定位置に達した後のスクロールコンテナテーブルの見出し、セクションのタイトル、サイドバー

position: relative

relative の要素は、フローの中の元の場所にとどまります。位置を指定すると描かれる場所は動きますが、元の場所は確保されたままなので、周りは何も動きません:

ボックス 2 は 20px 下、20px 右に描かれてボックス 3 と重なりますが、ボックス 3 は動いていません。ボックス 2 の元の場所を空けたままです。relative だけで要素を動かすことはあまりありません。主な役割は、absolute の子の基準のボックスになることです。

位置の指定と inset

top、right、bottom、left には長さ、パーセント (包含ブロックが基準)、auto を指定できます。inset のショートハンドは、margin と同じ順番で 4 つをまとめて指定します:

.overlay {
  position: absolute;
  inset: 0;              /* top: 0; right: 0; bottom: 0; left: 0; */
}
.corner {
  position: absolute;
  inset: auto 16px 16px auto;  /* bottom right corner, 16px in */
}

向かい合う 2 辺を指定すると要素は伸びます。left: 0; right: 0 で包含ブロックと同じ幅になります。absolute の子に inset: 0 を指定するのが、カードをオーバーレイで覆う定番の方法です。

absolute と transform で中央に置く

top: 50%; left: 50% で、要素の左上の角が中央に来ます。続けて translate(-50%, -50%) で、要素自身のサイズの半分だけ戻します:

要素をフローに残せるなら、flexbox や grid のほうが簡単に中央に置けます。すべての方法の比較は div の中央寄せのページ にあります。

position: fixed

fixed の要素はビューポートを基準に配置され、ページをスクロールしてもその場にとどまります:

.chat-button {
  position: fixed;
  bottom: 16px;
  right: 16px;
}

注意点が 2 つあります。fixed の要素は場所を取らないので、body に padding-top を付けないと、固定ヘッダーがページの上部を覆います。また、祖先に transform、filter、perspective があると、ビューポートではなくその祖先が基準になり、要素は祖先と一緒にスクロールします。

position: sticky

sticky の要素は、指定した位置に達するまでは普通にスクロールし、その後は親の終わりがスクロールで通り過ぎるまでそこに張り付きます。下のボックスをスクロールしてみてください:

各文字は、そのセクションが見えている間はスクロールボックスの上端に張り付き、次の文字に押し出されます。sticky の要素は親から出ることがないからです。

sticky が張り付かないときは、次を確認しましょう:

  • 位置の指定がない。 top、bottom、left、right のどれもなければ、position: sticky は何もしません。
  • 祖先に overflow: hidden、auto、scroll がある。 その祖先がスクロールコンテナになり、実際にスクロールしなければ何も張り付きません。はみ出しを隠すだけなら overflow: clip を使います。
  • 親が sticky の要素と同じ高さしかない。 親の中に張り付く余地がありません。
  • flex や grid の親が要素を引き伸ばしている。 flex の行の中なら、sticky のサイドバーに align-self: flex-start を追加します。

よくある間違い

  • absolute の要素の親に position: relative を付け忘れる。
  • ページのレイアウトに absolute を使う。 absolute の要素はお互いも内容も無視するので、小さい画面で文字が重なります。レイアウトには flexbox か grid を使い、absolute は小さな装飾に使いましょう。
  • static の要素に位置を指定する。 position がなければ top: 10px は何もしません。
  • どの要素が上に来るかで悩む。 重なった位置指定された要素の順番は z-index で決まります。
  • 固定ヘッダーが内容を隠す。 ページに padding を付けるか、scroll-padding-top を指定して、アンカーリンクの移動先がヘッダーの下に来るようにします。

よくある質問

position: absolute は何をしますか?

要素を通常のフローから取り出し (ほかの要素はその要素がないかのように並びます)、top、right、bottom、left で配置します。基準は包含ブロック、つまり position が static ではない一番近い祖先です。

親要素を基準に absolute で配置するには?

親に position: relative;、子に position: absolute; と top: 0; right: 0; のような位置を指定します。位置指定された親がないと、子はページを基準に配置されます。

relative と absolute の違いは何ですか?

relative は要素をフローに残したまま描く位置だけをずらし、元の場所はそのまま残ります。absolute は要素をフローから取り出し、位置指定された祖先を基準に配置します。

position: sticky が効かないのはなぜですか?

たいてい次の 3 つのどれかです。top (などの位置) を指定していない、祖先に overflow: hidden や auto があってそれがスクロールコンテナになっている、sticky の要素の親がその要素と同じ高さしかなく、張り付く余地がない。

fixed と sticky の違いは何ですか?

fixed はフローから取り出され、ビューポートに固定されます (祖先に transform や filter がある場合を除く)。sticky はフローに残って普通にスクロールし、指定した位置に達すると、親が画面にある間だけ張り付きます。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める