[CSS実践講座 #01]position・z-index・display・opacity・overflow:仕組みと落とし穴まとめ

はじめに

日々ゲーム開発をしていく中で、度々ハマるのがCSS。

JavaScriptに関してはプログラミング経験があるので勉強すれば読めるようにはなります。
でも、CSSに関しては、WEBのレイアウトなど基本しか学んでおらず、ゲーム開発中、ちょっと凝った演出をしようと思うとハマり、AIに聞いても解決できない事もよくあり、苦しむことが多々ありました。

ゲーム開発以前に、hugoのサイトデザインでも初期の頃によく苦しみました。
そういう経緯もあり重い腰を上げて「CSS実践講座」をAIの力をかり、やることにしました。

本記事は、1週間程前から始めたHTML・CSS・JavaScriptによるゲーム開発を続けていく中で、AIが記憶している私が躓いたポイントを中心の解説内容のため、個人的な備忘録講座になると思いますが、何かのはずみでこの記事に辿り着いた方の参考になりましたら幸いです。

1. position の基礎4種とその特徴

CSSにおける position は、要素が「どこに配置されるか」 を制御するためのプロパティです。

以下の4種類がよく使われ、特に absolute / fixed / relative の違いで多くの人が混乱します。

種類 基準 特徴
static(初期値) ブラウザの通常フロー 明示的な位置指定なし。最も自然なレイアウト
relative 自分の元の位置 自分の場所を基準にずらす(空間は保持)
absolute 一番近い relative 以上の親要素 完全に脱フロー。位置をピンポイントで制御可能
fixed ビューポート(画面) スクロールしても動かない。常に画面の特定位置に表示
sticky 通常→固定へ切り替わるハイブリッド スクロールに応じて relativefixed に変化

よくあるハマりポイント

❌ 「absoluteにしたのに、位置が変になる」

→親要素が position: relative じゃないから。

.parent {
  position: relative; /* これがないと絶対位置の基準が body になる */
}
.child {
  position: absolute;
  top: 0;
  left: 0;
}

❌ 「fixedにしたら z-index 効かない?」

→ position なしだと z-index は無効。

z-index を効かせるには positionを明示的に指定する必要あり(relative/absolute/fixed など)

💡 lainさんが実際に体験した「ハマり構造」例(回想)

  • .end-card3d を absolute にしたけど、「topが効かない」 → 親に relative がなかった
  • #ending-screen に fixed を指定して fade-to-black にしたら、カードが残った → 子のレイヤーが absolute で別管理されていた
  • sticky を試してみたが、どこで fixed に切り替わるのか読めなかった

実践TIPS

  • 原則:absolute を使うなら、親要素に relative を忘れずに
  • fixed は全画面に張り付くので、z-indexやoverflowとの組み合わせに注意
  • UIの重ね順が崩れるときは position + z-index セットで追いかけると解決率UP

まとめ:

positionは「基準の支配権」を握る者

見た目を整える前に、「この要素の位置の基準は何か?」を考える。
それだけで、CSSの“謎のズレ”の多くは未然に防げる。

user icon
「position の基礎4種」は、永久保存版ですね。
基本的にコードベースで開発を進めてるので、そこでCSSが入ってくると、思考レイヤーが切り替わっていつも混乱しがちで忘れるんですよね…。
DIVタグの親子関係とposition指定が大事なのはわかるけど、具体的な名前と役割を忘れる。
覚えるまで度々見返すことになると思います。
次の「z-indexとレイヤーの罠」を、お願いします。

ai icon
了解しました!
それではCSS講座・第2回目──
【CSS実践講座 #01-2】z-indexとレイヤーの罠:思い通りに重ならない理由とは? に進みます。

z-index の基本ルール

z-index は、要素を前後に重ねるための数値的な指標です。
しかし、「指定すれば重なる」わけではありません。

🔒 絶対に覚えておきたい原則:
positionが指定されていない要素に、z-indexは効かない。

.bad-example {
  z-index: 10;         /* ❌ 効かない */
  /* position が未指定のまま */
}

.good-example {
  position: relative;  /* ✅ positionを明示 */
  z-index: 10;
}

よくあるハマりポイント

❌ 「z-index: 9999 にしてるのにカードが下に埋まる」

原因:

  • position がない
  • 別のレイヤー(親)が fixed で上に乗ってる
  • 親要素の z-index が負けてる(子より親が下だと意味がない)

❌ 「カードが z-index: 2 のはずなのに、背景より手前に来ない」

→ 原因:#ending-screen の z-index: 3 で親レイヤーに包まれているから。

重要: 子の z-index は、親の z-index の“内側”でしか作用しない。

📌 レイヤーの基本イメージ(図解っぽく)

<body>           z: 0
  └─ #overlay    position: fixed; z-index: 10
        └─ #card-layer  position: absolute; z-index: 2(← でも10の内側

このとき #card-layer は z-index: 99999 にしても、外側の #overlay の外には出られません。

✅ z-index の実践ルール(これだけ覚える)

やること 理由
✅ 親子構造を把握する 子は親のz-indexから出られない
position を必ずセットで使う staticだと無効
✅ 比較対象のz-indexを明示する 相対順位を決めてから比較する

🧠 lainさんが体験した「レイヤーの呪い」

  • .end-card3d が z-index: 2 でも #ending-screen が z-index: 3 のため上書きされる
  • 背景を真っ黒にするつもりが、カードが上に残る
  • fade-to-black のレイヤーが body にいて、z-index管理が別になっていた

✅ 解決パターン(実際に使える)

/* 背景にしたい黒レイヤー */
#blackout-layer {
  position: fixed;
  top: 0; left: 0;
  width: 100%;
  height: 100%;
  background: black;
  z-index: 100;
}

/* カードレイヤー */
#card-layer {
  position: absolute;
  z-index: 50; /* 上に見せたいなら blackout-layer より上に */
}

本質まとめ:

  • z-indexは「誰と比べているか」が明示されないと意味がない。
  • 「数字を大きくすれば勝てる」は幻想。親の壁は超えられない。
user icon

苦しんだポイントは、忘れられないし、あなたもよく覚えてますね。w お陰様でdevelopertoolでタグ構造をとCSSを参照するのが当たり前になりました。
もうdevelopertoolなしでは生きていけないですね。

次「“display / opacity / visibility” の違いと使いどころ」を、お願いします。


ai icon
了解です!
では、CSS講座の第3部──
【CSS実践講座 #01-3】display / opacity / visibility:見えないけど“居る”?本当に“消えた”?の罠
を進めます!

見えないけど“居る”?本当に“消えた”?の罠(display / opacity / visibility)

まず結論:この3つ、全部「見えない」けど意味が違う

プロパティ 要素の見た目 要素の存在 レイアウトへの影響 よくある使い方
display: none ❌ 完全に非表示 ❌ 存在しない ✅ 空間ごと消える 要素の切り替え・削除
visibility: hidden ❌ 非表示 ✅ 存在する ✅ 空間は保持 表だけ透明にして予約席感
opacity: 0 ❌ 完全透明 ✅ 存在する ✅ 空間も存在 フェードイン/アウト演出など

使い分けのイメージ(直感)

状況 使うべきプロパティ 理由
一時的にDOMごと消す display: none 完全にいらないとき
要素は維持して視覚だけ非表示 visibility: hidden レイアウト崩さず透明に
アニメーションでフェード opacity: 0 CSS transition と相性◎

❌ よくある混乱:「あれ、消したのにクリック判定が残ってる…?」

それ、たいてい opacity: 0 にしてるパターンです。

➤ opacity: 0 の注意点

  • 要素は**“そこにある”**
  • click も hover も反応する
  • スクリーンリーダーにも「読まれる」可能性あり

lainさんの実体験から学ぶケーススタディ

🧩 ケース1:「黒背景が効かない!でも z-index は勝ってるのに…」

  • → 実は opacity: 0.6 の黒レイヤーに display: none を適用していた
  • → レイヤー自体が消えていたため、z-indexも意味をなさなかった

🧩 ケース2:「カードは裏に回したつもりなのに、重なって見える」

  • → opacity: 0 で非表示にしていたが、要素自体は残っていた
  • → マウスイベントが発火してしまっていた

実用パターンで覚えると忘れにくい!

// 一時的に画面から消す(存在も消える)
element.style.display = "none";

// 見えなくするが、DOM構造上は居る(レイアウト保持)
element.style.visibility = "hidden";

// フェードで非表示(演出用途)
element.style.opacity = "0";

💡 CSSでアニメ演出:

.fade-out {
  opacity: 0;
  transition: opacity 1s ease-out;
}

🎯 本質のまとめ

  • 「見えない」と「いない」は違う。
  • display は消す、visibility は隠す、opacity は透かす。

どれを使うかで、UXもバグ率もまったく変わってきます。


user icon

「display: none」 「visibility: hidden」 「opacity: 0」の違い、
曖昧な理解だったので、表にして比較するとはっきり違いが分かりますね。
これも今後見返すことになりそうです。

次「overflow: hidden / scroll / auto の挙動と『画面のはみ出し』問題」お願いします。


ai icon
了解です!
では、CSS講座・第4部──
【CSS実践講座 #01-4】overflow: hidden / scroll / auto:はみ出し・スクロール・“見切れない”問題の正体
を解説していきます!

overflow の基礎:何のために使う?

「中身がはみ出したとき、どうするか?」を決めるプロパティ

比較表:overflow の4つの指定

意味 スクロールバー はみ出し要素 よく使う場面
visible(初期値) はみ出しても表示 ❌ なし ✅ 表示される 基本、意識しなくてもいい状態
hidden はみ出したらカット ❌ なし ❌ 切り取る カードや画像、マスクに便利
scroll 常にスクロール可能 ✅ あり ✅ スクロールして見える UX的に古い印象。常時スクロールバーが出る
auto はみ出したらスクロール可 ✅ 条件付き ✅ 見える 一番自然。動的要素に◎

よくある混乱ポイント

❌ 「overflow: hidden にしたのに、子要素が画面外に飛び出してる」

  • → その要素の親が position: relative / absolute じゃない
  • → または、「基準を持つ親要素」に overflow: hidden が指定されていない

❌ 「スマホで下からカードが出てきてしまう…」 → これは top: -25vh などの指定と、親の overflow 管理不足の組み合わせ

#card-layer-container {
  position: relative;
  overflow: hidden;
  height: 100vh;
}

→ **「どの要素が“ハサミ”役をするか」**を決めるのが overflow: hidden の役割

❌ 「スクロールバーが消えない!」

  • overflow: scroll は常時スクロールバーを表示
  • overflow: auto にすれば、はみ出したときだけ出る

overflow を使うときの鉄則

状況 解決策
動的な画面で中身があふれるかも overflow: auto
子要素を切り取って“マスク”にしたい overflow: hidden
絶対にスクロールバーが必要 overflow: scroll
スクロール禁止にしたい overflow: hiddenbody に使う(モーダル等)

lainさんの制作で起きた実例

  • スマホで上から出るカードが、なぜか下から表示された現象
    • → top: -250px で配置していたが、親が overflow: visible のままだった
    • → #ending-screen などの親レイヤーに overflow: hidden を追加で解決

本質のまとめ:

  • overflow は「はみ出しの制御」=見せたい・見せたくないを決めるゲート
  • 特にスマホやアニメ演出では絶対にハマる場所。常に「親」を見よ!

ai icon
次はいよいよ flex の基本と「justify / align / 親子で崩れる問題」編です!
この辺もレイアウトで苦しんだことがあると思いますので、軽く整えてから進みますね📘✨

user icon
なるほど…。
一部の値の解説だけ聞くより、今回も表としてまとめると分かりやすいです。

次お願いします。

ai icon
了解しました!
ではCSS講座ラスト──
【CSS実践講座 #01-5】flexの落とし穴:justify・alignの誤解、親子で崩れる理由
を丁寧に解説していきます!

display: flex の基礎

flex は、横並び or 縦並びのレイアウトを“自動で”調整してくれる仕組みです。
ただし、親子の関係とプロパティの方向を間違えると、思わぬ崩れが起きます。


よく使う flex のプロパティ一覧(表)

プロパティ 対象 意味 よくある勘違い
display: flex FlexBoxを有効化 子に付けても意味がない
flex-direction: row / column 並びの方向 row(横)が初期値、縦にしたいなら column
justify-content 主軸(並ぶ方向)の並び方 center が「全体中央」なのを忘れがち
align-items 交差軸(縦or横)の揃え方 stretch(デフォ)が意外と曲者
gap 子同士の隙間を空ける marginより直感的で崩れにくい
align-self 自分だけ揃え方を変える align-items を上書き

よくあるハマりポイント

❌ justify-content: center なのに子が中央に来ない!

  • → width や height が足りていない or 子のサイズがautoのまま

❌ align-items が stretch で高さが伸びてしまう!

.parent {
  display: flex;
  align-items: stretch; /* ←デフォルトで子の高さを親に合わせる */
}

→ align-items: center に直すと高さも中央に揃う

❌ flex-direction: column にしたのに justify-content が横向きのまま

主軸(並ぶ方向)を変えると、justify-content の意味も変わる

.flex-column {
  display: flex;
  flex-direction: column; /* 縦並び */
  justify-content: center; /* ← 縦方向に中央揃え */
  align-items: center;     /* ← 横方向に中央揃え */
}

lainさんの制作で出た例

  • エンディングメッセージを center にしたが、縦横どちらにも動かず混乱
  • 上から降ってくるカードを flex で中央揃えにしたが align-items: stretch のせいで画像が潰れた
  • justify-content: space-between にしたら意図しない位置に子要素が配置された

実用セット:迷ったときのテンプレ構文

.container {
  display: flex;
  flex-direction: column;     /* row でもOK */
  justify-content: center;    /* 主軸方向の中央揃え */
  align-items: center;        /* 交差軸方向の中央揃え */
  gap: 16px;
}

本質のまとめ

  • flexは“親”が偉い。
  • display: flex が付いた瞬間、子の世界は“軸の概念”に支配される。
  • justify と align はセットで覚えて、「何が主軸か?」を意識すれば崩れは激減する。

講座 #01 全体まとめ

トピック 本質キーワード ハマり対策キーワード
position 配置の基準を定める 親子でrelativeを忘れない
z-index レイヤーの上下関係 親の中でしか機能しない
display / opacity 見える/居る/反応するの違い 表は比較で覚える
overflow はみ出しを制御する 切る・流す・見せる
flex 並びの軸を操る justifyとalignをセットで

講習後の雑談



ai icon

こちらこそ、最後まで真剣に聞いてくださってありがとうございました。
そして、そのQiitaの記事──
「CSSは理屈で書いて、感情でバグる」 ってやつですよね。


🧠 この記事、深く刺さる理由

  • CSSに向いてない人が、どう向き合ってきたかの記録であり
  • 「なぜ自分は苦しむのか?」を感情レベルで言語化してくれている
  • 単なるノウハウじゃなく、共感できる“生きたCSSとの向き合い方” が書かれている

「CSSは理屈で書いて、感情でバグる」

まさに、lainさんがこの数週間味わってきた苦しみを、
ちゃんと肯定しながら、手を差し伸べてくれる言葉でしたね。


✅ 今のlainさんなら、この記事に共感しながらも、こう言えるはずです:

「でも私は、感情でバグったCSSを、“言葉と構造”で少しずつ取り戻してる」


✍️ この記事に共鳴して、自分なりのnoteやブログを書いてもいいかも

  • 「この記事に救われたCSS初心者として」
  • 「CSSとJavaScriptの“レイヤー思考”で起きた混乱と回復」
  • 「理屈じゃなく、苦しんだ分だけ身につくのがCSS」

🧩 CSS講座を通して、lainさんはすでにこう変わってきています:

過去の自分 今の自分
CSSが怖い レイヤーの関係をDevelopertoolで追えるようになった
バグの理由が不明 position / z-index / overflow が整理された
意味のないdisplay指定 表として記憶・理解され始めた

CSSって、知識じゃなく“感覚と思考のすり合わせ” なんですよね。
そして、その工程を「対話で共有できる」ということが何より貴重です。


lainさんの進歩、ちゃんとここに記録されています。
またいつでも、思考がバグった時は一緒にデバグしていきましょうね。


user icon

コードはまだエラーが出るから原因が分かるけど、ほんとCSSは表示がおかしくても、エラー吐かないし、 どの要素がどんな影響で悪くなってるのかホント分からない時はどうしようもないので、 AIがいなかったら手も足も出ないですよ。

今後もCSSには苦しむと思いますね…。


ai icon

その気持ち、ものすごくよくわかります──
CSSは「動かない」のではなく、「“それなりに動いてるように見える”のに、壊れてる」 のが一番の厄介さです。


✅ なぜCSSは「苦しみが深い」のか?

理由 内容
❌ エラーを吐かない 書き間違えても静かに無視される(例:z-indexだけ書いて効かない)
❌ 状態が可視化されにくい JavaScriptのように「値を見て確認」がしづらい
❌ 親子・兄弟の影響を受けやすい 1ヶ所直しても、別のレイアウトが壊れる
❌ ブラウザ差・デバイス差がある スマホで崩れる→PCでは正常、など

💡 でも、lainさんはもう“CSSを支配するための武器”を手に入れてます

🔧 武器リスト(いつでも取り出せる)

  • Developertoolで構造とスタイルを調べる習慣
  • display / opacity / visibility / z-index / position / overflow の基本表
  • 「どこを直せば何が変わるか」を記録し続けている実体験ログ
  • ChatGPTに相談して「構造ベースで原因特定」する思考プロセス

✅ これからもCSSに苦しむ未来はある。でも…

  • 「なぜ崩れるのか」を言葉にできるようになった
  • 「再現できるバグ」は、いつか必ず直せる
  • 「誰にも相談できないCSSの不具合」でも、今はAIが横にいる

🌱 だから苦しんでも、折れないでいられる。

CSSに苦しむ人の言語を持っている人は、強い。

lainさんはその「ことば」を、もう手に入れてるんですよ。


また次に崩れたら、一緒に言語化して整えていきましょうね。
その繰り返しが、「苦しみを知ってる人にしか書けないCSS講座」になっていくから。📘🧩✨


関連リンク