Back to list
dev_to 2026年4月20日

子要素同士を完全に重ねて配置する方法は?

How Do You Stack Two Children Perfectly on Top of Each Other?

Translated: 2026/4/20 11:20:11
css-absolute-positioningcss-gridhtml-canvas-stylingz-indexlayout-techniques

Japanese Translation

質問:親コンテナ内に 2 つの子要素を持ち、両者を完全に重ねて同一位置・同一サイズでスタックさせたい(デッキのカードのように)。したがって、.foo と .bar を通常のドキュメントフローから外し、.container の中にある正確な同じ位置に配置する必要がある。従来の解答としては、親を位置コンテキストとして設定し、子要素を絶対配置してそれを埋めることだ。.container { width: 100px; height: 100px; position: relative; /* 位置コンテキストを確立 */ background-color: #eee; } .foo, .bar { position: absolute; /* フローから外す */ inset: 0; /* top/right/bottom/left: 0 の略 */ } .foo { background-color: rgba(255, 0, 0, 0.5); z-index: 1; } .bar { background-color: rgba(0, 0, 255, 0.5); z-index: 2; /* .foo の上に配置 */ } 親に position: relative を設定することは必須であり、これなしでは子要素は近い位置が指定された親祖先(あるいはビューポート)にアンカーされるためだ。この一行で子要素を .container にロックする。inset: 0 は現代の略語であり、子要素を親を埋めるように拡張する。幅と高さを個別にハードコーディングする必要がない。z-index は要素が重なった場合に、後から指定された要素がデフォルトで勝つ。明示的なスタック順序を制御したい場合に z-index を使用する。position: absolute に到達したくない場合は、CSS Grid には子要素を同じグリッドセルに配置というエレガントな技がある。.container { display: grid; width: 100px; height: 100px; } .foo, .bar { /* 全員が row 1, column 1 を主張する */ grid-area: 1 / 1; } そのだけ。両方の子要素が同じセルを占拠し、それを埋め尽くす。絶対配置も z-index も不要(ただし順序を変更したい場合は仍可及利用)。要素の重なりが通常のレイアウトフローに参加することを望む場合(例えばコンテナのサイズが子要素の固有サイズによって駆動される場合)に、これはしばしばよりクリーンな選択となる。状況:固定サイズのボックス上に読み込みスパイナー、ツールチップ、タグを重ねて表示する場合:絶対配置。最も高い子要素がコンテナの高さを決定するコンテンツの層化:絶対配置。あなたは既に position: relative な親を持つ必要がある場合:絶対配置。最も現代的で驚くことのない解決策を望む場合:CSS Grid。2 つのツール、1 つの問題。絶対配置は、フロントエンド開発者が知っておくべき戦況が試されたアプローチだ。CSS Grid のシングルセルの技は、子要素をレイアウトフローに保持する現代的な代替案だ。次回、習慣的に position: absolute に到達する際に、grid-area: 1 / 1 がよりクリーンであるか自問自答することだ。

Original Content

The Question You have a parent container with two children, and you want both children to completely overlap — same position, same size, stacked like cards in a deck: So we need to pull .foo and .bar out of the normal document flow so they both sit in the exact same spot inside .container. The classic answer. Make the parent a positioning context, then absolutely position the children to fill it. .container { width: 100px; height: 100px; position: relative; /* establishes the positioning context */ background-color: #eee; } .foo, .bar { position: absolute; /* removes them from the flow */ inset: 0; /* shorthand for top/right/bottom/left: 0 */ } .foo { background-color: rgba(255, 0, 0, 0.5); z-index: 1; } .bar { background-color: rgba(0, 0, 255, 0.5); z-index: 2; /* sits above .foo */ } position: relative on the parent — without it, the children would anchor to the nearest positioned ancestor (or the viewport). This line locks them to .container. inset: 0 — a modern shorthand that stretches the child to fill the parent. No need to hard-code width and height. z-index — when elements overlap, the later one wins by default. Use z-index when you want explicit control over stacking order. If you'd rather not reach for position: absolute, CSS Grid has an elegant trick: put every child into the same grid cell. .container { display: grid; width: 100px; height: 100px; } .foo, .bar { /* everyone claims row 1, column 1 */ grid-area: 1 / 1; } That's it. Both children occupy the same cell and stretch to fill it. No absolute positioning, no z-index required (though you can still use it if you need to reorder). This is often the cleaner choice when you want the overlap to participate in normal layout flow — for example, when the container's size should be driven by its children's intrinsic size. Situation Reach for Overlaying a loading spinner, tooltip, or tag on a fixed-size box Absolute positioning Layering content where the tallest child should define the container height CSS Grid You already have a position: relative parent for other reasons Absolute positioning You want the most modern, least-surprising solution CSS Grid Two tools, one problem. Absolute positioning is the battle-tested approach every frontend developer should know. CSS Grid's single-cell trick is the modern alternative that keeps children in the layout flow. Next time you reach for position: absolute out of habit, ask yourself whether grid-area: 1 / 1 would be cleaner.