【CSS】positionプロパティを使いこなす!relative・abosolute・fixedの使い方

「CSSのpositionってどう使っていいかわからない。」
「スマホで見たときにレイアウトが崩れていた。正直、CSSのpositionは使いづらい」

これは始めたばかりの人にとっては自然な印象です。どのサイトにも、「使用頻度が高く、便利なので、使えるようになれ」と書いてある割に、どの場面で使えばいいのか、検討がつかず、また、慣れるまで時間がかかります。

ですが、安心してください。一旦、これから説明する内容を自分でも手を動かして確かめてください。挙動の違いやポイントが大まかにつかめればしめたものです。習得に時間がかかることは確かですが、最初に正しい理解をしておけば、その後のハードルが一気に下がります。恐れずに始めましょう。

CSSのpositionとは?

「position」は、CSSで使うプロパティの一つです。特に要素の「配置」を決めるのが「position」の役割です。基本的な使い方として、以下のように書きます。

.要素セレクタ{
  position: static/relative/absolute/fixed/stickyをここに配置する。;
}

ここで、英語のカタカナ表記に苦手意識を持つ人もいるかもしれませんね。そこで、簡単におさらいしておきましょう。プロパティとは、以下のCSSの要素を指します。

「配置」を決めるプロパティ

ところで「配置」を決めるプロパティは、「position」だけではありません。今回は「position」を説明しますが、「position」以外にも「floatプロパティ」や「displayプロパティ」があることを知っておいてください。デザインの目的に沿って使い分ける必要があります。

メリット デメリット
positionプロパティ 配置の細かな指定に向いている。要素を重ねたりする場合には特に向いている。 画面サイズの変更による調整が難しい。設計に失敗すると画面の大きさの違いにより要素同士が重なることもある。
floatプロパティ 横並びなど単純なレイアウト作成、小さな変更などに向いている。要素の重なりなどの心配はない。 レイアウトやページの構成に影響する複雑な配置には向かない。
displayプロパティ 横並び、縦並びなど単純なレイアウト作成、小さな変更などに向いている。floatに比べて、様々な値のオプションが用意されており、使用の幅がある。 複雑な配置には向かない。

「position」で取れる値の種類

「position」を理解する上で、以下の区別は重要です。まず、「position」は、何もしなければ、「static」という値をとりますが、これは、位置の指定ができない値です。「position」という割に、何もできない値もあることは覚えておいてください。つまり、実務上は、特別な理由がない限り、「static」以外の値を取ります。

 

位置指定の有無 区別
位置指定無効 static
位置指定有効 相対配置 relative
絶対配置 absolute
fixed
sticky

値の特徴

「position」の理解をややこしくするのは、値が多様であり、その値ごとに特徴を正確に把握していないと、思い通りの挙動にならない点です。そこで、「relative」と「absolute」はよく使うプロパティですので、全部は無理という方は、最低限、ここだけ読んでおいてください。この場合、positionでは、「配置の種類(相対か絶対か)」と「どの程度距離をとるか」の2つを考えます。まず、以下は「配置の種類」です。

特徴 説明
static 位置指定ができない。 top,right,bottom,left,z-indexgが使えない。位置を変えたいときはrelativeやabsoluteにしなければならない。
relative 現在の位置を起点に要素の位置が動く。 relativeの指定だけではなく、同時に、この時、top、right bottom、leftという値も指定する。つまり、値の組み合わせで配置を行うことに注意する。
absolute 最も近い「relative」(親や先祖の要素)を起点に要素の位置が動く。 absoluteだけでは具体的な位置が指定できないため、「relatvie」同様にtop、bottom、left、rightプロパティを指定する。relativeを指定していなければ起点はページ全体となる。
fixed 基準位置は常にブラウザウィンドウ領域(一旦はbody要素と考える) どこかの要素が基準にはならない。relativeと同様に、top、bottom、left、rightプロパティが使われる。navbarやmenuバーなど常に画面に固定したいものがある場合に使う。
sticky スクロールに応じて要素を固定する。 指定した値を超えるまではrelative、その後はfixedの特徴となる。位置や重なり順の指定も可能。

positionプロパティと一緒に使う位置指定のプロパティ「top」「right」「bottom」「left」

次に、「どの程度距離をとるか」ですが、左右上下で距離の設定ができます。

top 基準となる位置の上からの距離を指定する。
right 基準となる位置の右からの距離を指定する。
bottom 基準となる位置の下からの距離を指定する。
left 基準となる位置の左からの距離を指定する。

以下が起点から指定する値のイメージです。

例えば、以下のように、起点から計算して、上(top)から10px、右(right)から50px、左(left)から10px、下(bottom)から30pxの地点に要素を表示したい時は、以下のように書きます。

.要素セレクタ {
   position: relative or absolute;
   top: 10px;
   left: 10px;
}

rightやbottomは指定していません。これは、指定してもいいのですが、rightに対してleftがbottomに対してtopが優先されるためです。基本的に、ほとんどの場合にleftとright、またはtopとbottomを同時に指定することはないことは覚えておいてください。

positionの値の使い方

では、ここでは、頻度高く使われる以下の要素の基本的な使い方を説明します。「多い」と思った方は、まずは使用頻度が高い最初の2つをマスターするようにしてください。

  1. relative
  2. absolute
  3. fixed
  4. sticky

 

relative

「position: relative;」は、起点として「現在の表示位置」をとります。これは、positionを設定しない場合に表示される位置と理解してください。そこからどれらだけの距離に配置するかを設定するのが、この「relative」の役割です。

例えば、HTMLで以下のように書いてみましょう。

<div class="container">
    <div class="main-box">
    	<div class="sample-box"></div>
    </div>
</div>

次に、CSSで次のように指定します。

.main-box{
    background: #fde8d0;
    width: 300px;
    height: 300px;
}

.sample-box{
    color: #ffffff;
    background: #ee827c;
    text-align: center;
    width: 300px;
    height: 300px;
}

すると、以下のように表示されるはずです。要素が重なって表示されていることがわかります。

検証ツールで、確認します。

やはり、「sample-box」は親要素の「main-box」と重なって配置されています。

ここが起点ということです。では、ここから配置を指定します。CSSで次のように「positionプロパティ」を追加し、指定しました。topとleftにそれぞれ50pxの距離をとった配置です。

.sample-box{
    position: relative;
    top: 50px;
    left: 50px;

    color: #ffffff;
    background: #ee827c;
    text-align: center;
    width: 300px;
    height: 300px;
}

すると、起点に対して50pxほど上と左から距離がとられたことがわかります。

このように、要素の表示位置から距離をとる場合は「relative」がよいでしょう。しかし、実際にはそのケースだけではありません。配置の起点をもっと柔軟に設定したいという時も多いのです。その時こそ「absolute」の出番です。

absolute

「absolute」では、起点を任意に設定することができます。例えば、以下のようなHTMLを書きます。そして、起点を「starting-point」とします。

<div class="container">
  <div class="starting-point">
     <div class="main-box">
         <div class="sample-box"></div>
     </div>
  </div>
</div>

 

この場合、CSSには、以下のように書きます。「starting-point」に「relative」を設定することで、ここを「起点」と宣言します。次に、起点に対して配置する要素に対して「absolute」を設定します。今回は、top:50px, left: 50pxを設定しています。

.starting-point{
    position: relative;
    width: 300px;
    height: 300px;
    background: #e0ebaf;
}

.sample-box{
    position: absolute;
    top: 50px;
    left: 50px;

    color: #ffffff;
    background: #ee827c;
    text-align: center;
    width: 300px;
    height: 300px;
}

 

すると、以下のような表示になります。要素が重なって表示されています。

「starting-point」からの距離で配置することが出来ました。さて、ここで重要な点は、今回設定した50pxという値が起点からの絶対的な距離となっているという点です。例えば、以下のようにpタグ2つをコード内に挿入してみましょう。これで位置がずれるようであれば、配置に「absolute」を使う意味はありません。

<div class="container">
  <div class="starting-point">
     <div class="main-box">
  	<p>これはサンプルです。_1</p>
  	<p>これはサンプルです。_2</p>
  	<div class="sample-box"></div>
     </div>
  </div>
</div>

 

floatを設定した時と同じように、要素が浮き、その下にpタグが入り込んでいることがわかります。その結果、距離が保たれているのです。

ただし、注意が必要です。設定した距離は、「margin」や「padding」の影響を受ける、ということです。以下のように、「sample-box」に「margin: 50px」を設定してみましょう。

.sample-box{
    position: absolute;
    top: 50px;
    left: 50px;

    color: #ffffff;
    background: #ee827c;
    text-align: center;
    width: 300px;
    height: 300px;
    margin: 50px;
}

 

すると、以下のように表示が変化します。つまり、CSSの設定によって距離は絶対的な距離にはならないということです。従って、ページを設計する際は、想定からずれることを考え、無意味な「margin」や「padding」の設定に気をつけてください。

インライン要素に対する配置変更

さて、これまでの説明は、「absolute」に関する、ブロック要素の配置変更についてでした。もし、インライン要素の配置を決める場合はどうすればいいでしょうか?
例えば、以下のようなインライン要素「spanタグ」があったとします。これをブロック要素に変え、文字を中心に置き、かつ、この要素を親要素から上左50pxに配置するデザインを考えてみましょう。

<div class="container">
  <div class="starting-point">
     <div class="main-box">
  	<span class="sample-box">POSITION</span>
     </div>
  </div>
</div>

以下のように表示されます。インライン要素は、幅も高さも指定することはできません。

これを「starting-point」を起点に、上左50pxほど、「absolute」 で移動させます。

.starting-point{
    position: relative;
    width: 300px;
    height: 300px;
    background: #e0ebaf;
    text-align: center;
}

.sample-box{
    position: absolute;
    top: 50px;
    left: 50px;

    background: #ee827c;
    color: #ffffff;
}

 

すると、以下のような表示になります。きちんと配置が変化したことがわかります。

ただ、ここで驚くべき事実が発覚します。「sample-box」はインライン要素ですが、CSSで高さと幅を指定してみましょう。

.sample-box{
    position: absolute;
    top: 50px;
    left: 50px;

    background: #ee827c;
    color: #ffffff;
    width: 300px;
    height: 300px;
}

すると、できないはずの幅と高さが設定できています。つまり、インライン要素でも、「position: absolute;」の設定によってブロック要素の性質を帯びるのです。
これらは、挙動を確認しながら実感として頭に入れておいてください。

最後に、文字をブロックの中心に配置します。以下のようなプロパティを設定してください。「displayプロパティ」は別の機会にご説明します。

.sample-box{
    position: absolute;
    top: 50px;
    left: 50px;

    background: #ee827c;
    color: #ffffff;
    width: 300px;
    height: 300px;
    display: flex;
    justify-content: center;
    align-items: center;
}

 

すると、以下のように文字がブロックの中心に配置されます。このように、インライン要素であっても、ブロック要素化し、配置変更することが可能であることがわかります。

ポイントをまとめると、「absolute」の使用は必ず挙動を確認し、それを経験としてまとめておかないと理解できない挙動が発生する可能性があるということです。「margin」や「padding」の設定、ブロック要素とインライン要素での挙動の違いには特に注意しておいてください。

fixed

「position: fixed;」の設定の特徴は、「relative」などの任意の起点がなく、ブラウザウィンドウのトップが起点となるということです。navbarの固定をはじめ、特定の要素をブラウザトップからの距離に対して固定したい場合に使います。以下のように設定してください。画面トップに要素を固定します。親要素に「relative」などを指定する必要はありません。

<div class="container">
  <div class="starting-point">
    <div class="main-box">
      <div class="sample-box">POSITION</div>
    </div>
  </div>
</div>
}

 

.sample-box{
    position: fixed;
    top: 0px;
    left: 0px;

    background: #ee827c;
    color: #ffffff;
    width: 100%;
    height: 100px;
    text-align: center;
}

すると以下のようにトップに固定して、表示されます。

sticky

最後に、positionの機能として比較的新しい「sticky」を説明します。positionの値として「sticky」を指定すると、「position: sticky;」とともに指定した配置箇所(例えば、top: 0px;)まではスクロールされますが、その後要素が固定されます。特定の広告の固定、サイドバーの固定などに便利で、今後、認知度も使用頻度も上がってくることでしょう。

以下のように要素を指定します。POSITIONの1-5まで指定し、それぞれの高さをわかりやすく300pxとしています。高さをできるだけ高くとることで効果がわかりやすくなるはずです。また、親要素に「relative」などを指定する必要はありません。

<div class="container">
	<div class="main-box">
		<div class="sample-box-1 block">POSITION_1</div>
		<div class="sample-box-2 block">POSITION_2</div>
		<div class="sample-box-3 block">POSITION_3</div>
		<div class="sample-box-4 block">POSITION_4</div>
		<div class="sample-box-5 block">POSITION_5</div>
	</div>
  </div>
}

 

.sample-box-1{
  background: #ee827c;
  z-index: 0;
}

.sample-box-2{
  background: #f4b3c2;
  z-index: 100;
}

.sample-box-3{
  background: #83ccd2;
  z-index: 200;
}

.sample-box-4{
  background: #b8d200;
  z-index: 300;
}

.sample-box-5{
  background: #ffd900;
  z-index: 400;
}


.block{
    position: -webkit-sticky;
    position: sticky;
    top: 0px;
    color: #ffffff;
    width: 100%;
    height: 300px;
    display: flex;
    justify-content: center;
    align-items: center;
}

 

画像からはわかりずらいですが、各要素がtop: 0px;まではスクロールで動き、その後、要素が固定されることがわかります。

まとめ

「position」の理解に最も役立つことは、自分で挙動の確認を一つ一つ行うことです。いろいろな参考資料がありますが、自分で手を動かし、その動きと制限を知ることほど役立つ学習法はありません。特に「relative」と「absolute」の使用頻度は高いため、まずはこちらの学習から始め、徐々に他の値についても学習すれば良いでしょう。