1. HTML/CSS 入門講座
  2. positionを理解しよう【CSS】

positionを理解しよう【CSS】

今回は、positionプロパティについて解説します。

positionは、要素をどのように配置するかを設定するプロパティです。

static

positionのデフォルト値はstaticです。

index.htmlを以下のように書き換えてください。

index.html
<!-- 省略 -->
<body>
    <div class="container">
        <div class="box1"></div>
        <div class="box2"></div>
    </div>
</body>
<!-- 省略 -->

次に、style.cssを以下のように書き換えてください。

style.css
.container {
    background-color: #ddd;
    height: 100px;
}
.box1 {
    position: static;
    background-color: #000;
    width: 30px;
    height: 30px;
}
.box2 {
    background-color: #aaa;
    width: 30px;
    height: 30px;
}

次に、要素の位置を決めるtop、leftプロパティを設定してみます。

style.css
.container {
    background-color: #ddd;
    height: 100px;
}
.box1 {
    position: static;
    background-color: #000;
    width: 30px;
    height: 30px;
    left: 10px;
    top: 10px;
}
.box2 {
    background-color: #aaa;
    width: 30px;
    height: 30px;
}

staticを指定している要素にtop、bottom、left、rightは効果がありません(staticがデフォルトなので何も指定していない場合もstaticになります)。

また、後ほど説明するz-indexプロパティも効果がありません。

relative

次に、relativeを指定した場合にどのように変化するかをみていきます。

style.cssのpositionをrelativeに変更してください。

style.css
.container {
    background-color: #ddd;
    height: 100px;
}
.box1 {
    position: relative;
    background-color: #000;
    width: 30px;
    height: 30px;
    left: 10px;
    top: 10px;
}
.box2 {
    background-color: #aaa;
    width: 30px;
    height: 30px;
}

box1クラス要素の位置が変わりました。

relativeを指定すると、元々あった位置を基準にtop、bottom、left、rightの指定値分移動します。

上記のコードでは、左から10px、上から10px移動しています。

次に、要素が重なり順を変えてみます。

style.css
.container {
    background-color: #ddd;
    height: 100px;
}
.box1 {
    position: relative;
    background-color: #000;
    width: 30px;
    height: 30px;
    left: 10px;
    top: 10px;
    z-index: 1;
}
.box2 {
    position: relative;
    background-color: #aaa;
    width: 30px;
    height: 30px;
    z-index: 2;
}

box1とbox2両方にposition:relativeを指定し、z-indexを追加しました。

表示を確認すると、box2が上に重なるように変化しました。

z-indexは要素の重なりを決めるプロパティです。数値が大きい方が

positionにstatic以外の値を入れると、重なり順を決めることができます。

absolute

次に、absoluteの動作を動作を見ていきます。

index.htmlを以下のように書き換えてください。

index.html
<!-- 省略 -->
<body>
    <div class="container1"></div>
    <div class="container2">
        <div class="box1"></div>
        <div class="box2"></div>
    </div>
</body>
<!-- 省略 -->

style.cssは以下のように書き換えてください。

style.css
.container1 {
    background-color: #f0f0f0;
    height: 100px;
}
.container2 {
    background-color: #ddd;
    height: 100px;
}
.box1 {
    position: relative;
    background-color: #000;
    width: 30px;
    height: 30px;
    z-index: 2;
}
.box2 {
    position: relative;
    background-color: #aaa;
    width: 30px;
    height: 30px;
    z-index: 1;
}

一度保存してブラウザの表示を確認してください。

次に、style.cssを以下のように書き換えます。

style.css
.container1 {
    background-color: #f0f0f0;
    height: 100px;
}
.container2 {
    position: relative;
    background-color: #ddd;
    height: 100px;
}
.box1 {
    position: absolute;
    background-color: #000;
    width: 30px;
    height: 30px;
    right: 10px;
    bottom: 10px;
    z-index: 2;
}
.box2 {
    position: relative;
    background-color: #aaa;
    width: 30px;
    height: 30px;
    z-index: 1;
}

box1クラスの要素は親要素(container2クラスの要素)を基準に右から10px、下から10pxの位置に移動しました。

このように、absoluteを指定した要素は、relativeやabsoluteなどstatic以外を指定した一番近い親要素を基準とした位置に配置されます。

では、親要素にpositionの指定がない場合はどのようのに振る舞うでしょうか。

以下のように、.container2のposition: relativeを削除し、.box1の位置をright: 0、top: 0に変更してみましょう。

style.css
.container1 {
    background-color: #f0f0f0;
    height: 100px;
}
.container2 {
    background-color: #ddd;
    height: 100px;
}
.box1 {
    position: absolute;
    background-color: #000;
    width: 30px;
    height: 30px;
    right: 0;
    top: 0;
    z-index: 2;
}
.box2 {
    position: relative;
    background-color: #aaa;
    width: 30px;
    height: 30px;
    z-index: 1;
}

ウィンドウの右上に移動しました。

親要素にstatic以外の指定がされていない場合、ブラウザウィンドウを基準に配置されます。

そして、box2クラスの要素はbox1があった位置になりました。

absoluteを指定すると、浮いているような状態になり、後に続く要素は詰めて表示されます。

fixed

position:fixedを指定した場合の動作を確認していきます。

index.htmlを以下のように書き換えてください。

index.html
<!-- 省略 -->
<body>
    <div class="container1">
        <h1>サイトタイトル</h1>
    </div>
    <div class="container2"></div>
</body>
<!-- 省略 -->

style.cssは以下のように書き換えてください。

style.css
.container2 {
    background-color: #ddd;
    height: 5000px;
}

fixedはスクロールしないと挙動が分かりづらいため、スクロールできるようにcontainer2クラスの要素縦に長くしました。

fixedなしの状態を確認するために、一度ブラウザの表示を見てください。

次に、style.cssにコードを追加します。

style.css
.container1 {
    position: fixed;
    left: 0;
    top: 0;
}
.container2 {
    background-color: #ddd;
    height: 5000px;
}

ブラウザの表示を確認してください。スクロールしてみると、container1クラスの要素がウィンドウの左上に固定されて追従します。

fixedを指定すると、ウィンドウを基準に位置が決まります。

また、fixedを指定したcontainer1クラスの要素は浮いたような状態になり、後続のcontainer2クラスの要素は詰めて表示されています。

sticky

stickyを指定した時の挙動を確認していきます。

index.htmlを以下のように書き換えてください。

index.html
<!-- 省略 -->
<body>
    <div class="container1">
        <h1>サイトタイトル</h1>
    </div>
    <div class="container2">
        <div class="box">
            <p>テキスト</p>
        </div>
    </div>
    <div class="container3"></div>
</body>
<!-- 省略 -->

次に、style.cssを以下のように書き換えてください。

style.css
.container1 {
    background-color: #f0f0f0;
    height: 300px;
}
.container2 {
    background-color: #ddd;
    height: 1000px;
}
.container3 {
    background-color: #ccc;
    height: 1000px;
}

一度position:stickyを指定する前の表示を確認してください。

boxクラスにposition: stickyを指定してみます。

style.css
.container1 {
    background-color: #f0f0f0;
    height: 300px;
}
.container2 {
    background-color: #ddd;
    height: 1000px;
}
.container3 {
    background-color: #ccc;
    height: 1000px;
}
.box {
    position: sticky;
    top: 0;
}

スクロールして挙動を確認してみてください。

boxクラスの要素がウィンドウの上になる位置を超えてスクロールすると追従表示されます。

そして、boxクラスの要素が親要素の下まで来たところで追従が止まります。

このように親要素の範囲内でスクロール追従したい時には、stickyを使います。

注意点として、祖先要素にoverflow: hiddenが指定されると、stickyは効かなくなります。

overflowは、はみ出た要素をどのように表示するかを決めるプロパティで、hiddenにするとはみ出た要素を隠すようになります。

style.css
.container1 {
    background-color: #f0f0f0;
    height: 300px;
}
.container2 {
    background-color: #ddd;
    height: 1000px;
    overflow: hidden;
}
.container3 {
    background-color: #ccc;
    height: 1000px;
}
.box {
    position: sticky;
    top: 0;
}

このように、親要素であるcontainer2クラスの要素にoverflow:hiddenを指定するとスクロール追従されなくなります。

もし親要素にoverflow:hiddenを指定したい場合は、代わりにoverflow:clipを使用してください。

clipはhiddenと同じようにはみ出た要素を隠し、子孫要素でposition: stickyがちゃんと動作します。