CSSのpositionとは?relative・absolute・fixed・stickyの違いと使い方を初心者向けに解説

CSS positionの配置の基準と4つの使い分けを解説するアイキャッチ

カードの右上にラベルを重ねたいときや、スクロールしてもボタンを画面の端に表示したいときに使うのが、CSSのpositionプロパティです。しかし、「absoluteは何を基準に動くの?」「fixedとstickyは何が違う?」と迷う方も多いのではないでしょうか。

positionを理解するポイントは、どこを基準に配置するかと、元の場所をレイアウトに残すかの2つです。この2点で整理すると、relative・absolute・fixed・stickyの違いを判断しやすくなります。

HTMLの要素やCSSのセレクターを学び、配置の調整で迷っている方へ、5つの値の違いと小さな練習例を紹介します。まずは親カードの右上へラベルを置き、fixedとstickyの違いをスクロールで確かめましょう。うまく動かない場合も、指定値と配置の基準を順に調べられるように解説します。

この記事で分かること
  • positionが決める配置の基準と通常フローとの関係
  • static・relative・absolute・fixed・stickyの違い
  • 親要素を基準に子要素を配置する基本コード
  • fixedとstickyの選び方
  • positionが効かない・ずれるときの確認順
目次

CSSのpositionとは

positionは、要素をどの基準で配置するかを決めるCSSプロパティです。初期値はstaticで、HTMLに書かれた順序に沿う「通常フロー」の中へ要素が配置されます。

relative・absolute・fixed・stickyへ変更すると、元の位置を基準にずらす、親要素へ重ねる、画面へ固定する、スクロール途中から追従させるといった配置ができます。各値の正式な定義と例は、MDNの「position」でも確認できます。

通常フローと元の場所

通常フローとは、positionで特別な配置をしないときに、ブラウザーがHTMLに書かれた順番に沿って要素を並べる仕組みです。ブロック要素が上から下へ並ぶ状態は、その代表例です。

relativeとstickyは通常フロー内の場所を残し、absoluteとfixedは通常フローから外れます。そのため、absoluteとfixedの要素のための空間は作られません。この違いを知らないと、後ろの要素が詰まったり、内容が重なったりします。

relativeではBの元の場所が残り、absoluteではCが上へ詰まる通常フローの違い

図ではA・B・Cを順に並べ、Bだけを動かしています。左の点線はBの元の場所です。relativeではその空間が残り、absoluteでは空間が確保されないためCが上へ詰まります。

positionの基本的な書き方

positionはCSSの宣言として、対象のセレクターへ書きます。次のコードは.badgeへrelativeを指定する最小例です。以下の例は、公開中のページではなく手元の練習用ファイルで試します。別の例へ進むときは、前の例のHTMLとCSSを置き換えてください。

.badge {
  position: relative;
}

positionの値を指定しただけでは、見た目の位置が変わらないことがあります。実際に動かすときは、top・right・bottom・leftなどを組み合わせます。CSSのセレクターや波括弧の書き方がまだ曖昧な方は、「CSSの基本的な書き方」を先に確認してください。

練習用ファイルがまだない場合は、次の順で準備します。すでにCSSを読み込める練習用ページがある方は、そのページを複製して使えます。

STEP
ファイルを用意する

新しいフォルダーにindex.htmlとstyle.cssを作ります。index.htmlには、この手順の下にあるHTMLを保存してください。

STEP
HTMLとCSSを入れる

試したい例のHTMLを<body>内のコメントの位置へ、CSSをstyle.cssへ貼り付けます。HTMLとCSSを両方保存します。

STEP
保存して表示を確認する

index.htmlをブラウザーで開きます。コードを変えたら両方のファイルを保存し、同じページを再読み込みして、各例の説明どおりに配置が変わるか確かめます。

<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>positionの練習</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- ここへ各例のHTMLを書く -->
</body>
</html>

positionの5つの値を比較

5つの値を、配置の基準と通常フローへの影響で整理します。

値配置の基準通常フロー・主な用途
static通常フロー残す|通常の配置
relative自分の元の位置残す|微調整・absoluteの基準
absolute基本は基準を指定した外側の要素外れる|親内へ重ねる
fixed原則、画面の表示領域外れる|画面へ固定
stickyスクロール領域の端(動ける範囲に制限)残す|途中から追従

表は基本形の比較です。absoluteでいう外側の要素や、stickyの基準と範囲は、後の各節でコードと合わせて確認します。

HOAI Point

基準と通常フローの2点を先に決めると、値を選びやすくなります。「どこを基準にしたいか」「元の場所を残したいか」を確認してからコードを書きましょう。

position: relativeの使い方

position: relativeは、要素の元の位置を基準にして配置を調整します。要素を動かしても、通常フロー内の元の場所は残ります。

元の位置からの移動

次のHTMLとCSSを組み合わせると、.noticeは元の位置から下へ8px、右へ12px動きます。

<p class="notice">お知らせ</p>
.notice {
  position: relative;
  top: 8px;
  left: 12px;
}

top: 8pxは「上へ8px動かす」指定ではありません。元の上端から8px離すため、結果として要素は下へ動きます。left: 12pxは、左辺を元の位置から右へ12px動かします。

動きを比べるときは、まずtopとleftの行だけを外して保存し、再読み込みします。次に2行を戻し、「お知らせ」が下・右へずれれば確認できています。比較後は元のコードへ戻してください。

relativeは要素を動かしても元の場所を残すため、周囲の要素は移動前の場所を基準に並びます。大きく動かすと空白や重なりが生じるため、細かな位置調整に向く書き方です。

absoluteの配置基準を作る

relativeは、要素自身を動かさず、子要素のabsolute配置に使う基準だけを作る目的でもよく使います。この場合はtopやleftを書かなくても問題ありません。

.card {
  position: relative;
}

.cardの子要素へposition: absoluteを指定すると、.cardを基準に配置できます。親へrelative、子へabsoluteという組み合わせは、カード内のラベルや画像上のボタンで使いやすい基本形です。

position: absoluteの使い方

position: absoluteは、要素を通常フローから外します。absoluteは基本的に、親要素から外側へ順番に確認し、最初に見つかったposition: static以外の要素を基準にします。祖先要素とは、親要素や、そのさらに外側にある要素です。

親要素を基準に子要素を配置する

カードの右上へ「NEW」ラベルを重ねる例です。上側のpaddingを64pxにして、ラベルと見出しが重ならない空間を作ります。親は.card、その中のラベルが子の.card__badgeです。保存後、ラベルがカードの上端・右端からそれぞれ12px内側にあり、見出しと重ならなければ、この例の配置は完了です。

<article class="card">
  <span class="card__badge">NEW</span>
  <h3>CSS入門</h3>
  <p>基本のプロパティを学びます。</p>
</article>
.card {
  position: relative;
  padding: 64px 24px 24px;
  background-color: #f5f5f5;
}

.card__badge {
  position: absolute;
  top: 12px;
  right: 12px;
}

親にrelative、子にabsoluteを指定すると、この例ではラベルがカードの上端から12px、右端から12pxの位置へ配置されます。親のrelativeを外すと、さらに外側の配置基準を持つ祖先が使われます。該当する祖先がなければ、初期包含ブロックという基準領域が使われるため、カードの外へ飛び出すことがあります。

relativeを指定した親カードの上端と右端から12pxの位置へabsoluteのNEWラベルを配置する図

図の矢印は、上端・右端からラベルまでの距離です。位置やサイズを計算する基準範囲を「包含ブロック」と呼びます。この例では枠線のない親カードが基準です。親に枠線がある場合、absoluteの基準は基本的に枠線の内側の領域になります。transformなど、position以外の指定で基準ができる例外もあります。詳しくはMDNの「レイアウトと包含ブロック」で確認できます。

通常フローから外れる点に注意する

absoluteを指定した要素のための空間は、通常フロー内に確保されません。absoluteの子要素だけで親の高さを広げようとしても、期待どおりにならないことがあります。

HOAI Point

主役の内容までabsoluteにしないことが、崩れを防ぐ基本です。見出しや本文は通常フローに残し、ラベルやアイコンなど、重ねる必要がある要素だけへabsoluteを使いましょう。

position: fixedの使い方

position: fixedは要素を通常フローから外し、原則としてブラウザーの表示領域であるビューポートを基準に固定します。ページをスクロールしても、指定した位置に表示され続けます。

画面の右下へボタンを固定する

次のHTMLとCSSでは、「ページ上部へ」のリンクを画面の右端と下端から24pxの位置へ固定します。本文を十分に長くしてスクロールすると、固定を確認できます。リンク先のid="page-start"もHTMLへ置いてください。

<h1 id="page-start">配置の練習</h1>
<p>ここにスクロールできる量の本文を入れます。</p>
<a class="page-top" href="#page-start">ページ上部へ</a>
.page-top {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 10;
  padding: 12px;
  background-color: #fff;
}

fixedはスクロール前から画面の同じ位置に固定されます。「ページ上部へ戻る」ボタンや、常に表示したい補助操作に向いています。

固定要素と本文の重なり

fixedの要素は通常フローから外れるため、本文の上へ重なることがあります。特にスマートフォンでは表示領域が狭いため、ボタンや固定バーが文章、リンク、フォームを隠していないか確認してください。

固定ヘッダーを使う場合は、ヘッダーの高さに相当する余白を本文側へ確保する方法があります。ブラウザーのズームや文字サイズを大きくした状態でも、操作対象が隠れないことを確認しましょう。

少し高度な例ですが、祖先要素にtransformなどが指定されていると、fixedの基準が画面ではなく祖先要素へ変わることがあります。画面へ固定したはずなのに一緒に動く場合は、祖先のCSSも確認してください。

position: stickyの使い方

position: stickyは通常フロー内の場所を保ち、スクロールで指定位置に達すると追従します。ただし、動ける範囲は包含ブロックに制限されます。次のような一般的なブロック配置では、見出しを囲む親のsectionがその範囲になります。

topとセットで追従させる

次のHTMLとCSSを組み合わせてページをスクロールします。「第1章」の見出しが画面上端に達すると追従し、見出しの下端がその章の下端に押される位置まで進むと、章と一緒に上へ流れます。続いて「第2章」でも同じ動きを確認できます。

<section>
  <h2 class="section-title">第1章</h2>
  <div class="demo-content">第1章の本文</div>
</section>
<section>
  <h2 class="section-title">第2章</h2>
  <div class="demo-content">第2章の本文</div>
</section>
.section-title {
  position: sticky;
  top: 0;
  z-index: 5;
  margin: 0;
  padding: 16px;
  background-color: #fff;
}

.demo-content {
  min-height: 120vh;
  background-color: #f5f5f5;
}

min-height: 120vhは、スクロールを試すために画面の高さの1.2倍以上の領域を作る指定です。実際の記事やページでは内容に合う高さにし、この練習用の指定をそのまま使う必要はありません。

stickyはtopなどのしきい値とセットで使います。縦方向のtopとbottomがどちらもautoのままなら、縦方向ではrelativeのように動作し、追従しません。

画面に最初から固定するfixedと、指定位置で追従し包含ブロック内で動くstickyの比較

図はページ全体をスクロールする基本例です。fixedは原則として画面を基準に固定されます。stickyは指定位置で追従を始めますが、包含ブロックの外へ出ないように位置が制限されます。

スクロールの基準と、動ける範囲を分けて確認する

overflowは、要素からはみ出した内容を隠すか、スクロールできるようにするかを決めるプロパティです。

stickyの追従位置は、overflow: hidden・auto・scrollなどでスクロールの仕組みを持つ直近の祖先の表示領域が基準です。その祖先が実際にはスクロールしていなくても基準になることがあるため、ページを動かしても期待どおりに追従しない場合があります。

一方、追従中に動ける範囲を制限するのは包含ブロックです。スクロールの基準と同じ要素とは限りません。上の例では各sectionの範囲内で動きます。見出しと親の高さがほぼ同じなら動く余地がないため、top、祖先のoverflow、親の高さを分けて確認してください。overflowを変更すると他の表示にも影響するので、原因を確かめてから調整します。

top・right・bottom・leftとz-index

positionで配置方法を選んだ後、top・right・bottom・leftで基準の端からの距離を指定します。z-indexは、要素が重なったときの前後関係を調整するプロパティです。

top・right・bottom・leftで位置を決める

absolute・fixedでは、基準となる領域の端からの距離として働きます。relativeでは、元の位置からどれだけずらすかを指定します。0以外の数値には、pxやremなどの単位が必要です。

.box {
  position: absolute;
  top: 16px;
  right: 16px;
}

position: staticのままでは、top・right・bottom・leftを指定しても位置は変わりません。まず目的に合うpositionの値を選び、その後に必要な方向だけを指定します。

z-indexは重なり順を調整する

.card__badge {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 1;
}

これは先ほどのカードのラベルへz-index: 1を加える例です。同じ重ね合わせのグループ内で、前後関係を調整します。1を指定すればページ内のすべての要素より前に出る、という意味ではありません。

重ね合わせコンテキストとは、要素の前後関係を決めるグループのようなものです。親のグループが異なると、子要素のz-indexだけを大きくしても前へ出ないことがあります。効かないときは対象要素だけでなく、祖先のposition・z-index・opacity・transformなども確認します。仕組みはMDNの「重ね合わせコンテキスト」で詳しく確認できます。

positionの使い分け

値を暗記するより、「何を基準に、どの範囲で表示したいか」から選ぶと迷いにくくなります。

  • 元の場所を残して少し動かす:relative
  • カードや画像の中へ重ねる:親にrelative、子にabsolute
  • 画面の同じ位置へ常に表示する:fixed
  • スクロール途中から決まった範囲内で追従する:sticky
  • 通常の配置へ戻す:static

まず、要素を重ねたり固定したりする必要があるかを確認します。通常の横並び・縦並び・中央揃えなら、positionではなくFlexboxやCSS Gridのほうが、画面幅や文章量の変化へ対応しやすくなります。

HOAI Point

並べるならFlexbox・Grid、重ねるならpositionを基本にすると、座標の微調整を減らせます。positionはページ全体のレイアウトを作る道具ではなく、基準を決めて重ねる・固定する場面へ絞って使いましょう。

positionが効かない・ずれるときの確認順

配置が変わらないときは、次の順で「CSSが届いているか」「指定が有効か」を確かめます。ここで解決したら、症状別の確認へ進む必要はありません。

STEP
対象の要素を選ぶ

対象の要素を選びます。PC版Chromeなら、練習ページのラベルなどを右クリックして「検証」を選び、「要素(Elements)」で対象のclass名を確認します。親カードと子ラベルを取り違えないようにしましょう。

STEP
CSSが届いているか調べる

「スタイル(Styles)」で、そのclassに書いたルールを探します。見つからなければHTMLのclass名とCSSのセレクター、href="style.css"と実際のファイル名・保存場所を照合し、保存して再読み込みします。

STEP
実際の適用値を確かめる

「計算済み(Computed)」でpositionやtop・rightの実際の値を確認します。必要に応じて「すべて表示(Show all)」を使います。意図した値と違えば「スタイル」に戻り、取り消し線のある宣言と優先されているルールを調べ、元のCSSファイルを修正します。

指定値が適用されているかを確かめてから、配置の基準を調べると原因を絞れます。一度に複数の値を変えず、修正するたびにブラウザーを再読み込みして確認してください。

開発者ツールで一時的に値を変えただけでは、元のファイルは保存されません。元のCSSを保存して再読み込みしても期待する配置が保たれれば、修正は完了です。操作名は言語やブラウザーで異なります。Chromeの画面の見方は、公式のCSS機能リファレンスでも確認できます。

absoluteがカードの外へ飛び出す場合

まず子ラベルのpositionがabsoluteであることを確認し、開発者ツールのHTMLで一段外側の.cardを選んで、position: relativeが適用されているか調べます。なければ、さらに外側の祖先が基準になり得ます。上の例と同じ親子関係へ直し、ラベルがカードの上端・右端から12px内側へ戻れば完了です。

stickyが追従しない場合

top: 0などの指定を確認し、次に「どの祖先がスクロールの基準か」と「包含ブロック内に動く余地があるか」を確認します。上の2章構成の例で動き、既存ページで動かない場合は、開発者ツールで親から外側へたどり、overflowと高さを確認します。overflow: hiddenなどがある祖先を見つけても、本番の指定をまとめて削除せず、練習用の複製で一つずつ比較してください。見出しが指定位置から追従し、親の範囲を出ずに流れれば完了です。

z-indexを増やしても前へ出ない場合

対象と重なっている相手の両方について、開発者ツールで祖先をたどります。positionとz-indexの組み合わせやtransformなど、重ね合わせコンテキストを作る指定を比較してください。別のまとまりにいる場合は子の数値だけを増やしても解決しません。前後関係を決めている祖先側を練習用の複製で調整し、必要な要素が前へ出て、ほかの本文や操作を隠さなければ完了です。

よくある質問

余白を空けたいときもrelativeを使いますか?

要素同士の間隔を空けたいなら、まずmarginやgapを検討します。relativeは元の場所を残したまま見た目だけを動かすため、周囲の要素との間隔を作り直す用途には向きません。

すべての要素にrelativeを付けてもよいですか?

必要な要素だけに指定しましょう。広い範囲へ付けると、absoluteの子要素が意図しない祖先を基準にすることがあります。カードなど、基準にしたい要素へ明示的に付けると関係を追いやすくなります。

まとめ

positionは、要素を配置する基準と、通常フローとの関係を決めるプロパティです。

  • static:通常フローに沿う初期値
  • relative:元の場所を残し、元の位置を基準にする
  • absolute:通常フローから外れ、直近の位置指定された祖先を基準にする
  • fixed:通常フローから外れ、原則としてビューポートへ固定する
  • sticky:通常フロー内の場所を保ち、指定位置から包含ブロックの範囲内で追従する
  • 効かないときは、CSSの読み込み・適用値を確認してから、配置の基準や重なり順を調べる

まずはカードの親へposition: relative、ラベルへposition: absolute; top: 12px; right: 12px;を書き、親の内側を基準に配置されることを確認してみてください。ラベルが見出しに重ならず、保存・再読み込み後も位置を保てれば、カードの練習は完了です。次にfixedとstickyの小さな例を別々に試し、画面へ固定される場合と、親の範囲で追従する場合を比べましょう。

目的別に次の記事を選ぶ

positionの基本を確認したら、次は作りたいレイアウトに合う方法を選びましょう。

横一列または縦一列を基準に要素を並べたいなら、次のFlexboxの記事で親要素と子要素の役割を確認してください。

行と列を同時に整えるカード一覧を作りたいなら、次のCSS Gridの記事で列幅と間隔の指定を確認してください。

この記事を書いた人

横畑デザイン事務所代表。Webデザイナー・プログラミング講師として、WordPressを中心としたWebサイトの制作・運用と個別指導に携わっています。実際の制作や指導で培った知識と経験をもとに、Web制作やAI活用について、初心者が迷わず一歩を踏み出せる情報を分かりやすく発信しています。

目次