In 'n' Out

知識を取り込み、そして発信する

CSSで要素の配置をコントロールする

要素の配置制御

positionは、要素を「どこに配置するか」を決めるためのCSSプロパティです。
marginやpaddingが要素同士の間隔を調整するのに対し、positionは要素を画面上の座標で配置します。
これにより、要素の重なり順や固定表示、スクロールに追随する表示などが可能になります。

位置指定プロパティ

位置指定プロパティは、指定した方向を基準として、要素をどれだけ移動させるかを決定します。

構文

セレクタ{
    top:値;
    right:値;
    bottom:値;
    left:値;
}

positionと組み合わせて初めて意味を持つため、単体では意味がありません。
なお、負の値も指定できます。

position

positionを指定すると、要素の配置方法や配置基準が決まります。
あわせて、topやleftなどの位置指定プロパティが有効になるかどうかも、この指定によって決まります。

構文

セレクタ{
    position:"値";
}

これらはセットで考える必要があり、positionだけを指定しても見た目が変わらない場合があります。
positionには複数の値がありますが、それぞれ役割がはっきり分かれています。

relative

relativeは、元の配置位置を基準にして要素をずらすための指定です。

構文

セレクタ{
    position:relative;
}

relativeを指定しても元の位置は保持されます。
下記サンプルで、子要素のみが移動し、周囲の要素は影響を受けないことを確認できます

コード例

<div id="parent">
	<div class="relative">
		<p>positionは初期状態です</p>
		<p>段落です。</p>
	</div>
</div>
#parent {
    width: 300px;
    border: 1px solid #000000;
    box-sizing: border-box;
    position: relative;
}

#parent > p:first-child {
    width: 200px;
    height: 100px;
    background-color: #fbfab099;
    margin: 0;
    position: relative;
    top: 50px;
    left: 50px;
}

#parent > p:nth-child(2) {
    width: 200px;
    height: 40px;
    background-color: #ff000099;
    margin: 0;
}

出力例

子要素にrelativeを指定して、上から50px、左から50pxと指定すると子要素のみが移動します。
周囲の要素の配置には影響を与えておらず、次の段落の位置は元の位置のままです。
これが「要素があった場所は保持」されているということです。
ただ、このような使い方はあまり直面することはなく、relative自体でtop・leftを動かすケースは少なく、子のabsolute配置の基準として使われることが多いです。

absolute

absoluteは、基準となる要素をもとに自由な位置に配置する指定です。

構文

セレクタ{
    position:absolute;
}

absoluteが参照する基準は、直近のpositionが指定されたrelative要素です。
そのような祖先要素が存在しない場合は、初期包含ブロック(通常は画面表示領域)を基準に配置されます。
absoluteを指定した要素は、通常のレイアウトの流れから外れるため、他の要素と重なって表示されることがあります。
なお、relativeの指定はabsoluteを有効にするための必須条件ではなく、配置の基準を特定の要素に限定したい場合にのみ必要です。

コード例

<div id="parent">
	<div class="relative">
		<p>positionは初期状態です</p>
		<p>段落です。</p>
	</div>
</div>
#parent {
    width: 300px;
    border: 1px solid #000000;
    box-sizing: border-box;
    position: relative;
}

#parent > p:first-child {
    width: 200px;
    height: 100px;
    background-color: #fbfab099;
    margin: 0;
    position: absolute;
    top: 50px;
    left: 50px;
}

#parent > p:nth-child(2) {
    width: 200px;
    height: 40px;
    background-color: #ff000099;
    margin: 0;
}

出力例

親要素に対し、子要素が上から50px、左から50pxと指定すると子要素のみが移動しました。
relativeとは異なり、次の段落の位置が元の位置からずれて表示されます。
このようにabsoluteを指定した要素は基準となるrelative要素に対して絶対配置になります。

fixed

fixedは、画面そのものを基準にして要素を固定表示する指定です。

構文

セレクタ{
    position:fixed;
}

スクロールを行っても要素の位置は変わらず、常に同じ場所に表示されます。

コード例

<div id="parent">
	<div class="relative">
		<p>positionは初期状態です</p>
		<p>段落です。</p>
	</div>
</div>
#parent {
    width: 300px;
    height: 700px;
    border: 1px solid #000000;
    box-sizing: border-box;
    position: relative;
}

#parent > p:first-child {
    width: 200px;
    height: 100px;
    background-color: #fbfab099;
    margin: 0;
    position: fixed;
    top: 50px;
    left: 50px;
}

#parent > p:nth-child(2) {
    width: 200px;
    height: 40px;
    background-color: #ff000099;
    margin: 0;
}

出力例

親要素に対し、子要素が上から50px、左から50pxと指定すると子要素のみが移動し、次の段落が元の位置からずれて表示されます。
ここまではabsoluteと同じですが、fixedを指定した要素はスクロールをすると追随してきます。
ヘッダーや追従ボタンなど、常に表示しておきたい要素に使われます。

sticky

stickyは、通常時はrelativeのように配置され、一定の位置に達するとfixedのように振る舞います。

構文

セレクタ{
    position:sticky;
}

スクロールに応じて動作が切り替わるのが特徴で、親要素の範囲内でのみ効果を持ちます。
また、topなどの位置指定がないと正しく動作しません。

コード例

<div id="parent">
	<div class="relative">
		<p>positionは初期状態です</p>
		<p>段落です。</p>
	</div>
    <p>親子内ではない要素の段落です。</p>
</div>
#parent {
    width: 300px;
    height: 700px;
    border: 1px solid #000000;
    box-sizing: border-box;
    position: relative;
}

#parent > p:first-child {
    width: 200px;
    height: 100px;
    background-color: #fbfab099;
    margin: 0;
    position: sticky;
    top: 50px;
    left: 50px;
}

#parent > p:nth-child(2) {
    width: 200px;
    height: 40px;
    background-color: #ff000099;
    margin: 0;
}

p{
    background-color: aliceblue;
    width: 250px;
    height: 280px;
}

出力例

見た目はfixedと同じに見えますが、スクロールしてみると途中まで追随し、親要素の終わりになると追随しなくなります。
つまり、親要素の範囲でのみ追随を行い、親要素の範囲内でのみ固定されます。

static

staticはすべての要素の初期状態です。
HTMLの通常の流れに従って配置され、上から下へ、左から右へと並びます。

構文

セレクタ{
    position:static;
}

この状態ではtopやleftを指定しても効果はありません。
positionを指定していない場合と同じ挙動になります。
なお、各プロパティを適用後のリセットボタンを押すと見え方が確認できます。

要素の重なり順をコントロールする

z-indexは、要素同士が重なったときに、どの要素を手前に表示するかを決めるためのプロパティです。

構文

セレクタ{
    z-index:値;
}

positionが要素の配置場所を制御するのに対し、z-indexは奥行き方向の表示順を制御します。

コード例

<div id="parent">
	<p>z-index(1)</p>
	<p>z-index(2)</p>
	<p>z-index(3)</p>
</div>
#parent {
    width: 300px;
    box-sizing: border-box;
    position: relative;
}

#parent p{
    width: 200px;
    height: 100px;
    margin: 0;
    position: absolute;
}

#parent p:nth-child(1){
    background-color: #ff0000;
    top: 0;
    left: 0;
}

#parent p:nth-child(2) {
    background-color: #ffff00;
    top: 30px;
    left: 50px;
}

#parent p:nth-child(3) {
    background-color: #ff00ff;
    top: 60px;
    left: 100px;
}

出力例

入力欄に数字を入れると、重なり順が変わります。 z-indexには数値を指定し、数値が大きいほど、要素は手前に表示されます。