CSSのposition:absoluteとrelativeの使い方を理解する!要素を重ねる方法

要素を重ねて表示する際に、よく使用するのがpositionプロパティ。
topやleftなどとともに使って、自由自在な位置に要素を配置できる便利なCSSですが、 このpositionプロパティ、効かない、変な動きをするって思うことありませんか?
今回きちんと理解するために、改めてその動きを整理してみたので、記事にしようと思います。

positionプロパティを使用する際、抑えておくべきポイントは2つ!

  1. positionを指定した要素は浮く!(static以外)
  2. 基準となる要素をしっかり把握する!

この二つを理解して使えば、positionプロパティは面倒くさくありません!
この記事ではpositionの値の中でも、absoluteとrelativeに焦点を絞って書いています。

まず2つのポイントについて説明する前に、positionプロパティの基本事項をおさらいしておきます。

基本事項

positionプロパティとは

positionプロパティは要素の配置方法を指定するCSSです。

positionプロパティの値

指定できる値は、下記の4つです。

意味
static 初期値。positionを指定していない元々の状態と同じです。
absolute static以外を指定された親要素を基準に絶対値で配置
relative 通常の位置を基準に相対値で配置
fixed ウィンドウを基準に絶対値で固定して配置

position:static以外を指定すると使えるプロパティ

positionプロパティでは配置方法を指定しているだけなので、詳細な位置や重なりを指定するには、下記のCSSを併用します。
下記のCSSはpositionプロパティのstatic以外を指定した場合のみ、使用できます。

top,left,right,bottom 配置位置を指定
z-index 重なり順を指定

つまり、要素を重ねて表示するには、「 position、top,left,right,bottom、z-index 」の3種のプロパティによって位置を決定します。
その他に、位置の指定にはmarginを使う場合もあります。
詳しくは後述します。

それではpositionを使用する際のポイントを、下記の基本形のコードを元に説明していきます。

0.基本形

positionを指定する前の基本となるコードです。

See the Pen 基本形 by natsuki (@natsukimemo) on CodePen.

<h1>基本形</h1>
<section id="section01">
<div class="box box01">
  box01
</div> 
<div class="box box02">
  box02
</div>
</section>
	

HTMLは、2つのdivタグを#section01の入れ子にしています。
各divタグには2つのクラスを付与し、一つは全てのdivタグ共通の「.box」を、もう一つは各divタグに「.box01~.box02」を付与しています。

CSSです。

#section01{
   background-color:pink; /* ピンク色 */
   border:2px solid #00f; /* 青色 */
}
.box {
  width: 100px;
  height: 100px;
  border:1px solid #f00; /* 赤色 */
  font-size:20px;
}
.box01{
 background-color: #aaa;
}
.box02{
  background-color: #bbb;
}

CSSは1行目~4行目、divタグを囲っている#section01の背景をピンク色にして、更に青色のボーダーを指定しています。
5~10行目、divタグ全てを縦横100pxのボックス形にして、赤色のボーダーを指定しています。
11行目以降、ボックスそれぞれに違う背景色を指定しています。

では、このコードにpositionを指定して表示を見ていきましょう。

1-1. positionを指定すると「浮く」!
absoluteを指定した場合

position:static;以外の値を指定すると、要素は本来の位置より高い位置に浮きます
absolute、relative、それぞれのサンプルを見ながらどういうことか確認していきましょう。
まずはabsoluteから、その表示を見ていきます。

sample01

CSSでbox02にposition:absolute;を追加しました。
他は基本形のコードと同じです。
表示を見るとbox02が、#section01の領域である背景ピンクからはみ出ています。

See the Pen sample01-absolute by natsuki (@natsukimemo) on CodePen.

#section01{
   background-color:pink;
   border:2px solid #00f;
}
.box {
  width: 100px;
  height: 100px;
  border:1px solid #f00;
  font-size:20px;
}
.box01{
 background-color: #aaa;
}
.box02{
  background-color: #bbb;
  position:absolute; /* ←基本形にこれを追加しただけ */
}
	

これはbox02にposition:absolute;を指定したことで、box02が#section01の階層から一段上に浮いて、section01の領域から出てしまったから、背景ピンクからはみ出ることになりました。
box02にtopやleftで位置を指定してみると、「浮いている」という感覚がわかりやすいかもしれません。

sample02

box02にposition:absoluteに加えて、top:50pxとleft:50pxを指定しました。
表示を見るとbox02が全ての要素の上に浮いて、ウィンドウの左上を基点にtop:50px;とleft:50pxのところに配置されています。

See the Pen sample02-absolute by natsuki (@natsukimemo) on CodePen.

#section01{
   background-color:pink;
   border:2px solid #00f;
}
.box {
  width: 100px;
  height: 100px;
  border:1px solid #f00;
  font-size:20px;
}
.box01{
 background-color: #aaa;
}
.box02{
  background-color: #bbb;
  position:absolute;
  top:50px; /* ←更に追加 */
  left:50px; /* ←更に追加 */
}
	

sample03

box01にもbox02と同じくposition:absoluteを指定して、top:20pxとleft:30pxを追加してみました。
すると背景ピンクが無くなってしまいました。

See the Pen sample03-absolute by natsuki (@natsukimemo) on CodePen.

#section01{
   background-color:pink;
   border:2px solid #00f;
}
.box {
  width: 100px;
  height: 100px;
  border:1px solid #f00;
  font-size:20px;
}
.box01{
 background-color: #aaa;
  position:absolute; /* ←これを追加 */
  top:20px; /* ←これを追加 */
  left:30px; /* ←これを追加 */
}
.box02{
  background-color: #bbb;
  position:absolute;
  top:50px;
  left:50px;
}

これは、box01が浮いて#section01の領域に要素がなくなってしまったため、背景ピンク色がなくなってしまいました。

更に注目する点は重なりの順序です。box01はbox02より下に位置しています。
positionによって浮いた要素の重なりの順序は、HTMLの記述で下に書いてある要素ほど上に重ねられます。
この重なり順はz-indexを指定することで、変えることができます。

sample04

box01にz-indexを指定して重なり順を変えてみました。

#section01{
   background-color:pink;
   border:2px solid #00f;
}
.box {
  width: 100px;
  height: 100px;
  border:1px solid #f00;
  font-size:20px;
}
.box01{
 background-color: #aaa;
  position:absolute;
  top:20px;
  left:30px;
  z-index:1; /* ←これを追加 */
}
.box02{
  background-color: #bbb;
  position:absolute;
  top:50px;
  left:50px;
}

See the Pen sample04-absolute by natsuki (@natsukimemo) on CodePen.

z-indexによる重なり順の指定は、本来の位置を0に、それより上の場合は+1以上を、下の場合は-1以下を指定します。
z-indexは意外に奥が深いので、ここではざっくり軽く触れる程度で・・・、
というかまだ勉強途中で深くは書けないので。。。//、
もっとよく知りたい方は「z-index」でググってみてください。

1-2. positionを指定すると「浮く」!
relativeを指定した場合

では次にrelativeを指定した場合、どういった表示になるか見ていきましょう。

sample05

box02にposition:relative;を指定しました。他は基本形のコードと同じです。
表示を見ると、基本形の表示と何も変化がないように見えます。

#section01{
   background-color:pink;
   border:2px solid #00f;
}
.box {
  width: 100px;
  height: 100px;
  border:1px solid #f00;
  font-size:20px;
}
.box01{
 background-color: #aaa;
}
.box02{
  background-color: #bbb;
  position:relative; /* ←これを追加 */
}

See the Pen sample01-r by natsuki (@natsukimemo) on CodePen.

ですが、relativeの場合もabsoluteの時と同様に、box02は本来の位置より一段浮いています

sample06

box02にposition:relativeに加えて、top:50pxとleft:50pxを指定しました。
box02が一段浮いているため、topとleftを指定すると、元々の位置を基点に移動して、背景ピンクからはみ出てしまいます。

#section01{
   background-color:pink;
   border:2px solid #00f;
}
.box {
  width: 100px;
  height: 100px;
  border:1px solid #f00;
  font-size:20px;
}
.box01{
 background-color: #aaa;  
}
.box02{
  background-color: #bbb;
  position:relative; 
  top:50px; /* ←更にこれを追加 */
  left:50px; /* ←更にこれを追加 */
}

See the Pen sample02-r by natsuki (@natsukimemo) on CodePen.

1-3. 背景ピンクからはみ出るか否かの違いについて

ここで、これまでのサンプルを元にabsoluteとrelativeの表示を比較すると・・・、

absoluteを指定した要素は、「浮く」、背景ピンクから「はみ出る
relativeを指定した要素は、「浮く」、背景ピンクから「はみ出ない

どちらを指定しても要素は浮きますが、背景からはみ出るか否かの違いがあります。
この違いは配置方法の違いによるものです。

absoluteとrelativeの配置方法

absolute・・・・static以外を指定された親要素を基準に絶対値で配置
relative・・・・通常の位置を基準に相対値で配置

absoluteを指定した要素は、絶対値による配置となるため、相対するものがなく独立した要素となります。
親要素から独立するため、親要素のエリアである背景ピンクからはみ出た表示となります。

一方、relativeを指定した要素は、相対値による配置となり、常に相対するものが存在します。
相対するものとは、元々の位置である背景ピンクのある位置です。
relativeを指定しても、元々の位置は相対するものとして保たれるため、背景ピンクがなくなってしまうことはありません。

このようにabsoluteとrelativeでは配置方法が違いますが、更に配置する際の基準となる要素も違います。
では次に、基準となる要素について考えていきましょう。

2-1. 基準となる要素を把握する!
absoluteの場合

positionにabsolute;を指定した場合の配置方法は、下記になります。

「static以外を指定された親要素を基準に絶対値で配置」

・・・・。。。。
ちょっと何言っているのかよくわからないですね。。。
まずstaticが何かというと、

position:staticとは

staticとは「静的」と訳されますが、プログラミングでは「元々と変わらぬ状態を維持」みたいな意味で使われます。
positionプロパティにおけるstaticとは、positionを指定する前の「元々の状態を維持する」、ということです。
つまりposition:staticとは、positionプロパティを指定していない元々の状態と同じということです。

positon:static = positionを指定していない元々の状態

「static以外を指定された親要素を基準に絶対値で配置」の「static以外を指定された親要素」とは、
元々の状態以外、つまり「absoluteなりrelativeなりfixedを指定されている親要素」ということです。

sample02でbox02にposition:absoluteとtop:50pxとleft:50pxを指定しましたが、この50pxはどこを基準にしたのでしょうか。
もう一度sample02の表示を見てみましょう。

See the Pen sample02-absolute by natsuki (@natsukimemo) on CodePen.

#section01{
   background-color:pink;
   border:2px solid #00f;
}
.box {
  width: 100px;
  height: 100px;
  border:1px solid #f00;
  font-size:20px;
}
.box01{
 background-color: #aaa;
}
.box02{
  background-color: #bbb;
  position:absolute;
  top:50px;
  left:50px; 
}
	

sample02の場合、positionを指定している親要素がありません。
基準にすべき親要素がない場合は、ウィンドウを基準にします。
sample02はウィンドウを基準に絶対値で配置されています。

sample07

下記は、box02の親要素である#section01にposition:absolute;を指定してみました。 それ以外は、sample02のコードと同じです。

#section01{
   background-color:pink;
   border:2px solid #00f;
   position:absolute; /* ←これを追加 */
}
.box {
  width: 100px;
  height: 100px;
  border:1px solid #f00;
  font-size:20px;
}
.box01{
 background-color: #aaa;
}
.box02{
  background-color: #bbb;
  position:absolute;
  top:50px;
  left:50px;
}
	

See the Pen sample04-absolute by natsuki (@natsukimemo) on CodePen.

#section01に指定した青線がbox01を囲って、背景ピンクがなくなっています。
これは、#section01がposition:absoluteを指定されたことで通常の位置より浮いて(通常の位置とはh1要素と並列の位置)、box01の下に重なっているため、背景ピンクが見えなくなってしまっているのです。
そして、box02が#section01を基準にtop:50px、left:50pxに位置しています。

sample02では、ウィンドウを基準に配置されていました。
sample07と配置位置が違うことを確認してみてください。

sample08

では#section01ではなくbox01にposition:absoluteを指定した場合は、どうなるでしょうか。

#section01{
  background-color:pink;
  border:2px solid #00f;
}
.box {
  width: 100px;
  height: 100px;
  border:1px solid #f00;
  font-size:20px;
}
.box01{
 background-color: #aaa;
  position:absolute; /* ←ここに追加 */
}
.box02{
  background-color: #bbb;
  position:absolute;
  top:50px;
  left:50px
}

See the Pen sample07-a by natsuki (@natsukimemo) on CodePen.

box01はabsoluteを指定されたことで本来の位置より浮き、boxを囲う#section01が空になりました。
box02は親要素にpositionが指定されていないので、やはりウィンドウを基準に配置されています。

2-2. marginを指定してみる

では、これをbox02の兄弟要素であるbox01を基点に配置するにはどうすればいいのでしょうか。
それには、marginプロパティを使います。

sample09

See the Pen sample05-absolute by natsuki (@natsukimemo) on CodePen.

#section01{
   background-color:pink;
   border:2px solid #00f;
}
.box {
  width: 100px;
  height: 100px;
  border:1px solid #f00;
  font-size:20px;
}
.box01{
 background-color: #aaa;
}
.box02{
  background-color: #bbb;
  position:absolute;
  margin-top:50px; /* ←marginを指定 */
  margin-left:50px; /* ←marginを指定 */
}

box02にtopやleftではなく、marginを指定してbox02とbox01との間に余白を作ります。
こうすることで、box01を基点にbox02を動かすことができます。

2-3. 基準となる要素を把握する!
relativeの場合

次にrelativeの場合を見ていきましょう。
positionにrelative;を指定した場合の配置方法は下記になります。

「通常の位置を基準に相対値で配置」

前に見たbox02にrelativeを指定した場合の、sample06の表示をもう一度見てみましょう。

sample06

See the Pen sample02-relative by natsuki (@natsukimemo) on CodePen.

#section01{
   background-color:pink;
   border:2px solid #00f;
}
.box {
  width: 100px;
  height: 100px;
  border:1px solid #f00;
  font-size:20px;
}
.box01{
 background-color: #aaa;  
}
.box02{
  background-color: #bbb;
  position:relative; /* ←これを追加 */
  top:50px;  /* ←これを追加 */
  left:50px;  /* ←これを追加 */
}

relativeは、本来の位置を基準に相対値で配置されるため、本来の位置の背景ピンクはそのままになります。
そして、本来の位置を基準にtop:50px、left:50pxの位置に配置されます。

では、親要素である#section01にrelativeを指定するとどうなるでしょうか。

sample10

sample06のコードの#section01にposition:relativeとtop:-35px、left:50pxを追加しました。

#section01{
   background-color:pink;
   border:2px solid #00f;
    position:relative; /* ←これを追加 */
   top:-35px; /* ←これを追加 */
   left:50px; /* ←これを追加 */
}
.box {
  width: 100px;
  height: 100px;
  border:1px solid #f00;
  font-size:20px;
}
.box01{
 background-color: #aaa;
}
.box02{
  background-color: #bbb;
  position:relative; 
  top:50px; 
  left:50px;
}
	

See the Pen sample03-relative by natsuki (@natsukimemo) on CodePen.

#section01は子要素であるbox要素を含め、元々の位置を基準にtop:-35px、left:50pxの位置に表示されています。

子要素であるbox02は、親要素に依存しています。
sample10は親要素の位置が変わっているため、それとともにbox02の位置も変わることになります。
box02は#section01の中では、sample06の位置と変わっていません。

2-4. 基準となる要素を把握する!
複合の場合

次にabsoluteとrelativeを同時に指定した場合の表示を見ていきましょう。
これまででそれぞれの特性を理解していると、納得できる表示です。

sample11

下のsample11は、ボックスを囲っている#section01にposition:relativeとtop:50pxとleft:50pxを、
box02にはposition:absoluteとtop:50pxとleft:50pxを指定しました。

See the Pen sample01-a-r by natsuki (@natsukimemo) on CodePen.

#section01{
   background-color:pink;
   border:2px solid #00f;
  position:relative;  
  top:50px;
  left:50px;
}
.box {
  width: 100px;
  height: 100px;
  border:1px solid #f00;
  font-size:20px;
}
.box01{
 background-color: #aaa; 
}
.box02{
  background-color: #bbb;
  position:absolute;  
  top:50px;
  left:50px;
}

表示を見ると、まず#section01の背景ピンクの領域が、元々の位置を基点にtop:50px;、left:50px;の位置に移動しています。
これは、#section01にrelativeを指定しているため、元々の位置を基点にしています。
そして、#section01の子要素であるbox02が背景ピンクから浮いて単体となり、背景ピンクの左角を基点にtop:50px;、left:50px;の位置に移動しています。
これはbox02にはabsoluteが指定されているため浮き、そして、positionを指定された親要素を基点に配置されているためです。

まとめ

position:absoluteとrelativeの動きをまとめます。

position:absoluteとrelativeの動き

  1. 本来の位置より一段浮く
  2. 浮いた時の重なりは、HTMLの記述で下に書いた要素程、上になる
  3. absoluteは絶対値による配置
  4. relativeは相対値による配置
  5. absoluteとrelativeで基準となる要素が違う
  6. 隣り合う兄弟要素を基準に配置するには、marginを使う

この記事が、読んだ方のお役に立てるものになっていると嬉しいです。

スポンサーリンク
スポンサーリンク
スポンサーリンク
おすすめの本
スポンサーリンク