position : 位置 CSSプロパティ
このページで解説するコードの実行結果。(タイトルの文字列をクリックすると、コードに移動)
left
right
left
right
left
right
left
right
left
right
left
right
HTML & CSSこのページでは、以下のコードをデフォルトとして使用している。
div { border: 2px solid orange; /* 境界線 */ } .parent { padding: 1em; /* 内側の余白 */ } .sample { width: 10em; /* 幅 */ height: 10em; /* 高さ */ opacity: 0.8; /* 半透明 */ border-color: gray; } .sample-1 { background-color: #daa; } .sample-2 { background-color: #ada; width: 8em; } .sample-3 { background-color: #aad; height: 6em; }
<div class="parent"> <div class="sample sample-1"> sample-1 </div> <div class="sample sample-2"> sample-2 </div> <div class="sample sample-3"> sample-3 </div> </div>
positionの概要
要素の位置を指定する。
このページの右下に(スクロールしても消えない)固定されたオレンジ色の要素が浮いていると思うが、これはposition: fixedで表示している。
static : 普通
デフォルト値であり、普通に表示される。(無指定の場合と同じ)
.sample { position: static; }
relative : 相対的
relativeを指定する。 これだけだとstaticと同じ。
.sample { position: relative; }
ここでsample-2クラスにtop: 3em;を設定すると、sample-2クラスは「表示されるべきところ」から相対的に+3em下がる。
(sample-1クラスとsample-3クラスには変化は無い。)
.sample { position: relative; } .sample-2 { top: 3em; }
マイナスを指定すると、上に上がる。
.sample { position: relative; } .sample-2 { top: -3em; }
これはbottomでプラスの値を指定するのと同じ。
.sample { position: relative; } .sample-2 { bottom: 3em; }
left: 3emにすると、右に+3emずれる。
.sample { position: relative; } .sample-2 { left: 3em; }
right: 3emにすると、左に+3emずれる。
.sample { position: relative; } .sample-2 { right: 3em; }
縦横を指定すると斜めにずれる。
.sample { position: relative; } .sample-2 { right: 3em; bottom: 2em; }
.sample { position: relative; } .sample-1 { top: 3em; left: 2em; } .sample-2 { right: 2em; } .sample-3 { bottom: 3em; }
繰り返すが、relativeの基準となる相手は「普通であれば表示される場所」であり、親要素でも上の要素でもない。
なお、重なりが下からsample-1 ⇒ sample-2 ⇒ sample-3になっているが、これを変更するのはz-index。
absolute : 絶対的
とりあえず実践的なTipsとして、position: absolute;の親要素はposition: relative;にしておく(← これ重要)。理由はここ。
absolute の説明には下のコードから始める。
.parentにはpadding: 1emを設定しているので、1em右下にずれている。
.parent { position: relative; width: 10em; height: 10em; border: 2px solid orange; padding: 1em; } .child { background-color: #daa; opacity: 0.5; width: 5em; height: 3em; border: 1px solid red; }
<div class="parent"> <div class="child"> child </div> </div>
まず、子要素のposition: absoluteを設定する。何も変化は無い。
.child { position: absolute; }
0を指定
top: 0;にすると、子要素の上辺が親要素の上辺と一致する。
.child { position: absolute; top: 0; }
bottom: 0;にすると、子要素の下辺が親要素の下辺と一致する。
.child { position: absolute; bottom: 0; }
left: 0;にすると、子要素の左辺が親要素の左辺と一致する。
.child { position: absolute; left: 0; }
right: 0;にすると、子要素の右辺が親要素の右辺と一致する。
.child { position: absolute; right: 0; }
縦横に0を指定すると「角」が一致する。
親要素と子要素の「左上の角」が一致。
.child { position: absolute; top: 0; left: 0; }
親要素と子要素の「右上の角」が一致。
.child { position: absolute; top: 0; right: 0; }
親要素と子要素の「左下の角」が一致。
.child { position: absolute; bottom: 0; left: 0; }
親要素と子要素の「右下の角」が一致。
.child { position: absolute; bottom: 0; right: 0; }
0以外の指定
(復習)top: 0;にすると、childの上辺が親要素の上辺と一致する。
.child { position: absolute; top: 0; }
top: 1em;にすると、childの上辺が親要素の上辺から1em下がる。
.child { position: absolute; top: 1em; }
top: 2em;にすると、2em下がる。
.child { position: absolute; top: 2em; }
マイナス値も指定可能。(上にあがる)
.child { position: absolute; top: -1em; }
.child { position: absolute; top: -2em; }
ここまでは上辺(top)を基準にした結果である。
bottomの場合 : 下辺を基準にする
2em ⇒ 1em ⇒ 0 ⇒ -1em ⇒ -2emと変化させる。
.child { position: absolute; bottom: 2em; }
.child { position: absolute; bottom: 1em; }
.child { position: absolute; bottom: 0; }
.child { position: absolute; bottom: -1em; }
.child { position: absolute; bottom: -2em; }
leftの場合 : 左辺を基準にする
2em ⇒ 1em ⇒ 0 ⇒ -1em ⇒ -2emと変化させる。
.child { position: absolute; left: 2em; }
.child { position: absolute; left: 1em; }
.child { position: absolute; left: 0; }
.child { position: absolute; left: -1em; }
.child { position: absolute; left: -2em; }
rightの場合 : 右辺を基準にする
2em ⇒ 1em ⇒ 0 ⇒ -1em ⇒ -2emと変化させる。
.child { position: absolute; right: 2em; }
.child { position: absolute; right: 1em; }
.child { position: absolute; right: 0; }
.child { position: absolute; right: -1em; }
.child { position: absolute; right: -2em; }
「角」を基準とする
bottom: 3px;とright: 3px;を指定すると「右下の角」が下から3px、右から3pxのところに来る。
.child { position: absolute; bottom: 3px; right: 3px; }
包含ブロック
上記では直接の親要素に対するabsolute(絶対的な位置)を説明してきたが、必ずしも直接の親要素にはならない。
下のような3重の親子関係を考える。
.parents { border: solid orange; padding: 1em; } .gg-parent { border-color: blue; } .g-parent { border-color: green; } .parent { width: 8em; height: 8em; } .child { background-color: #daa; opacity: 0.5; width: 4em; height: 3em; border: 1px solid red; }
<div class="gg-parent parents"> <div class="g-parent parents"> <div class="parent parents"> <div class="child"> child </div> </div> </div> </div>
直接の親要素(.parent)にposition: relative;を設定した場合、.parentの右上の角にchildが移動する。
.parent { position: relative; } .child { position: absolute; top: 0; right: 0; }
position: relative;を祖父要素(.g-parent)や曾祖父要素(.gg-parent)にすると、直接の親要素(.parent)を飛び越えている。
.g-parent { position: relative; } .child { position: absolute; top: 0; right: 0; }
.gg-parent { position: relative; } .child { position: absolute; top: 0; right: 0; }
このように、absoluteの基準となるものを包含ブロックと呼ぶ。
包含ブロックは、「positionでstatic以外を指定された、もっとも近い先祖要素」になる。(繰り返すがstaticはデフォルト値である。)
つまり、absoluteやfixedを指定しても包含ブロックになるのだが、無駄に指定するとややこしくなる。
よって、実践的には「包含ブロックにしたい要素(=absoluteの基準にしたい要素)にposition: relative;を設定する」ということになる。
fixed : 固定
fixed の説明には下のコードから始める。
実行結果にはオレンジ色の要素が見えている。
<div class="fixed"> fixed </div>
これに以下のCSSを追加で設定する。
そうすると、オレンジの要素がブラウザの右下に固定されて表示されているであろう。
(このページに来た時から、ずっと浮いているハズ)
.fixed { position: fixed; bottom: 1em; right: 1em; z-index: 800; }
position: absolute;では包含ブロックに対して絶対的な位置になるように。position: fixed;ではブラウザに対して絶対的な位置になる。
上記コードではbottom:とright:で右下から1emのところに固定しているが、top:やleft:も使える。
これらの指定方法はposition: absolute;と同じであるので省略。
z-index: 800;を指定しているがその説明は下。
top/bottom/left/right
position | 基準 | top | bottom | left | right |
|---|---|---|---|---|---|
static | (なし) | 無効 | 無効 | 無効 | 無効 |
relative | 本来あるべき位置 | ↓(下) | ↑(上) | →(右) | ←(左) |
absolutefixed | 包含ブロック ブラウザ | 上辺から ↓(下) | 下辺から ↑ (上) | 左辺から →(右) | 右辺から ←(左) |
relative の場合
下のコードから始める。真ん中が「本来あるべき位置」。
div { border: 1px solid gray; } .parent { border-color: orange; border-width: 2px; padding: 4em; } .child { position: relative; background-color: #daa; width: 3em; height: 2em; border-color: red; }
<div class="parent"> <div class="child" > child </div> </div>
top/bottom/left/right を指定してみる。
.child { top: 3em; }
.child { bottom: 3em; }
.child { left: 3em; }
.child { right: 3em; }
縦と横を指定すると、斜めに移動する。
.child { top: 3em; left: 3em; }
.child { top: 3em; right: 3em; }
.child { bottom: 3em; left: 3em; }
.child { bottom: 3em; right: 3em; }
absolute/fixed の場合
下のコードから始める。
div { border: 1px solid gray; } .parent { position: relative; border-color: orange; border-width: 2px; padding: 11em; } .children { background-color: #daa; opacity: 0.7; width: 4em; height: 4em; border-color: red; }
<div class="parent"> <div class="children" > child </div> <div class="children top" > top </div> <div class="children bottom" > bottom </div> <div class="children left" > left </div> <div class="children right" > right </div> <div class="children top-left" > top<br>left </div> <div class="children top-right" > top<br>right </div> <div class="children bottom-left" > bottom<br>left </div> <div class="children bottom-right" > bottom<br>right </div> </div>
left
right
left
right
子要素にposition: absolute;を指定すると、全ての子要素は重なる。
(子要素の左上の角が親要素の中心に来ている(← つまり、子要素が中心から外れている)。これはabsoluteになると親要素は子要素が存在しないものとして配置されるため。)
.children { position: absolute; }
left
right
left
right
0にすると、それぞれの角と辺に張り付く。
.children { position: absolute; } .top { top: 0; } .bottom { bottom: 0; } .left { left: 0; } .right { right: 0; } .top-left { top: 0; left: 0; } .top-right { top: 0; right: 0; } .bottom-left { bottom: 0; left: 0; } .bottom-right { bottom: 0; right: 0; }
left
right
left
right
正の値を設定すると、(包含ブロックの)内側に移動する。
.children { position: absolute; } .top { top: 2em; } .bottom { bottom: 2em; } .left { left: 2em; } .right { right: 2em; } .top-left { top: 2em; left: 2em; } .top-right { top: 2em; right: 2em; } .bottom-left { bottom: 2em; left: 2em; } .bottom-right { bottom: 2em; right: 2em; }
left
right
left
right
負の値を設定すると、(包含ブロックの)外側に移動する。
.children { position: absolute; } .top { top: -1em; } .bottom { bottom: -1em; } .left { left: -1em; } .right { right: -1em; } .top-left { top: -1em; left: -1em; } .top-right { top: -1em; right: -1em; } .bottom-left { bottom: -1em; left: -1em; } .bottom-right { bottom: -1em; right: -1em; }
left
right
left
right
まとめると、
| 正の値 | 内側に移動 |
| 負の値 | 外側に移動 |
fixedは(包含ブロックではなく)ブラウザになることだけが異なる。
z-index : 重なりの順番
重なりの上下関係は後で指定されたものが上になるので、下からsample-1 ⇒ sample-2 ⇒ sample-3の重なりになっている。
.sample { position: relative; opacity: 1; } .sample-1 { top: 7em; left: 2em; } .sample-2 { right: 2em; } .sample-3 { bottom: 4em; }
<div class="parent"> <div class="sample sample-1"> sample-1 </div> <div class="sample sample-2"> sample-2 </div> <div class="sample sample-3"> sample-3 </div> </div>
これを変更するにはz-indexプロパティを指定する。
デフォルトは0であり、大きな数字ほど、上に重ねられる。
とりあえず、.sample-2のz-indexを700にすると、sample-2が最前面に出る。
.sample-2 { z-index: 700; }
.sample-1をz-index: 710にする。(sample-1が最前面)
.sample-1 { z-index: 710; } .sample-2 { z-index: 700; }
.sample-3をz-index: 720にする。(sample-3が最前面)
.sample-1 { z-index: 710; } .sample-2 { z-index: 700; } .sample-3 { z-index: 720; }
Emmet : pos
| 記述 | Visual Studio Code |
|---|---|
pos | position: relative; |
posa | position: absolute; |
posf | position: fixed; |
t | top: ; |
b | bottom: ; |
l | left: ; |
r | right: ; |
z | z-index: ; |