目次
- はじめに|positionで詰まるのは普通。むしろみんな一回やらかす
- CSS positionとは何か(スニペット用の一文)
- positionの種類一覧(まずは全体像)
- position: static(初期状態)|top/leftが効かないのはこれ
- staticの特徴
- position: relative(相対配置)|“元の場所”を残したままズラす
- relativeの特徴
- 使いどころ(実務)
- position: relativeで「なぜスペースが残る?」を噛み砕く
- position: absolute(絶対配置)|“基準がないと迷子”になる
- absoluteの特徴
- absoluteの鉄板ルール|親にrelativeを付ける(ほぼこれで解決)
- absoluteで“要素が消えたように見える”原因あるある
- 原因1:基準が想定外で、画面外へ飛んだ
- 原因2:親要素の外にはみ出して、隠された
- 原因3:z-indexで下に潜った
- position: fixed(画面固定)|ヘッダー固定で下が隠れる問題までセットで覚える
- fixedの特徴
- fixedで「下が隠れる」を防ぐ定番
- アンカーリンクが固定ヘッダーに隠れる時の対策(実務で刺さるやつ)
- 解決策:scroll-margin-top
- position: sticky(途中から固定)|効かない原因が分かると強い
- stickyの特徴
- stickyが効かない時に見るポイント(ここで詰まりがち)
- ポイント1:topが必要
- ポイント2:親の中だけで効く(親から出ない)
- ポイント3:祖先にoverflowがあると死ぬことがある
- top/right/bottom/leftの基本|positionがないと効かない
- よくある勘違い
- 「marginでよくない?」問題を整理する(混乱しやすいところ)
- positionとz-indexの関係|“数字が大きいほど前”だけだと事故る
- z-indexの基本
- 実務での落とし穴:スタッキングコンテキスト
- DevToolsで“消えた要素”を探す手順(差別化ポイント)
- 手順(Chrome)
- その場で直すコツ(実務)
- positionはいつ使うべき?(レイアウトで多用すると崩れる)
- 役割分担のおすすめ
- スマホ崩れ・横スクロール問題とpositionの関係
- よくある例:100vwで横スクロール
- よくある失敗例を“リアルに”再現して直す
- 失敗1:absoluteでアイコンを置いたら画面右上へ飛んだ
- 失敗2:fixedヘッダーでリンクの上が隠れて押しにくい
- 失敗3:stickyが効かない(ずっと普通に流れる)
- 最小で使える“定番セット”(コピペOK)
- 親の角にバッジを置く(relative + absolute)
- 追従ボタン(fixed)
- 目次を途中から固定(sticky)
- チェックリスト|positionで崩れたらここから見る
- よくある質問
- relativeとabsoluteは必ずセット?
- stickyが効かないのはなぜ?
- z-indexを上げても前に出ないのはなぜ?
- まとめ|positionは“配置・装飾の武器”。レイアウトの主役にしない
はじめに|positionで詰まるのは普通。むしろみんな一回やらかす
CSSを触り始めると、だいたいこの3つで止まります。
positionを入れた瞬間、レイアウトが崩れたabsoluteを使ったら要素がどこかへ消えたrelativeとabsoluteの違いが、言葉では分かるのに手が動かない
私も昔、装飾アイコンを右上に置きたくて 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);
}
他にも opacity や filter、position と z-index の組み合わせなどで発生します。
モーダルやドロワーが裏に回る時は、まず親側に transform がないか疑います。
DevToolsで“消えた要素”を探す手順(差別化ポイント)
要素が消えた時、勘で直すと沼ります。DevToolsが一番早いです。
手順(Chrome)
- 右クリック → 検証
- Elementsで該当要素を探す(検索: Ctrl+Fでクラス名)
- 右側 Styles で
position/top/left/z-indexを確認 - Computed で最終的な座標やサイズを見る
- 画面上に表示されてないなら、
topやleftが変な値になってないか確認 - クリックできないなら、上に被ってる要素がないか(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でいけない?)
- 横スクロール →
100vwやright:-を使ってない?
よくある質問
relativeとabsoluteは必ずセット?
absoluteを“親の中で”使うなら、ほとんどのケースでセットです。
逆にセットじゃない時は「画面全体基準にしたい」など、意図がある時です。
stickyが効かないのはなぜ?
だいたいこのどれかです。
topを書いてない- 親が短い(固定される距離がない)
- 祖先に
overflowがある
z-indexを上げても前に出ないのはなぜ?
「別の重なり世界(スタッキングコンテキスト)」に入っていることが多いです。
親に transform や opacity が付いていないかを先に見てみてください。
まとめ|positionは“配置・装飾の武器”。レイアウトの主役にしない
positionが分かると、できることが一気に増えます。
- relative:基準作り&微調整
- absolute:親の中で自由配置(基準がないと迷子)
- fixed:画面固定(下が隠れる対策もセット)
- sticky:スクロール追従(topとoverflowがカギ)
「css position」で検索した方は、まず relativeとabsoluteの関係(基準作り) を体に入れてください。
そこが分かると、positionは怖くなくなります。