Webサイトを作っていると「要素を特定の位置に固定したい」「他の要素と重ねて表示したい」「スクロールしても常に画面上部に表示させたい」といった対応が必要になる場面があります。
このとき、HTMLの構造を変えずにCSSだけで要素の配置を細かくコントロールできるのが、position(ポジション)プロパティです。
ここでは、CSSのpositionプロパティの種類(static、relative、absolute、fixed、sticky)と基本的な使い方、実務でよく使うユースケースについて解説します。
Contents
position(ポジション)プロパティとは
position(ポジション)プロパティは、HTML要素をどのように配置するかを指定するプロパティです。Webサイト制作における次のような場面で特に活躍します。
| 場面 | 具体例 |
|---|---|
| 要素を重ねて表示したい | 商品画像に「NEW」「SALE」バッジを重ねる、テキストを画像の上に重ねる |
| スクロールしても常に表示したい | 画面上部に固定するナビゲーションバー、右下に固定するページトップボタン |
| 特定の要素を基準に配置したい | モーダルウィンドウを画面中央に表示する、ドロップダウンメニューを親要素の直下に表示する |
| スクロール途中で要素を固定したい | 長い表のヘッダー行をスクロールしても常に表示する |
positionプロパティを使用するときは、positionで要素の配置方法を指定し、top・bottom・left・rightの4つのプロパティで具体的な表示位置を指定します。
| 要素 { position: 値; /* 配置方法を指定(static / relative / absolute / fixed / sticky)*/ top: px(または%); bottom: px(または%); left: px(または%); right: px(または%); } |
top・bottom・left・rightは「基準となる要素から、上下左右どのくらい移動した場所に要素を配置するか」を指定することができます。例えば「top: 50px; left: 80px」とした場合、基準となる要素の上から50px、左から80px移動した位置に要素が配置されます。

top・bottom・left・rightは同時にすべて指定する必要はなく、topとleft、bottomのみなど、必要なものだけ指定します。
positionプロパティに指定できる主な値は次の5種類です。
| 種類 | 説明 | 特徴 |
|---|---|---|
| static | デフォルト値。HTMLに書かれた順番どおりに自動的に配置されます。 | 位置の指定(top・bottom・left・right)は効きません。positionを指定しない場合もこの状態です。 |
| relative | 通常の位置を基準に、相対的にずらして配置します。 | 移動しても元いた場所のスペースはそのまま残ります。また、relative内に配置したabsoluteの基準位置になります。 |
| absolute | 直近の「position: static以外」の要素を基準に位置を指定します。 | 他の要素には「そこに存在しない」ものとして扱われます。要素が重なって表示されることがあります。 |
| fixed | ブラウザに表示されている画面の範囲を基準に配置します。 | ページをどれだけスクロールしても、画面上の同じ場所に表示され続けます。 |
| sticky | 最初はrelativeと同じように配置され、スクロールして指定した位置に達すると固定されます。 | relativeとfixedの中間のような動作をします。 |
(1) static
staticはpositionのデフォルト値です。HTMLの記述順どおりに上から下へ要素が並ぶ通常の配置になります。top・bottom・left・rightプロパティは効果がありません。
CSSでpositionの指定がない場合、すべての要素はstaticとして扱われます。明示的に記述することはほとんどありませんが、他のCSSで上書きされたpositionをリセットしたいときに使います。
例)style.css
| .box { position: static; /* デフォルト値のため省略可 */ width: 100px; height: 100px; background-color: lightblue; margin-bottom: 10px; } |
例)index.html
| <html> <head> <title>ページのタイトル</title> <style> @import url(style.css) </style> </head> <body> <div class=”box”>ボックス1</div> <div class=”box”>ボックス2</div> <div class=”box”>ボックス3</div> </body> </html> |
ブラウザでの表示結果

(2) relative
relativeは、要素が本来配置されるべき位置(staticのときの位置)を基準に、top・bottom・left・rightで指定した量だけずらして表示します。
例)style.css
| .box { width: 100px; height: 100px; background-color: lightblue; } .box-relative { position: relative; top: 30px; /* 元の位置より30px下にずらす */ left: 50px; /* 元の位置より50px右にずらす */ width: 100px; height: 100px; background-color: salmon; } |
例)index.html
| <html> <head> <title>ページのタイトル</title> <style> @import url(style.css) </style> </head> <body> <div class=”box”>通常の要素</div> <div class=”box-relative”>relativeで移動した要素</div> <div class=”box”>通常の要素</div> </body> </html> |
ブラウザでの表示結果

今回の例の場合、通常は2つ目のdiv要素は点線の位置に表示されますが、position: relativeを指定したことで、もとの表示位置から下に30px、右に50pxずれた位置に表示されています。

position: relativeで要素をずらしても、元の位置のスペースはそのまま残るため、3つ目のdiv要素はrelativeの要素が移動する前の位置を基準に並びます。
(3) absolute
absolute を指定した要素は、直近の「position: static以外」の要素(=親要素やその外側にある要素)を基準に位置を指定します。親要素やその外側の要素のどれにもposition(static以外)が指定されていない場合は、ページ全体(body要素)が基準になります。
例)style.css
| .parent { position: relative; /* 基準となる要素 */ width: 300px; height: 200px; background-color: lightgray; } .child { position: absolute; top: 80px; /* 親要素の上端から80px */ right: 50px; /* 親要素の右端から50px */ width: 80px; height: 80px; background-color: steelblue; } |
例)index.html
| <html> <head> <title>ページのタイトル</title> <style> @import url(style.css) </style> </head> <body> <div class=”parent”> 親要素(position: relative) <div class=”child”>子要素(absolute)</div> </div> </body> </html> |
ブラウザでの表示結果

今回の例の場合、position: relativeが指定されている親要素の位置を基準として、下に80px、右から50px内側にずれた位置に表示されています。

absoluteはrelativeとセットで使うのが基本パターンです。基準にしたい要素にrelativeを指定し、その中の要素にabsoluteを指定して位置を決めます。
また、absoluteを指定した要素は他の要素から「そこに存在しない」ものとして扱われるため、他の要素はabsoluteの要素を無視して並びます。例えば、以下のように3つの要素を並べた場合の動きを見てみます。
例)style.css
| .item { width: 200px; height: 60px; background-color: lightblue; margin-bottom: 5px; } .item-absolute { position: absolute; top: 100px; left: 200px; width: 200px; height: 60px; background-color: salmon; } |
例)index.html
| <html> <head> <title>ページのタイトル</title> <style> @import url(style.css) </style> </head> <body> <div class=”item”>要素A</div> <div class=”item-absolute”>要素B(absolute)</div> <div class=”item”>要素C</div> </body> </html> |
ブラウザでの表示結果

通常であれば「要素A → 要素B → 要素C」の順に縦に並びますが、要素Bにabsoluteを指定したことで、要素Cは要素Bが存在しないかのように、要素Aのすぐ下に詰めて表示されます。要素Bは指定した位置(上から100px、左から200px)に、他の要素とは独立して表示されます。
(4) fixed
fixedは、ブラウザのビューポート(画面に表示されている領域)を基準に配置します。ページをスクロールしても常に同じ位置に表示され続けます。ページ上部に固定するナビゲーションバーや、右下に固定するページトップボタンなどによく使われます。
ナビゲーションバーの例は以下のとおりです。ページトップボタンは「CSS positionバッジ(ラベル)、モーダルウィンドウ、ページトップボタン、追随ボタンの作り方 画面右下にページトップボタンを固定する」で紹介します。
例)style.css
| .fixed-header { position: fixed; top: 0; /* 画面の上端に固定 */ left: 0; width: 100%; height: 50px; background-color: steelblue; color: white; line-height: 50px; padding-left: 20px; } |
例)index.html
| <html> <head> <title>ページのタイトル</title> <style> @import url(style.css) </style> </head> <body> <div class=”fixed-header”>固定ヘッダー</div> <div style=”margin-top: 80px;”> <p>段落① スクロールしてもヘッダーは画面上部に固定されます。</p> </div> <div style=”margin-top: 80px;”> <p>段落② スクロールしてもヘッダーは画面上部に固定されます。</p> </div> <div style=”margin-top: 80px;”> <p>段落③ スクロールしてもヘッダーは画面上部に固定されます。</p> </div> <div style=”margin-top: 80px;”> <p>段落④ スクロールしてもヘッダーは画面上部に固定されます。</p> </div> <div style=”margin-top: 80px;”> <p>段落⑤ スクロールしてもヘッダーは画面上部に固定されます。</p> </div> </body> </html> |
ブラウザでの表示結果

ブラウザを下にスクロールしても、ヘッダーは上部に固定されたままです。

fixedを指定した要素は、他の要素から「そこに存在しない」ものとして扱われます。そのため、fixedで固定したヘッダーなどの下にコンテンツが隠れてしまうことがあります。コンテンツを隠したくない場合、fixed要素の高さに合わせて、コンテンツ側にmargin-topやpadding-topを設定して対処してください。
例えば、上記の例では各段落に margin-top: 80px を指定することで、固定ヘッダー(高さ50px)に隠れないようにしています。
| <div style=”margin-top: 80px;”> <p>段落① スクロールしてもヘッダーは画面上部に固定されます。</p> </div> |
または、body全体に余白を設定する方法もあります。
| body { margin-top: 50px; /* 固定ヘッダーの高さ分の余白を確保 */ } |
(5) sticky
stickyは、最初はrelativeと同じように通常の位置に表示されますが、ページをスクロールして要素が指定した位置(例:top: 0 なら画面の上端)に達すると、そこで止まって固定されます。長い表の見出し行をスクロール中も常に表示したいときなどに便利です。
例)style.css
| .sticky-header { position: sticky; top: 0; background-color: cornsilk; border-bottom: 2px solid gray; padding: 8px; } |
例)index.html
| <html> <head> <title>ページのタイトル</title> <style> @import url(style.css) </style> </head> <body> <p>コンテンツ1</p> <p>コンテンツ2</p> <p>コンテンツ3</p> <div class=”sticky-header”>この見出しはスクロールで固定されます</div> <p>コンテンツ4</p> <p>コンテンツ5</p> <p>コンテンツ6</p> <p>コンテンツ7</p> <p>コンテンツ8</p> <p>コンテンツ9</p> <p>コンテンツ10</p> <p>コンテンツ11</p> <p>コンテンツ12</p> <p>コンテンツ13</p> <p>コンテンツ14</p> <p>コンテンツ15</p> <p>コンテンツ16</p> <p>コンテンツ17</p> <p>コンテンツ18</p> <p>コンテンツ19</p> <p>コンテンツ20</p> <p>コンテンツ21</p> <p>コンテンツ22</p> <p>コンテンツ23</p> <p>コンテンツ24</p> <p>コンテンツ25</p> <p>コンテンツ26</p> <p>コンテンツ27</p> <p>コンテンツ14</p> <p>コンテンツ15</p> <p>コンテンツ16</p> <p>コンテンツ17</p> <p>コンテンツ18</p> <p>コンテンツ19</p> <p>コンテンツ20</p> <p>コンテンツ21</p> <p>コンテンツ22</p> <p>コンテンツ23</p> <p>コンテンツ24</p> <p>コンテンツ25</p> <p>コンテンツ26</p> <p>コンテンツ27</p> <p>コンテンツ28</p> <p>コンテンツ29</p> <p>コンテンツ30</p> <p>コンテンツ31</p> <p>コンテンツ32</p> <p>コンテンツ33</p> <p>コンテンツ34</p> <p>コンテンツ35</p> <p>コンテンツ36</p> <p>コンテンツ37</p> </body> </html> |
ブラウザでの表示結果

下にスクロールしていき、見出しがposition: stickyで指定した位置(画面の上端)に達すると、そこで位置が固定されます。さらにスクロールしても見出しは表示されたままの状態です。

※画面の下端までスクロールした状態

position(ポジション)プロパティがうまく動かないときの原因と対処法
positionを指定しても意図通りに動かない場合、次のような原因が考えられます。
(1) absoluteが意図した位置に表示されない
absoluteは直近の「position: static以外」の要素(=親要素やその外側にある要素)を基準にします。基準にしたい親要素にposition: relativeを指定し忘れると、さらに外側の要素やページ全体が基準になってしまい、意図しない位置に表示されてしまいます。
(2) stickyが効かない
topなどの位置プロパティが指定されていないとstickyとして動作しないため、必ずtop・bottom・left・rightのいずれかを指定してください。
>>CSS positionバッジ(ラベル)、モーダルウィンドウ、ページトップボタン、追随ボタンの作り方
