【完全保存版】CSS positionの使い方まとめ|relative・absolute・fixed・stickyで“消える・崩れる”を卒業する実務ガイド

【完全保存版】CSS positionの使い方まとめ|relative・absolute・fixed・stickyで“消える・崩れる”を卒業する実務ガイド

2025.12.21

目次

はじめに|positionで詰まるのは普通。むしろみんな一回やらかす

CSSを触り始めると、だいたいこの3つで止まります。

  • position を入れた瞬間、レイアウトが崩れた
  • absolute を使ったら要素がどこかへ消えた
  • relativeabsolute の違いが、言葉では分かるのに手が動かない

私も昔、装飾アイコンを右上に置きたくて position: absolute; top: 0; right: 0; を書いたら、ページの右上(画面の角)に飛んでいって「え、親の中に置きたいんだけど…」ってなりました。
あれ、原因が分かると笑えるんですが、その場は普通に焦ります。

この記事は「css position」で検索してきた人が、“消える・隠れる・効かない”を自力で直せるようになるための実務ガイドです。DevToolsでの確認手順も具体的に書きます。


CSS positionとは何か(スニペット用の一文)

CSSのpositionは、要素を「どの基準(通常の流れ/親要素/画面/スクロール位置)」で配置するかを決めるプロパティです。

positionを理解すると、こういうUIが作れます。

  • 親要素の中で、角にピタッと置く(バッジ、アイコン、装飾)
  • 画面に固定する(固定ヘッダー、追従ボタン)
  • スクロールに合わせて途中から固定する(目次、サイドメニュー)
  • 要素を重ねる(モーダル、ドロワー、吹き出し)

positionの種類一覧(まずは全体像)

ざっくり役割 基準
static 初期値。普通に並ぶ 通常の流れ
relative 自分の元いた位置からズラす 自分自身(元の位置)
absolute 流れから外して、基準に対して配置 直近の“position付き祖先”
fixed 画面(viewport)に固定 画面
sticky 途中まで通常、ある位置から固定 スクロール+親要素

この表が頭にあるだけで、半分勝ちです。


position: static(初期状態)|top/leftが効かないのはこれ

.box {
  position: static;
  top: 10px; /* 効かない */
}

staticの特徴

  • 全要素の初期値
  • top/right/bottom/left が効かない
  • HTMLの流れ通りに配置される

「topを入れたのに動かない」時、まず position: static; のままじゃないか確認します。


position: relative(相対配置)|“元の場所”を残したままズラす

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

relativeの特徴

  • 元の位置を基準に動く
  • 動いても「元いたスペース」は残る(ここが大事)
  • absolute の“基準作り”として超よく使う

使いどころ(実務)

  • 装飾アイコンを重ねたい時の親側(基準作り)
  • 1〜2pxだけ微調整(ただしやりすぎ注意)

position: relativeで「なぜスペースが残る?」を噛み砕く

relativeは「見た目だけズラす」動きです。
元の位置に“透明のまま残っている”イメージが近いです。

だから、relativeで動かしても周りの要素は詰まりません。
逆に言うと、レイアウト調整目的で乱用すると「なんかズレてるのに余白もある」みたいな事故が起きます。


position: absolute(絶対配置)|“基準がないと迷子”になる

.badge {
  position: absolute;
  top: 0;
  right: 0;
}

absoluteの特徴

  • 通常のレイアウトの流れから外れる(=周りに影響されにくい)
  • 基準は「直近の position が指定された祖先」
  • 基準が見つからないと、ページ全体(だいたい画面左上)を基準にする

ここで一番多いのが、「親の中に置きたいのに、画面の角に飛んでいく」現象です。


absoluteの鉄板ルール|親にrelativeを付ける(ほぼこれで解決)

.card {
  position: relative;
}

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

これが一番多いパターンです。
「absoluteで消えた」の正体は、だいたい 基準が親じゃなかった だけです。


absoluteで“要素が消えたように見える”原因あるある

原因1:基準が想定外で、画面外へ飛んだ

top: -9999px みたいな話ではなく、基準がbodyになってて右上へ、みたいなやつです。
「どこいった?」となったら、まずこれを疑います。

原因2:親要素の外にはみ出して、隠された

親に overflow: hidden; があると、はみ出した分が切れます。

.parent {
  overflow: hidden; /* はみ出したabsoluteが見えない */
}

画像の角丸を作るために overflow: hidden; を付けた結果、バッジが切れる…は実務でよくあります。

原因3:z-indexで下に潜った

重なり順で負けると、存在してるのに見えません。


position: fixed(画面固定)|ヘッダー固定で下が隠れる問題までセットで覚える

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

fixedの特徴

  • 画面(viewport)基準
  • スクロールしても同じ位置
  • よく使う:固定ヘッダー、追従ボタン、チャットボタン、ページトップ

fixedで「下が隠れる」を防ぐ定番

固定ヘッダーを付けると、本文が下に潜ります。

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

body {
  padding-top: 60px;
}

これを忘れると「スマホで上が見切れてる」「クリックできない」みたいなトラブルにつながります。
特に、ページ内リンク(アンカーリンク)で飛んだ時にタイトルが隠れるのが地味に痛いです。


アンカーリンクが固定ヘッダーに隠れる時の対策(実務で刺さるやつ)

固定ヘッダーがあるサイトで「#見出しに飛んだのに上が隠れる」問題、かなり多いです。

解決策:scroll-margin-top

h2, h3 {
  scroll-margin-top: 80px;
}

これでアンカー移動時に、見出しがヘッダー下にちゃんと出ます。
JSいらずで効くので、覚えると楽です。


position: sticky(途中から固定)|効かない原因が分かると強い

.toc {
  position: sticky;
  top: 16px;
}

stickyの特徴

  • 普段は通常の流れ(relativeっぽい)
  • 指定位置に来たら固定(fixedっぽい)
  • 便利:目次、カテゴリメニュー、サイドバー

stickyが効かない時に見るポイント(ここで詰まりがち)

ポイント1:topが必要

position: sticky; だけでは動きません。

.toc {
  position: sticky;
  top: 0;
}

ポイント2:親の中だけで効く(親から出ない)

stickyは「親要素の範囲内」で固定されます。
親が短いと、すぐ終わります。

ポイント3:祖先にoverflowがあると死ぬことがある

特にこれ。

.wrapper {
  overflow: hidden; /* stickyが効かなくなる原因になりがち */
}

スクロールの基準が変わって、stickyが期待通り動かないことがあります。


top/right/bottom/leftの基本|positionがないと効かない

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

よくある勘違い

  • top だけ書いても動かない(positionが必要)
  • margin と混同する(役割が違う)
  • % の基準が分からなくなる(要素や親のサイズ基準になる)

「marginでよくない?」問題を整理する(混乱しやすいところ)

  • margin は「周りとの距離」を変える
  • top/left は「自分の位置」をズラす(positionが必要)

たとえば、隣の要素との間隔を空けたいならmargin。
角にピタッと置きたいならposition。

この切り分けができると、レイアウトが安定します。


positionとz-indexの関係|“数字が大きいほど前”だけだと事故る

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

z-indexの基本

  • positionが絡む要素で効きやすい(staticだと効かないケースが多い)
  • 数字が大きいほど前

実務での落とし穴:スタッキングコンテキスト

「z-indexを9999にしたのに出てこない」
このパターン、ほぼスタッキングコンテキストです。

スタッキングコンテキストは、ざっくり言うと「重なり順の別世界」ができる仕組みです。
別世界に入ると、外のz-indexと勝負できません。

よくある“別世界を作る原因”はこれです。

.parent {
  transform: translateZ(0);
}

他にも opacityfilterpositionz-index の組み合わせなどで発生します。
モーダルやドロワーが裏に回る時は、まず親側に transform がないか疑います。


DevToolsで“消えた要素”を探す手順(差別化ポイント)

要素が消えた時、勘で直すと沼ります。DevToolsが一番早いです。

手順(Chrome)

  1. 右クリック → 検証
  2. Elementsで該当要素を探す(検索: Ctrl+Fでクラス名)
  3. 右側 Stylesposition / top / left / z-index を確認
  4. Computed で最終的な座標やサイズを見る
  5. 画面上に表示されてないなら、topleft が変な値になってないか確認
  6. クリックできないなら、上に被ってる要素がないか(hoverで重なりを見る)

その場で直すコツ(実務)

DevTools上で top: 0; right: 0; を一旦外してみる。
それで画面内に戻ってきたら「座標指定が原因」だと即分かります。


positionはいつ使うべき?(レイアウトで多用すると崩れる)

positionは強いですが、レイアウトの主役にすると崩れやすいです。

役割分担のおすすめ

  • レイアウト(横並び・均等配置・段組み) → Flexbox / Grid
  • 位置調整(角に置く・重ねる・固定する) → position

この分け方にすると、スマホ崩れ・横スクロール問題が目に見えて減ります。
「positionで全部作る」癖が付くと、後から自分が苦しみます。


スマホ崩れ・横スクロール問題とpositionの関係

positionが原因の横スクロール、だいたいこれです。

  • right: -20px; みたいに画面外へ押し出している
  • fixed要素に width: 100vw; を使っていて、スクロールバー分で溢れている
  • absolute要素が親幅を超えている(画像や長文)

よくある例:100vwで横スクロール

.header {
  position: fixed;
  width: 100vw; /* 横スクロールの原因になりがち */
}

対策はこれ。

.header {
  width: 100%;
}

「なんかスマホだけ横にスーッと動く」時、真っ先に疑ってOKです。


よくある失敗例を“リアルに”再現して直す

失敗1:absoluteでアイコンを置いたら画面右上へ飛んだ

原因:親が基準になってない

/* 修正 */
.card {
  position: relative;
}

.card__icon {
  position: absolute;
  top: 0;
  right: 0;
}

失敗2:fixedヘッダーでリンクの上が隠れて押しにくい

原因:本文がヘッダーの下に潜ってる
対策:paddingを入れる

body {
  padding-top: 60px;
}

失敗3:stickyが効かない(ずっと普通に流れる)

原因:topがない/overflowが邪魔してることが多い

.toc {
  position: sticky;
  top: 16px;
}

最小で使える“定番セット”(コピペOK)

親の角にバッジを置く(relative + absolute)

.card {
  position: relative;
}

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

追従ボタン(fixed)

.fab {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 1000;
}

目次を途中から固定(sticky)

.toc {
  position: sticky;
  top: 16px;
}

チェックリスト|positionで崩れたらここから見る

  • top/left が効かない → positionがstaticのままじゃない?
  • absoluteが迷子 → 親(または祖先)に position: relative; は付いてる?
  • 見えない → overflow: hidden; に切られてない?
  • クリックできない → 何かが上に被ってない?(z-index)
  • stickyが効かない → top はある? overflowが祖先にない?
  • スマホ崩れ → positionでレイアウトを組みすぎてない?(Flex/Gridでいけない?)
  • 横スクロール → 100vwright:- を使ってない?

よくある質問

relativeとabsoluteは必ずセット?

absoluteを“親の中で”使うなら、ほとんどのケースでセットです。
逆にセットじゃない時は「画面全体基準にしたい」など、意図がある時です。


stickyが効かないのはなぜ?

だいたいこのどれかです。

  • top を書いてない
  • 親が短い(固定される距離がない)
  • 祖先に overflow がある

z-indexを上げても前に出ないのはなぜ?

「別の重なり世界(スタッキングコンテキスト)」に入っていることが多いです。
親に transformopacity が付いていないかを先に見てみてください。


まとめ|positionは“配置・装飾の武器”。レイアウトの主役にしない

positionが分かると、できることが一気に増えます。

  • relative:基準作り&微調整
  • absolute:親の中で自由配置(基準がないと迷子)
  • fixed:画面固定(下が隠れる対策もセット)
  • sticky:スクロール追従(topとoverflowがカギ)

「css position」で検索した方は、まず relativeとabsoluteの関係(基準作り) を体に入れてください。
そこが分かると、positionは怖くなくなります。

タグ:

#CSS #HTML #css position #position relative #position absolute #fixed #sticky #z-index #DevTools #スマホ崩れ #横スクロール