CSSのpositionプロパティ(static / relative / absolute / fixed / sticky)を使い分ける

CSS でレイアウトを組むとき、要素の配置方法を決めるのが position プロパティだ。5 つの値があり、それぞれ振る舞いが大きく異なる。

static(初期値)

すべての要素は初期状態で position: static が適用されている。通常フロー(上から下、左から右)に従って配置され、top / left などのオフセット指定は効かない。特別な理由がなければ明示的に書く必要はない。

.box {
  position: static;
  /* top: 10px; は無視される */
}

relative

要素は通常フローの位置に留まったまま、そこからの相対位置でずらすことができる。元の場所にはスペースが残り続けるため、周囲のレイアウトには影響を与えない。また、子要素に absolute を使うときの基準点としても頻繁に利用される。

.box {
  position: relative;
  top: 20px;
  left: 10px;
}

この例では、本来の位置から下に 20px、右に 10px ずれた場所に描画される。

absolute

通常フローから完全に外れ、直近の position: static 以外の祖先要素を基準に配置される。基準となる祖先がなければ、html 要素(ページ全体)が基準になる。

HTML
CSS
JavaScript
<div class="parent">
  <div class="child">absolute</div>
</div>
.parent {
  position: relative;
  width: 200px;
  height: 150px;
  background: #e0e7ff;
  border: 2px solid #6366f1;
}
.child {
  position: absolute;
  bottom: 10px;
  right: 10px;
  background: #6366f1;
  color: #fff;
  padding: 6px 12px;
  font-size: 14px;
}

親要素に relative を設定し、子要素を absolute で右下に配置した例だ。親の relative がないと、ページ全体の右下に飛んでしまう。

fixed

ビューポート(ブラウザの表示領域)を基準に固定される。スクロールしても位置が変わらないため、ヘッダーやフローティングボタンに向いている。

.header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  background: #1e293b;
  color: #fff;
  z-index: 100;
}

ただし fixed 要素は通常フローから外れるため、その分のスペースを body 側の padding-top などで確保しなければ、コンテンツが隠れてしまう点に注意が必要だ。

sticky

relative と fixed を組み合わせたような振る舞いをする。通常フロー内に存在しつつ、スクロールで指定位置に達すると固定される。サイドバーの目次やテーブルのヘッダー行に便利だ。

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

sticky が効かないときは、親要素の overflow が hidden や auto になっていないか確認するとよい。overflow の設定が sticky の動作を妨げる代表的な原因だ。

5 つの値の比較

static / relative

通常フローに従う。relative はオフセットで微調整でき、absolute の基準点にもなる。

absolute / fixed / sticky

通常フローから外れる(sticky は条件付き)。absolute は祖先基準、fixed はビューポート基準、sticky はスクロール位置に応じて切り替わる。

実務では relative と absolute の組み合わせが最も多く、fixed はナビゲーション、sticky はテーブルや目次といった用途で使い分けるのが定番のパターンになっている。