CSSのposition属性を覚える

前置き

  • 数多のCSSerが説明を試みたこの登竜門(?)
  • absolute = 絶対、原点、relative = 相対、自身との比較、自省、...のような感じで妄想を膨らませる

イメージ

ある親子がラーメン店を営んでいる。
現在は父親が店主を務めており、子は修行中である。

先祖代々伝わる秘伝のスープが旨いと雑誌で取り上げられることは何度かあったが、
最近は客足が減ってきてしまっていた。
どうも最近、店主である父親の腕が落ちてきているらしい。

店の状況を見て、子は焦った。
このままでは親父と道連れになってしまう。
今はまだ修行中の身だが、何とかして味が落ちてしまった店のスープを生き返らせたい。

この場合、子が取れる行動は2つ。
ひとつは、自分の腕を上げ独立することで先祖代々伝わるスープの味を再現する、つまり世代を超えて原点回帰する方法。
もうひとつは、父親にもう一度研鑽を促し、親子二人で切磋琢磨しながら店を続けていく方法。

始めの状態 (親が店主)

<body style="border:1px solid lightgray;">
    <div class="parent">
        親のスープ
        <div class="child">子のスープ</div>
    </div>
</body>
/* 親 */
.parent {
    background-color: #ff7f50;    /* coral */
}

/* 子 */
.child {
    background-color: #ff4500;    /* orangered */
}

f:id:zdassen:20180627115941j:plain

子、焦る (親がrelative)

子が焦る。なぜかというと親父の腕が落ちて道連れになってしまうかもしれないから。子は入れ子な存在であり、修業中の身であるから、親父の味が落ちると道連れになる。

.parent {

    /* 親父の腕が落ちた ( ズレる方向に意味はない.. ) */
    position: relative;
    top: 30px;
    left: 30px;
}

.child { /* position 指定なし */ }

f:id:zdassen:20180627121551j:plain

子が修行に励む (子のみrelative)

子が(焦って)修行に励む。取りあえず昨日の自分のスープの味を、今日超えるしかない。昨日の自分の味に対して今日の自分の味はどうか。過去の(?)自分自身が基準な状態。position: relativeとすると、本来の自分自身が描画されるべき位置からの相対位置となる。他者と比較するのはまだ早い、修業中の身。relativeというのは自分との比較。あくまで自分の位置を決める際に登場人物となるのは、自分だけ(親父の腕前が(昔の親父に比べて)落ちたり、子が(昔の子自身と比べて)成長したり)。ちなみに、子はまだ修行中なので親の店にまだ居場所となるスペースがある。

.parent {
    /*
    position: relative;
    top: 30px;
    left: 30px;
    */
}

.child {
    position: relative;
    top: 30px;    /* 昨日の自分より成長した度合い */
    left: 30px;    /* 昨日の自分より成長した度合い */
}

f:id:zdassen:20180627120741j:plain

子、独立する (初めのほう) *1

子が独立する。もう親父に守ってもらうことはできない。代わりに先々代の味を復活させてやる。親父や昨日の自分の味ではなくて、この店が始まった時の味ってどんなだったのだろう。が、始めのうちはそんなにうまくいかない。昨日今日で人間、そんなに成長しない。position: absoluteとなったので、親の影響を受けない。が他に何も指定しなければtop: auto、left: autoとなり位置は変わらない。

.parent {
    /* 親はrelativeしない = サボっている */
    /*
    position: relative;
    top: 30px;
    left: 30px;
    */
}

.child {
    position: absolute;
    /*
    何も指定しなければ
    top: auto;
    left: auto;
    となっている
    */
}

f:id:zdassen:20180627132259j:plain

子、独立する (軌道に乗ってくる)

段々と、先々代の味が再現できるようになってくる。

.parent { /* 上記のまま */ }

.child {
    /* 原点回帰? */
    position: absolute;
    top: 0px;
    left: 0px;
}

f:id:zdassen:20180627132511j:plain

新展開 (親が反省する)

独立して秘伝の味を取り戻した子が雑誌に取り上げられている。
親は反省する。自省=relativeだった(オレオレ定義)。父親は自分のスープの味を見直すようになる。
独立したはずの子は父親のそんな姿を見て、父親の店に戻る決心をする。
子はあの時の独立心を保ち続けたまま、元の店に戻る。子の独立心が旺盛だとしても、父親は自らを省みることによって、子の基準(手本?)となれるのである

.parent {
    /* 親父、反省する */
    position: relative;
}

.child {
    /* 親父の味をベースにしたっていいじゃないか */
    position: absolute;
    top: 0px;
    left: 0px;
}

f:id:zdassen:20180627133728j:plain

ややこしい点

  • 子が"absolute"な場合でも、実際には親のposition属性値が影響する
  • なんか"absolute"っぽくない(字面が直観に反する)
  • 入れ子になっている場合、親を移動させると子も道連れになるので子の基準点も移動している(そこからさらに子のposition: relativeなどとやると...)

サブストーリー (親父の親父もズレてた)

(この例において)そもそも親父の味がここにあるのは、
親父の親父(つまり子からみた先々代)がbody要素で、
f:id:zdassen:20180627142158j:plain
body要素にはデフォルトでmarginが設定されているから。
つまり親父がベースにしている先々代の味は店の原点と呼べるものではなかった(何代続いてんだよ)。しかし、子が独立したときに追い求めた原点の味は正しい。先々代を原点回帰させるにはbody要素のmarginを0にする必要がある(p要素などにも当然それ自体にマージンが設定されている)。

※手を動かして試す場合のややこしさの原因となるので一応触れておいた

結論

親父の親父と親父のせい

*1:※180729追記..冒頭で親父の味が落ちる→relativeを使用↔親父がサボる→relativeしない、に意味が変わっている点はカンベンしてください。あくまでイメージを利用して動作を覚えることを目的としたものです