脳汁portal

アメリカ在住(だった)新米エンジニアがその日学んだIT知識を書き綴るブログ

画像を重ねる方法(positionとかtopとか)

html5で画像を重ねて表示する方法
毎回力技でやっているので備忘録として
使用するpropertyは主にpositionとz-indexと位置に関するtop/left/bottom/right

基点の指定(position)

  • relative, absolute, static, fixedをとる
  • 指定しない場合のデフォルトはstatic

static

  • positionのデフォルト値
  • topとかleft等の位置情報やz-indexを指定しても反映されない
<div>
  <img src="freedom.jpg" />
</div>

f:id:portaltan:20170530123620p:plain

明示的にstaticを指定して位置情報を与えても変わらない

<div style="position: static; top: 150px; left: 100px;">
  <img src="freedom.jpg" />
</div>

f:id:portaltan:20170530123628p:plain

absolute

  • 親ボックスの端を基準にして、指定距離だけ移動した位置に表示
    • 親ボックスとはpositionプロパティにstatic以外が指定されている要素のこと
    • 何も指定されない場合はwindowの端が基準になる
<div style="position: absolute; top: 150px; left: 100px;">
  <img src="freedom.jpg" />
</div>

次にpositionをabsoluteに変更するとtopとleftプロパティが反映され、上端から150px、左端から100pxずれた位置に画像が表示される
f:id:portaltan:20170530123731p:plain

ここでずれた位置に画像を一つ追加してみる

<div>
  <img src="kira.png" />
</div>

<div style="position: absolute; top: 150px; left: 100px;">
  <img src="freedom.jpg" />
</div>

見事新しい画像が先ほどずらした150pxの空間に配置されました
f:id:portaltan:20170530124410p:plain

relative

  • 本来そのコンテンツが表示される位置を基準に指定した値だけ移動して表示する
<div style="position: relative; top: 100px; left: 100px;">
  <img src="freedom.jpg" />
</div>

単純に1つの画像を表示するだけではabsoluteとほぼ同じ
f:id:portaltan:20170530123731p:plain

次にabsoluteとの時と同じくずらした位置に画像を追加します

<div>
  <img src="kira.png" />
</div>

<div style="position: relative; top: 150px; left: 100px;">
  <img src="freedom.jpg" />
</div>

f:id:portaltan:20170530124532p:plain
すると今度は少し下の位置に表示されてしまいました
これはabsoluteの場合は親ボックス(今回はwindowの端)から指定した分だけ移動した位置に表示されていたのが、relativeの場合は実際に表示されるはずだった位置から指定した分だけ移動しているためです
f:id:portaltan:20170530125118p:plain

fixed

  • windowの端から指定した距離だけ移動
  • そしてスクロールしても移動せずに固定(fix)される

位置の指定(top / bottom/ left / right)

  • topは上記で指定した基準からどの程度下にずらすかを示す
  • bottom, left, rightは同様に下、左、右からどの程度ずらすかを示す
<div style="position: absolute; top: 50px;">
  <img src="freedom.jpg" />
</div>

f:id:portaltan:20170530130335p:plain

<div style="position: absolute; bottom: 50px;">
  <img src="freedom.jpg" />
</div>

f:id:portaltan:20170530130425p:plain

  • topとbottom, leftとright両方を指定したい場合、それぞれtopとleftが優先される
<div style="position: absolute; top: 50px; bottom: 50px; left: 50px; right: 50px;">
  <img src="freedom.jpg" />
</div>

f:id:portaltan:20170530130537p:plain

画像の重ね方

やっと本題の画像の重ね方ですが、上のpositionの位置の指定を使えば簡単にできます
今回はフリーダムの画像の上にキラの写真を重ねます

absoluteの場合

<div>
  <img src="freedom.jpg" />
</div>

<div style="position: absolute; top: 100px; left: 100px;">
  <img src="kira.png" />
</div>

f:id:portaltan:20170530131143p:plain
親ボックスの左上を基点にして下に100px、右に100px移動したところにキラの顔が表示されました

relativeの場合

上記のpositionを単純にrelativeにすると以下のようになります
f:id:portaltan:20170530131558p:plain
これは上で説明したように基点が実際に表示される場所(フリーダムの画像の下)になるためです
このケースでもし画像を重ねあわせたい場合は位置を指定する際に逆にマイナスを指定することで重ねることができます
f:id:portaltan:20170530154251p:plain

更に画像を重ねる場合

同じようにpositionと位置を指定していけば何重にも画像を重ねることができます

<div>
  <img src="freedom.jpg" />
</div>

<div style="position: absolute; top: 100px; left: 100px;">
  <img src="kira.png" />
</div>

<div style="position: absolute; top: 150px; left: 150px;">
  <img src="kira2.jpg" />
</div>

f:id:portaltan:20170530132656p:plain
f:id:portaltan:20170530134553p:plain

重なりの順番(z-index)

今回は順番的に上から『キラ⇒キラ⇒キラの乗ってたやつ』となりましたが、この順番もz-indexで変更することができます

  • z-indexの値の大きい要素が上に表示されます
  • デフォルトは親要素と同じ値か0です
  • positionがstaticの場合は反映されない

なので以下のように記述すれば一番下のフリーダムが1番上に表示されて、他の2枚はその下に隠れます

<div style="position: absolute; z-index: 20;">
  <img src="freedom.jpg" />
</div>

<div style="position: absolute; top: 100px; left: 100px;">
  <img src="kira.png" />
</div>

<div style="position: absolute; top: 150px; left: 150px;">
  <img src="kira2.jpg" />
</div>

f:id:portaltan:20170530133735p:plain

absoluteとrelativeの違い(親要素の高さ)

relativeとabsoluteの違いとしてもう1つあげられるのが、親要素の高さの扱いです。

  • relativeの場合はそのまま残る
  • absoluteの場合はなくなる

両方staticの場合、親要素に色をつけて見やすくしてみると

<div style="background-color: blue;">
  <img src="freedom.jpg" />
</div>
<div style="background-color: red;">
  <img src="justice.jpg" />
</div>

f:id:portaltan:20170530155700p:plain

ここから上の要素をrelative、下をabsoluteにすると

<div style="position: relative; background-color: blue;">
  <img src="freedom.jpg" />
</div>
<div style="position: absolute; background-color: red;">
  <img src="justice.jpg" />
</div>

f:id:portaltan:20170530155821p:plain

逆にすると上の要素の高さがなくなり、下のrelativeの要素が基点とする位置がずれて両方の画像が重なってしまいます
わかりやすくabsoluteの方を上になるようにz-indexで調整しています

<div style="position: absolute; background-color: blue; z-index: 2;">
  <img src="freedom.jpg" />
</div>
<div style="position: relative; background-color: red;">
  <img src="justice.jpg" />
</div>

f:id:portaltan:20170530160219p:plain