「要素を好きな場所に動かしたいけど、positionを使ったら逆に崩れてしまった…」
「staticやabsoluteってよく出てくるけど、何が違うの?」
そんな疑問を持っている人は多いのではないでしょうか?
CSSのposition
は、Webページのレイアウトを自在に操るための強力なプロパティです。
しかし、仕組みを理解しないと、思わぬところに配置されてしまうことも…。
この記事では、position
の基礎から、それぞれの種類の特徴と使い方まで、初心者にもわかりやすく解説します。
CSSのpositionとは?

position(配置)の基本概念
position
は、HTML要素の配置方法を決めるためのCSSプロパティです。
これを使うことで、以下のようなことが可能になります:
- 自由な配置:ページの左上や右下など、好きな場所に配置
- 相対的な配置:親要素の中で相対的に位置を調整
- 固定表示:スクロールしても常に同じ位置に表示
- 重なり順の制御:要素同士を重ね合わせてレイアウト
通常のHTMLの流れ(Normal Flow)
position
を理解するには、まず「通常の文書の流れ」を知ることが大切です。
通常の流れ
- HTML要素は上から下へ順番に配置される
- ブロック要素(div、p、h1など)は縦に並ぶ
- インライン要素(span、aなど)は横に並ぶ
<div>要素1(ブロック)</div>
<div>要素2(ブロック)</div>
<span>要素3(インライン)</span><span>要素4(インライン)</span>
position
を使うと、この自然な流れから「外して」自由に配置できるようになります。
positionの種類と詳しい使い方
CSSのposition
には主に以下の5種類があります。
static(デフォルト)
基本的な特徴
position
を何も指定しなかったときの標準状態- 通常の文書の流れ(HTMLの並び順)に従って配置される
top
、right
、bottom
、left
プロパティは無効
実際のコード例
.normal-box {
position: static; /* 書かなくても同じ */
background-color: lightblue;
padding: 20px;
}
いつ使う?
ほとんどの要素はこれが基本です。わざわざposition: static;
と書くことはほぼありません。
リセット目的で使用
.reset-position {
position: static; /* 他のpositionを上書きしたい場合 */
}
relative(相対配置)
基本的な特徴
- その場(元の位置)を基準にして動く
top
、right
、bottom
、left
で移動量を指定- 元の場所は空いたまま(他の要素は影響を受けない)
- 子要素の
absolute
配置の基準点になる
実際のコード例
基本的な移動
.relative-box {
position: relative;
top: 20px; /* 元の位置から下に20px */
left: 30px; /* 元の位置から右に30px */
background-color: lightgreen;
}
子要素の基準点として使用
.container {
position: relative; /* 子要素の基準点 */
width: 300px;
height: 200px;
border: 2px solid #333;
}
.child {
position: absolute;
top: 10px;
right: 10px;
/* containerを基準に右上に配置 */
}
よくある使用例
軽微な位置調整
.logo {
position: relative;
top: -2px; /* 少しだけ上にずらして調整 */
}
親要素としての役割
.card {
position: relative; /* absoluteな子要素のため */
}
.card-badge {
position: absolute;
top: -5px;
right: -5px;
}
absolute(絶対配置)
基本的な特徴
- 親要素を基準に絶対的な位置に配置
- 通常の文書の流れから完全に外れる
- 他の要素に影響を与えず、また他の要素からも影響を受けない
- 基準となる親要素は「
position: static
以外の最も近い祖先要素」
基準点の決まり方
/* パターン1:親にrelativeがある場合 */
.parent {
position: relative; /* この要素が基準になる */
}
.child {
position: absolute;
top: 0;
left: 0; /* parentの左上に配置 */
}
/* パターン2:親にrelativeがない場合 */
.child {
position: absolute;
top: 0;
left: 0; /* ブラウザ画面の左上に配置 */
}
実際のコード例
カードの中にバッジを配置
.card {
position: relative;
width: 300px;
height: 200px;
border: 1px solid #ddd;
}
.badge {
position: absolute;
top: 10px;
right: 10px;
background: red;
color: white;
padding: 5px 10px;
border-radius: 4px;
}
中央配置のテクニック
.modal {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* 中央に調整 */
width: 400px;
height: 300px;
background: white;
border: 1px solid #ccc;
}
フルスクリーンオーバーレイ
.overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0; /* 親要素全体を覆う */
background: rgba(0, 0, 0, 0.5);
}
absoluteの注意点
元の場所が消える
/* 他の要素は、absolute要素が最初から存在しなかったように配置される */
.disappearing-element {
position: absolute;
/* この要素の元の場所は詰められる */
}
fixed(固定配置)
基本的な特徴
- ブラウザ画面(ビューポート)を基準に配置
- スクロールしても常に同じ位置に表示される
- 通常の文書の流れから外れる(absoluteと同様)
- モバイルで特殊な動作をする場合がある
実際のコード例
固定ヘッダー
.fixed-header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 60px;
background: #333;
color: white;
z-index: 1000; /* 他の要素より上に表示 */
}
/* ヘッダー分だけbodyの上部にスペースを確保 */
body {
padding-top: 60px;
}
「トップへ戻る」ボタン
.scroll-to-top {
position: fixed;
bottom: 20px;
right: 20px;
width: 50px;
height: 50px;
background: #007BFF;
color: white;
border: none;
border-radius: 50%;
cursor: pointer;
z-index: 1000;
}
サイドナビゲーション
.sidebar {
position: fixed;
top: 0;
left: 0;
width: 250px;
height: 100vh; /* 画面の高さいっぱい */
background: #f8f9fa;
overflow-y: auto; /* 内容が多い場合はスクロール */
z-index: 999;
}
fixedの注意点
モバイルでの問題
/* iOS Safariでの修正 */
.fixed-element {
position: fixed;
/* iOS Safariでは100vhが正しく計算されない場合がある */
height: 100vh;
height: -webkit-fill-available;
}
スクロールバーの考慮
.fixed-full-width {
position: fixed;
left: 0;
right: 0; /* width: 100% よりも安全 */
}
sticky(スクロール連動)
基本的な特徴
relative
とfixed
のハイブリッド- 通常は
relative
として表示 - 指定した位置でスクロールすると
fixed
のように固定される - 親要素の範囲内でのみ有効
実際のコード例
スクロール固定メニュー
.sticky-nav {
position: sticky;
top: 0; /* 画面上端に達したら固定 */
background: white;
border-bottom: 1px solid #ddd;
z-index: 100;
}
テーブルヘッダーの固定
.table-header {
position: sticky;
top: 0;
background: #f8f9fa;
z-index: 10;
}
サイドバーの部分固定
.sidebar-content {
position: sticky;
top: 20px; /* 上から20pxの位置で固定 */
}
stickyの注意点
親要素のoverflowの影響
/* NG:stickyが効かない */
.parent {
overflow: hidden; /* これがあるとstickyが無効 */
}
.sticky-child {
position: sticky;
top: 0;
}
親要素の高さが必要
/* stickyが動作するには十分な親要素の高さが必要 */
.parent {
height: 200vh; /* 親が十分に高い必要がある */
}
位置指定プロパティの詳細

top, right, bottom, left
基本的な使い方
.positioned-element {
position: absolute;
top: 10px; /* 上から10px */
right: 20px; /* 右から20px */
bottom: 30px; /* 下から30px */
left: 40px; /* 左から40px */
}
便利な指定方法
要素を親要素いっぱいに広げる
.full-overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
/* 親要素全体に広がる */
}
中央配置の複数パターン
/* パターン1:transformを使用 */
.center-transform {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* パターン2:marginを使用(サイズ固定時) */
.center-margin {
position: absolute;
top: 50%;
left: 50%;
width: 200px;
height: 100px;
margin-top: -50px; /* height の半分 */
margin-left: -100px; /* width の半分 */
}
/* パターン3:CSS Grid風(現代的) */
.center-inset {
position: absolute;
inset: 0;
width: 200px;
height: 100px;
margin: auto;
}
z-index(重なり順)
基本的な概念
.layer-1 {
position: relative;
z-index: 1; /* より小さい値 */
}
.layer-2 {
position: absolute;
z-index: 10; /* より大きい値が上に表示される */
}
実際の使用例
レイヤー管理のベストプラクティス
/* レイヤー定数を定義 */
:root {
--z-dropdown: 1000;
--z-sticky: 1020;
--z-fixed: 1030;
--z-modal-backdrop: 1040;
--z-modal: 1050;
--z-popover: 1060;
--z-tooltip: 1070;
}
.modal {
position: fixed;
z-index: var(--z-modal);
}
.tooltip {
position: absolute;
z-index: var(--z-tooltip);
}
z-indexの注意点
スタッキングコンテキスト
/* 親要素にz-indexがあると、子要素は親の範囲内でしか重なり順が決まらない */
.parent {
position: relative;
z-index: 1;
}
.child {
position: absolute;
z-index: 9999; /* 親のz-indexが1なので、他の親(z-index: 2)には勝てない */
}
よくあるトラブルと解決方法
absoluteが思った場所に配置されない
問題の原因
基準となる親要素がない
/* NG:親にpositionが指定されていない */
.parent {
/* position指定なし = static */
}
.child {
position: absolute;
top: 10px;
left: 10px;
/* body要素を基準に配置されてしまう */
}
解決方法
/* OK:親に基準となるpositionを指定 */
.parent {
position: relative; /* これで基準点になる */
}
.child {
position: absolute;
top: 10px;
left: 10px;
/* parentを基準に配置される */
}
stickyが効かない
よくある原因と解決法
親要素のoverflowが原因
/* NG */
.container {
overflow: hidden; /* これが原因 */
}
.sticky-element {
position: sticky;
top: 0;
}
/* OK */
.container {
overflow: visible; /* または指定しない */
}
親要素の高さが不足
/* NG:親の高さが足りない */
.short-parent {
height: 100px; /* 短すぎる */
}
/* OK:十分な高さを確保 */
.tall-parent {
min-height: 200vh; /* または十分な高さ */
}
fixedでレイアウトが崩れる
問題の例
/* 問題:fixedヘッダーによってコンテンツが隠れる */
.header {
position: fixed;
top: 0;
height: 60px;
/* コンテンツがヘッダーの下に隠れてしまう */
}
解決方法
.header {
position: fixed;
top: 0;
height: 60px;
}
/* bodyまたはメインコンテンツに上部余白を追加 */
body {
padding-top: 60px; /* ヘッダーの高さ分 */
}
/* または */
.main-content {
margin-top: 60px;
}
モバイルでのfixed要素の問題
iOS Safariでの対応
.mobile-fixed {
position: fixed;
/* iOS Safariでのビューポート問題対応 */
height: 100vh;
height: -webkit-fill-available;
}
/* さらに安全な方法 */
.safe-fixed {
position: fixed;
top: env(safe-area-inset-top); /* ノッチ対応 */
bottom: env(safe-area-inset-bottom);
}
実践的なレイアウトパターン
モーダルウィンドウ
/* オーバーレイ */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
}
/* モーダル本体 */
.modal-content {
position: relative; /* 閉じるボタンの基準点 */
background: white;
border-radius: 8px;
padding: 20px;
max-width: 500px;
max-height: 80vh;
overflow-y: auto;
}
/* 閉じるボタン */
.modal-close {
position: absolute;
top: 10px;
right: 10px;
background: none;
border: none;
font-size: 24px;
cursor: pointer;
}
カードレイアウトのバッジ
.card {
position: relative;
width: 300px;
height: 200px;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
}
.card-image {
width: 100%;
height: 120px;
object-fit: cover;
}
.card-badge {
position: absolute;
top: 10px;
right: 10px;
background: #ff4757;
color: white;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
font-weight: bold;
}
.card-content {
padding: 15px;
}
スクロール連動ナビゲーション
.page-header {
height: 200px;
background: linear-gradient(45deg, #667eea, #764ba2);
}
.sticky-nav {
position: sticky;
top: 0;
background: white;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
z-index: 100;
transition: box-shadow 0.3s ease;
}
.sticky-nav.scrolled {
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}
.nav-list {
display: flex;
list-style: none;
margin: 0;
padding: 0;
}
.nav-item {
padding: 15px 20px;
}
パフォーマンスとアクセシビリティ

パフォーマンスの考慮
GPU加速の活用
/* GPU加速を有効にする */
.accelerated-element {
position: absolute;
transform: translateZ(0); /* またはwill-change: transform; */
}
/* アニメーションで使用する場合 */
.animated-element {
position: relative;
will-change: transform; /* アニメーション前に指定 */
transition: transform 0.3s ease;
}
.animated-element:hover {
transform: translateY(-5px);
}
レイアウトシフトの最小化
/* 悪い例:レイアウトが変わってしまう */
.bad-animation {
transition: top 0.3s ease; /* レイアウトを変更 */
}
/* 良い例:transformを使用 */
.good-animation {
transition: transform 0.3s ease; /* レイアウトに影響しない */
}
アクセシビリティ配慮
スクリーンリーダー対応
/* 視覚的に隠すが、スクリーンリーダーでは読み上げられる */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
フォーカス管理
/* モーダルなどでフォーカストラップが必要 */
.modal-overlay {
position: fixed;
/* ... */
}
/* フォーカス可能な要素のスタイル */
.modal-content button:focus,
.modal-content input:focus {
outline: 2px solid #007BFF;
outline-offset: 2px;
}
ブラウザ対応とフォールバック
古いブラウザ対応
/* sticky のフォールバック */
.navbar {
position: -webkit-sticky; /* Safari */
position: sticky;
top: 0;
}
/* IE11 対応(stickyが使えない場合) */
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
.navbar {
position: relative; /* IE11ではrelativeにフォールバック */
}
}
機能検知
/* CSS Feature Queries */
@supports (position: sticky) {
.modern-sticky {
position: sticky;
top: 0;
}
}
@supports not (position: sticky) {
.fallback-sticky {
position: relative;
/* JavaScriptでの制御が必要 */
}
}
まとめ
CSSのposition
は、Webレイアウトの自由度を大幅に高める重要なプロパティです。
基本的な使い分け
relative
- 元の場所からの微調整
- absolute要素の基準点として使用
- 通常の文書の流れを保ちたい場合
absolute
- 親要素内での自由な配置
- オーバーレイやバッジなどの装飾要素
- モーダルウィンドウのコンテンツ
fixed
- ヘッダーやフッターの固定表示
- 「トップへ戻る」ボタン
- サイドナビゲーション
sticky
- スクロール連動のナビゲーション
- テーブルヘッダーの固定
- セクション見出しの追従表示
コメント