LoginSignup
3
5

More than 3 years have passed since last update.

CSSレイアウトの基本のき。absolute, fixed, sticky, relativeについて。

Last updated at Posted at 2019-08-08

absolute, fixed, sticky, relativeの奥深さ

それぞれ概ね以下のように理解している人は多いと思います
- fixed: 画面を基準とした配置
- absolute: 親要素を?基準とした絶対位置
- relative: 親要素からの相対位置(???)
- sticky: 画面にひっついてくる

しかし、このように理解していても、postion: abosluteや、position: fixedを行うとすぐにレイアウトが崩れてしまい訳が分からなくなるという人は多いのではないでしょうか。

なぜそのような事が起きるかというと、absolute.sitcky,fixed,relativeなどを設定した要素に適用されるPositioned要素という概念と、Positioned要素の基準位置となるContaining Block、そしてPositioned要素の親要素のサイズ計算への影響について正しく理解していないためです。

少し難しいですが、Positioned 要素とContaining Block,そしてPositioned要素のサイズ計算について確認していきましょう。

Positioned Element(要素)

Positioned要素とは、HTMLの通常の配置フローから外れる要素です。
absoluteなどを利用するとPositioned要素となり、他の配置フローとは異なった考え方をする必要が出てきます。
どのような場合にPositioned ELementとなるのかは正確に把握しましょう。

Positioned要素に該当する要素

positionプロパティーが以下の値の時、要素はPositioned要素となります。
- fixed
- absolute
- relative
- sticky
Positioned要素でないのはデフォルトのstaticだけです。
それ以外の場合は通常の配置フローと異なった考え方をする必要があります。

Containing Block

Positioned要素の配置フローの基準位置となる場所(仮想の箱)が「Containing Block」です。
それぞれのPositioned要素ごとに、どこがContaining Blockとなるかは異なります。
Containing Blockを正しく把握しない事が混乱の元なので、正確に把握する必要があるでしょう。

それぞれのContaining Block

それぞれのpositionプロパティーに対応するContaining Blockがどれかは以下の通りです。

relative, staticの場合

この二つは通常通りの場所が基準となります。直近の親要素の上部(手前に兄弟要素がある場合、その要素を除いた部分)がContaining Blockとなります。

relativeがstaticと違うのは以下の2点です。
- 1.topやleftなどの値を設定できる。基準位置はContaining Block
- 2.子要素のPositioned要素のContaining Blockとして基準位置となる

2の特徴は特に重要で、relative要素は自身の配置をずらす目的よりも、absoluteの子要素の位置を調整するために使う事の方が多いように思います。

stickyの場合

stickyは非常に紛らわしいのですが、こちらもrelative,staticと同様、直近の親要素がContaining Blockとなり、通常の配置フローにしたがって配置されます。

しかし、topなどの基準位置は、直近の親要素のうち,overflowが「hidden,autoもしくはscroll」となっているものとなり、親要素のoverflowがvisible(default)となっているとstickyは機能しなくなります。** overlowが設定されている要素が存在しない場合はviewportが基準**となります。

かなり複雑ですが、relativeとfixedの両方の要素+アルファの性質があるといった感じです。

例えば以下の場合、id=3divid=1の上から50pxの距離を取るように配置されます。
id=1の上枠から50pxに引っかかるように挙動し、id=2(container block。Container Blockと固定の基準位置は異なる)の下枠にぶつかるまで画面にくっついてきます。

example.html
<div id="1" style="position: overflow: hidden;">
  <div id="2">
    <div  id="3" style="position: fixed; top: 50px;"></div>
  </div>
</div>

画面の枠が基準となると理解している人も多いように思いますが、違うパターンになることも非常に多いです。

absoluteの場合

absoluteの場合、直近の親のPositioned要素がContaining Blockです。
例えば以下の場合、id=3divの基準となるのは、2個上の親である id=1divです。
id=1のdivの上の枠から50pxの位置に配置されます。

id=1のpositionがrelativeabsolute, fixedでも同様の結果となります。

example.html
<div id="1" style="position: fixed">
  <div id="2">
    <div  id="3" style="position: absolute; top: 50px;"></div>
  </div>
</div>

fixedの場合

Viewport(ブラウザの枠)が基準となります。
下の場合、id=1やid=2の要素は無視され、ブラウザの上の枠から50pxの位置に配置されます。

example.html
<div id="1" style="position: relative">
  <div id="2">
    <div  id="3" style="position: fixed; top: 50px;"></div>
  </div>
</div>

Positioned要素の親要素のサイズの計算

HTMLにおいて、親要素のwidth, heightは指定しなければ内側の要素のサイズを計算してボトムアップ式に決定されます。しかし、子要素がabsolute, もしくはfixedの場合は親要素のサイズに影響を与えません。

まとめ

以上をまとめると以下のようになります。

position Positioned Container Block 親要素のサイズ計算に含むか
static × 親要素 含む
relative 親要素 含む
sticky 親要素: 固定の基準位置はviewport(もしくは直近のoverflowが設定された親要素) 含む
fixed viewport 含まない
absolute 親のPositioned要素 含まない

CSSがうまく機能しない理由の大半はこのへんの理解が深まれば解消するのではないかと思います。

しかし、ここまででも十分複雑ですがここにも記述しきれなかった例外規則なども多数あります。
困った時はちゃんとドキュメントに当たるようにしましょう。

参考

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5