べんりワザ・チートシート・早見表

positionの早見表

「absoluteにしたら変な場所へ飛んだ」「stickyが効かない」に答える早見表。positionの5つの値の違いと基準の決まり方を、動くデモつきで整理しました。z-indexのコツつき。

positionは、CSSで「重ねる」「浮かせる」「追従させる」を担当するプロパティ——なのにabsoluteにした瞬間に要素が画面のどこかへ飛んでいく経験、誰にでもあります。この記事は、5つの値の違いと「基準がどう決まるか」を引ける早見表です。

CSSpositionで重ねる・固定するpositionをはじめて学ぶ人は、先にCSSコースのこの回へ。この記事は「思い出す」ための早見表です

5つの値の早見表

元の場所位置の基準主な用途
static残るずらせない(標準)指定を打ち消したいとき
relative残る自分の元の位置少しだけずらす/absoluteの基準になる
absolute抜ける祖先のうちstatic以外の最も近い要素バッジ、重ねた文字、右上のボタン
fixed抜ける画面(ビューポート)追従ヘッダー、右下のボタン
sticky残るスクロールに応じて切りかわる追従する見出し、テーブルのヘッダー

いちばん大事なのは「元の場所が残るか、抜けるか」の列です。抜ける(absolutefixed)と、その要素があった場所は詰められ、周りのレイアウトが動きます。

下のデモで、値を切り替えて動きの違いを見てください。オレンジの箱にpositionを指定しています。

relativeでは箱3が動かないのに、absoluteにすると箱3が左に詰まります。これが「元の場所から抜ける」という意味です。

位置は top / right / bottom / left で決める

positionstatic以外にすると、この4つが使えるようになります。

.badge {
  position: absolute;
  top: 8px;      /* 基準の上から8px */
  right: 8px;    /* 基準の右から8px */
}

top: 8pxは「上端から下へ8px」、right: 8pxは「右端から左へ8px」です。書いた側から内側へ入っていくと覚えると迷いません。

4つまとめて書けるinsetもあります。

.overlay {
  position: absolute;
  inset: 0;       /* top・right・bottom・left すべて0=親いっぱいに広がる */
}

inset: 0は「親をぴったり覆う」の最短の書き方です。写真の上に半透明の黒を重ねるときの定番です。

absoluteの基準はどう決まるか

ここがpositionでいちばんつまずくところです。absoluteの位置は、祖先をさかのぼって、最初に見つかった「positionstatic以外の要素」を基準にします。

<div class="card">          <!-- position: relative -->
  <img src="photo.jpg" alt="写真">
  <span class="badge">NEW</span>   <!-- position: absolute -->
</div>
.card {
  position: relative;    /* ← これが基準の宣言 */
}
.badge {
  position: absolute;
  top: 8px;
  right: 8px;
}

.cardposition: relativeがないと、.badgeはページ全体の右上へ飛びます。 「absoluteにしたら変な場所へ行った」の原因は、ほぼ100%これです。

fixed——画面に張りつける

基準が画面そのものになるので、スクロールしても位置が変わりません。

.header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
}

sticky——途中から張りつく

stickyは「ふだんは普通に流れていて、スクロールで指定の位置に来たら張りつく」というハーフの動きをします。

.section-title {
  position: sticky;
  top: 0;
}

fixedとの違いは親の外へは出ないことです。親の領域を抜けると、いっしょにスクロールアウトします。だから「セクションごとに見出しが張りついて、次のセクションで入れかわる」という動きが1行で作れます。

z-index——重なりの順番

重なったときにどちらが前に出るかはz-indexで決めます。数字が大きいほど前です。

.modal {
  position: fixed;
  z-index: 100;
}

大事な前提が1つあります。z-indexpositionstatic以外の要素にしか効きません。 「z-indexを書いたのに前に出ない」ときは、まずpositionを指定してください。

もう1つの落とし穴が重なりの層です。親にz-indextransformopacity(1未満)が付いていると、その中の要素は親の層の中だけで順番を競うようになります。子にz-index: 9999を書いても、親の層ごと後ろに沈んでいれば前には出ません。「なぜか前に出ない」ときは、親をさかのぼって確認してください。

そのまま使えるレシピ6つ

画像の右上にバッジ

.card {
  position: relative;
}
.badge {
  position: absolute;
  top: 8px;
  right: 8px;
}

画像の上に半透明の黒を重ねる

.thumb {
  position: relative;
}
.thumb::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.35);
}

重ねた要素をど真ん中に置く

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);   /* 自分の幅・高さの半分だけ戻す */
}

top: 50%だけでは「要素の左上」が中央に来てしまいます。transformで自分の半分だけ戻すのがセットです。

スクロールしても消えないヘッダー

.header {
  position: sticky;
  top: 0;
  z-index: 10;
}

fixedではなくstickyにすると、本文が裏に潜り込まないので余白の調整が不要です。追従ヘッダーはstickyのほうが楽です。

右下に浮かぶボタン

.fab {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 50;
}

表の見出し行を固定する

thead th {
  position: sticky;
  top: 0;
  background: #fff;   /* 背景色は必須。透明だと下の行が透けて重なる */
}

効かないときのチェックリスト

  • topleftが効かないpositionstatic(標準)のままです。まずrelativeなどを指定します
  • absoluteが遠くへ飛ぶ → 基準にしたい親にposition: relativeを足します
  • stickyが動かないtopを書いたか、祖先にoverflowがないか、親の高さがあるか
  • z-indexが効かないpositionを指定したか、親が重なりの層を作っていないか
  • fixedが画面に張りつかない → 祖先にtransformfilterが付いていると、そこが基準になります
  • 横スクロールが出たabsolutefixedの要素が画面の外へはみ出しています。right側の値を見直します

まとめ

  1. 5つの値でいちばん大事な違いは「元の場所が残るか、抜けるか
  2. absoluteの基準は祖先でstatic以外の最も近い要素——親にrelativeを書くのがセット
  3. sticky親の中でだけ張りつくtop必須、祖先のoverflowに注意
  4. z-indexpositionを指定した要素にしか効かない
  5. 追従ヘッダーはfixedよりstickyが楽(本文が裏に潜らない)
べんりワザコピペで使えるCSSレイアウト集中央寄せや重ね合わせの実例は、コピペで使えるレイアウト集へ

positionは「基準がどこか」を言えるようになった瞬間に、こわくなくなります。飛んでいったら、まず親を見てください。

よくある質問

absoluteにしたら要素が思わぬ場所へ飛びました
absoluteの位置は「祖先のうち、positionがstatic以外になっている最も近い要素」を基準に決まります。その祖先が1つもないと、ページ全体が基準になるため遠くへ飛びます。基準にしたい親に position: relative; を書けば直ります。
position: stickyが効きません
3つを確認します。(1)top・bottomなどの位置指定を書いているか(stickyは位置指定が必須です)。(2)親に overflow: hidden や overflow: auto がついていないか(付いていると効きません)。(3)親の高さが足りているか(親の中でしか張りつけません)。
relativeとabsoluteの違いは何ですか?
relativeは「元いた場所を保ったまま、そこからずらす」、absoluteは「元いた場所から抜けて、基準からの座標で置く」です。relativeは周りのレイアウトに影響を残し、absoluteは残しません。
z-indexを大きくしても前に出ません
z-indexはpositionがstatic以外の要素にしか効きません。まずpositionを指定してください。それでも前に出ない場合は、親要素がz-indexやtransform、opacityで「重なりの層」を作っていて、その層ごと後ろに沈んでいる可能性があります。