CSSのposition徹底ガイド|初心者でもわかる使い方と違い

CSS

「要素を好きな場所に動かしたいけど、positionを使ったら逆に崩れてしまった…」

「staticやabsoluteってよく出てくるけど、何が違うの?」

そんな疑問を持っている人は多いのではないでしょうか?

CSSのpositionは、Webページのレイアウトを自在に操るための強力なプロパティです。

しかし、仕組みを理解しないと、思わぬところに配置されてしまうことも…。

この記事では、positionの基礎から、それぞれの種類の特徴と使い方まで、初心者にもわかりやすく解説します。

スポンサーリンク

CSSのpositionとは?

position(配置)の基本概念

positionは、HTML要素の配置方法を決めるためのCSSプロパティです。

これを使うことで、以下のようなことが可能になります:

  • 自由な配置:ページの左上や右下など、好きな場所に配置
  • 相対的な配置:親要素の中で相対的に位置を調整
  • 固定表示:スクロールしても常に同じ位置に表示
  • 重なり順の制御:要素同士を重ね合わせてレイアウト

通常のHTMLの流れ(Normal Flow)

positionを理解するには、まず「通常の文書の流れ」を知ることが大切です。

通常の流れ

  1. HTML要素は上から下へ順番に配置される
  2. ブロック要素(div、p、h1など)は縦に並ぶ
  3. インライン要素(span、aなど)は横に並ぶ
<div>要素1(ブロック)</div>
<div>要素2(ブロック)</div>
<span>要素3(インライン)</span><span>要素4(インライン)</span>

positionを使うと、この自然な流れから「外して」自由に配置できるようになります。

positionの種類と詳しい使い方

CSSのpositionには主に以下の5種類があります。

static(デフォルト)

基本的な特徴

  • positionを何も指定しなかったときの標準状態
  • 通常の文書の流れ(HTMLの並び順)に従って配置される
  • toprightbottomleftプロパティは無効

実際のコード例

.normal-box {
  position: static; /* 書かなくても同じ */
  background-color: lightblue;
  padding: 20px;
}

いつ使う?

ほとんどの要素はこれが基本です。わざわざposition: static;と書くことはほぼありません。

リセット目的で使用

.reset-position {
  position: static; /* 他のpositionを上書きしたい場合 */
}

relative(相対配置)

基本的な特徴

  • その場(元の位置)を基準にして動く
  • toprightbottomleftで移動量を指定
  • 元の場所は空いたまま(他の要素は影響を受けない)
  • 子要素の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(スクロール連動)

基本的な特徴

  • relativefixedのハイブリッド
  • 通常は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

  • スクロール連動のナビゲーション
  • テーブルヘッダーの固定
  • セクション見出しの追従表示

コメント

タイトルとURLをコピーしました