CSS positionプロパティ

`position`プロパティは、HTML要素をどのように配置するかを定義します。
このプロパティには主に以下の5つの値があり、それぞれが要素の振る舞いを大きく変えます。

- `static` (初期値)
- `relative`
- `absolute`
- `fixed`
- `sticky`

# 1.`static`
- `position`プロパティの初期値で、元の位置に配置されます。
- 指定したpositionをリセットしたい場合などに利用します。

## 特徴
- `top`, `right`, `bottom`, `left`, `z-index` プロパティは効果がありません。


# 2. `relative`
- **相対位置**とも呼ばれます。
- 元の位置を基準として、**`top`, `right`, `bottom`, `left` で指定した分**だけ「ずらして」表示されます。

## 特徴
- 元の位置にはスペースが残されます。
 ずれて表示されても、他の要素は元の位置に要素があるものとして扱います。
- `z-index` プロパティが有効になり、重ね順を制御できます。

## 使用例

```HTML
      <div>
        <img id="p1" src="images/hana.jpg" alt="" />
        <img id="p2" src="images/mori.jpg" alt="" />
        <img id="p3" src="images/sora.avif" alt="" />
      </div>
```
```CSS
#p2 {
  position: relative;
  top: 100px;
  left: 100px;
}
```
![スクリーンショット 2025-05-12 12.20.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627033/9d30e886-7e8e-4f26-a524-0b15bf0b24c0.png)

# 3.`absolute`
- 絶対位置と呼ばれるものです。
- 最も近い `position` が `relative`の親要素をがある場合それを基準として、`top`, `right`, `bottom`, `left`で位置が決められます。
    - ない場合はウィンドウを基準に指定された数値を移動します。

:::note info
`relative`以外にも `absolute`, `fixed`, `sticky` のいずれかが指定された親要素があれば基準にすることができますが、一般的には`relative`を指定します。
:::

## 特徴
- 要素は通常のドキュメントフローから完全に切り離されます。
    - フローから切り離されるため、その要素があった場所にはスペースが残りません。他の要素はその要素が存在しないかのように詰めて表示されます。
- `z-index` プロパティが有効になり、重ね順を制御できます。

## 使用例

### 起点とする親要素がある場合
```HTML
<div>
     <img id="p1-1" src="images/hana.jpg" alt="" />
     <img id="p2-2" src="images/mori.jpg" alt="" />
     <img id="p3-3" src="images/sora.avif" alt="" />
</div>
```

```CSS
body > div {
  position: relative;
  border: 2px solid blue;
  width: 400px;
  max-height: 300px;
}

#p2-2 {
  position: absolute;
  top: 100px;
  left: 100px;
}
```
![スクリーンショット 2025-05-12 12.15.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627033/9b8dad1a-e9f1-438f-b71f-4e69c460981d.png)

- 起点としたい親要素に`position: relative`と`max-height`を設定する。
    - 上記の例では親要素は青いボックスとなります。
    - 絶対位置がしていされた要素はフローから切り離されるため、その要素があった場所にはスペースが残りません。`max-height`を指定することで、次の要素が重なることなく表示できます。
- 配置を変更したい要素に、`position: absolute`と`top`, `right`, `bottom`, `left`を設定する。
    - 画像 #p2-2（森の画像）は、親要素（青い枠）の左上角をスタート地点として右に100px・下に100pxの位置に表示されます。
- 空の画像は、#p2-2（森の画像）がないものと考えているため、すぐ次に表示されます。
※`img`はインライン要素のため、横並びにしようとしますが、幅が指定されてスペースが足りないから、縦に表示されています。

### 起点とする親要素がない場合

``` HTML
<p>絶対位置</p>
<div>
  <img id="p1-1" src="images/hana.jpg" alt="" />
  <img id="p2-2" src="images/mori.jpg" alt="" />
  <img id="p3-3" src="images/sora.avif" alt="" />
</div>
```
``` CSS
#p2-2 {
  position: absolute; 
  top: 100px;
  left: 100px;
}
```
![スクリーンショット 2025-05-12 12.00.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627033/aa523a04-437d-4b60-a7ec-ba0c7a15b9f7.png)
- 配置を変更したい要素に、`position: absolute`と`top`, `right`, `bottom`, `left`を設定する。
    - 画像 #p2-2（森の画像）は、ビューポートをスタート地点として右に100px・下に100pxの位置に表示されます。

:::note info
スタート地点の決定方法として、内部の動きは下記となります。
①もし、絶対位置の要素を囲む親要素に何か設定がある場合、絶対位置の要素はその親要素の内側の端を基準にプロパティで位置が決定されます。

②もし、親要素にこれらの `position` プロパティが設定されていない場合、絶対位置の要素はブラウザのウィンドウの端を基準に位置が決定されます。

:::

## 実務的なポイント
- `absolute`で位置を指定するとき、フローには表示されないことから表示が詰まることを防ぐため、親に`min-height`を設定しておこう。

## 包含ブロック
CSSで何かを「絶対位置」で配置しようとするとき、その要素は「どこを基準に動けばいいの？」と迷ってしまいます。
この「どこを基準に動けばいいか」の目印になる箱のことを、**包含ブロック**と呼びます。

この「基準となる壁や窓（包含ブロック）」は、前述のとおり以下のルールで決まります。
1. 一番近くにある「特別な壁（`position: relative;`などの親要素）」を探す
1. もし親や祖先にそのような「特別な壁」が全く見つからなかったら、最終的にはブラウザの画面全体（html要素の領域）を「特別な壁」とみなして、そこを基準に動きます。

注意が必要なのは`::after`のような、 擬似要素の際です。
- 擬似要素は、「生成元の要素」 の「一部」のようなものです。
- そのため、擬似要素 に `position: absolute;`を設定した場合、その「生成元の要素」自身に `position: relative;`が設定されていれば、それがそのまま「包含ブロック」になります。
```HTML
<a class="btn" href="">ONLINE STORE</a>
```
```CSS
.btn {
  position: relative; /*生成元の要素に設定。ここが親となる。*/
}
.btn::after {
  position: absolute; /*絶対位置指定。*/
  top: 20px;
  right: -20px;
}
```


# 4.`fixed`
- 要素は指定された位置で固定されます。
    - 画面をスクロールしても、その要素は常に同じ画面上の位置に表示され続けます。
- **ビューポート（ブラウザの表示領域）を基準**として、`top`, `right`, `bottom`, `left` で位置が決められます。

## 特徴
- 要素は通常のドキュメントフローから完全に切り離されます。
- `z-index` が有効です。
- `width: 100%;`と`top: 0; left: 0;`などを組み合わせることで、ヘッダーやフッターを画面に固定するのによく使われます。

## 使用例
```HTML
<header>
  <h1>
    <a href="index.html"><img src="img/logo.svg" alt="" /></a>
  </h1>
</header>
```
```CSS
header {
  position: fixed;
  top: 0;       /* 画面の上端に固定 */
  left: 0;      /* 画面の左端に固定 */
  width: 100%;  /* 画面幅いっぱい */
  z-index: 1000; /* 他のコンテンツの上に表示 */
}
```
 
:::note info
`fixed`要素もフローから外れるため、その下のコンテンツが隠れてしまうことがあります。
隠れる部分には、`fixed`要素の高さ分の`margin`や`padding`を設定してスペースを空けるのが一般的です。
:::

# 5. `sticky`
- 親要素で固定されて表示されます。
- サイドバーの追従バナーでよく使用されますが上記の値に比べると使用頻度は少なめです。

## 特徴
- `top`, `right`, `bottom`, `left` と組み合わせて使います。
- `z-index` が有効です。

## 使用例
```CSS
.sticky-element {
  position: sticky;
  top: 0; /* 画面上端に到達したら固定 */
  background-color: yellowgreen;
  padding: 10px;
  margin-bottom: 20px;
  z-index: 10;
}
```

:::note info
親要素に `overflow`プロパティが `hidden`, `scroll`, `auto` などに設定されていると、正しく機能しない場合があります。
:::

5つのプロパティの違いを、表にまとめておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627033/4eeba491-fb5f-4373-9f96-16fd8b80ac2b.png)


続いて、`potision`プロパティとよく一緒に使用するプロパティについて紹介します。

# `top`, `right`, `bottom`, `left`プロパティ
- 要素の位置を指定するプロパティです。
- 基準となる位置から、上、下、左、右の移動位置を指定します。

:::note info
- 指定した値をリセットする場合は、初期値である`auto`を指定します。
- 値には、`px`や `%`、`em`, `rem`, `vw`, `vh` などの単位を指定できます。
:::

# `z-index`プロパティ
- 重なり合う要素の順序を制御します。
- 0を基準として、数値が大きい方が前に表示されます。
- 一般的にはあとで要素が追加になった場合に間に入れられるよう、10単位（10,20,30…）で使用することが多いです。

:::note info
`auto`の場合は、親と同じ重なりレベルになります。
:::

:::note warn
`position`を指定していない場合や`static`が指定されている場合は、効きません。
:::

```CSS
.box1 {
  position: absolute;
  top: 10px; left: 10px;
  background-color: red;
  z-index: 20; /* 手前に表示 */
}
.box2 {
  position: absolute;
  top: 30px; left: 30px;
  background-color: blue;
  z-index: 10; /* box1の後ろに表示 */
}
```

# `object-fit`プロパティ
- 画像をトリミングする際によく使用されるプロパティです。
- CSSで指定した「箱」（`width`・`height`で指定した表示領域）に、その要素（画像や動画自体）をどう収めるかを決めるプロパティとなります。

## 指定値
| 値            |  解説                                    |
| ------------ |  ------------------------------------- |
| `fill`       | ボックスを埋めるように引き伸ばされる（縦横比は無視されるので、崩れる可能性あり）  |
| `contain`    |  コンテンツが縦横比を維持したまま、ボックス内に完全に収まるように拡大縮小される（余白ができる可能性あり） |
| `cover`      | 縦横比を維持したまま、ボックスからはみ出した分はトリミングされて表示される |
| `none`       |  コンテンツは拡大縮小されず、元のサイズで表示される（はみ出したり、余白ができたりする可能性あり）   |
| `scale-down` |  `none` と `contain` を比べて、小さいほうを表示する  |


:::note indo
実務では`contain`と`cover`をよく使用します。
- `contain`:画像を絶対に切らずに全部表示したいとき、よく使用されます。
- `cover` :見切れてもいいから枠ピッタリにカッコよく見せたいとき、よく使用されます。
:::

## `object-position`
`object-fit`と組み合わせて使われます。
画像がはみ出して切り取られるときに、画像のどの部分を残すかを決めます。

### `object-fit: cover`の際の挙動 
-  `object-fit: cover`のとき、ボックスからはみ出した分はトリミングされます。
-  ここで `object-position`を使うと、「写真のどの部分を箱の中心に持ってくるか」 を指定できます。
    -  `object-position: center` → 写真の真ん中が箱の中心に来る。
    -  `object-position: top;` → 写真の上側が箱の中心に来る。
    -  `object-position: right;` → 写真の右側が箱の中心に来る。

### `object-fit: contain`の際の挙動 
-   `object-fit: contain`はコンテンツが縦横比を維持したまま、ボックス内に完全に収まるように拡大縮小されます。（余白ができる可能性あり）
- ここで `object-position` を使うと、「窓の中で写真をどこに置くか」 を指定できます。
    - `object-position: center;` → 写真を箱の真ん中に置く。
    - `object-position: left;` → 写真を箱の左側に寄せて置く。
    - `object-position: bottom;` → 写真を箱の下側に寄せて置く。


#  `visibility` プロパティ
- 要素を表示するか、非表示にするかを制御します。

## 指定値
### `visibility:visible`
- 初期値。要素が表示されます。
 
### `hidden`
- 要素は非表示になりますが、その要素が占めるスペース（レイアウト上の位置）は維持されます。
- 他の要素は、その要素が存在するかのように配置されます。

### `collapse`
- テーブルの特定の行や列を、スペースを占めずに非表示にしたいときに使用されます。
- 他の要素に適用されると、`hidden`と同じように振る舞いますが`hidden`を使用するのが一般的です。

## `display:none`との違い
- `visibility: hidden;`
    - 非表示だがスペースを占める 
    - `opacity: 0;`と似ているが、クリックなどのイベントは通ってしまうのに対して、`visibility: hidden`はイベントも無効になります。
- `display: none;`
    - 非表示になり、スペースも占めない。
    - ドキュメントフローから完全に消滅したかのように扱われる。


# `overflow`プロパティ
- 要素のコンテンツが、その要素のコンテンツボックスからあふれた（オーバーフローした）場合の挙動を制御します。

## 指定値
```CSS
#p1 {
  overflow: hidden; /*はみ出た部分は表示しない*/
}

#p2 {
  overflow: scroll; /*はみ出た部分はスクロールして表示させる*/
}

#p3 {
  overflow: visible; /*はみ出た部分も表示する*/
}
```

![スクリーンショット 2025-05-12 15.36.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627033/ba28b2d4-92cc-4fb3-9462-5915a62d8eae.png)

:::note info
- `auto`も指定できます。
    - `auto`はコンテンツがオーバーフローした場合にのみ、自動的にスクロールバーが表示されます。オーバーフローしていない場合は表示されません。
- `overflow-x` 横方向（水平方向）、`overflow-y` 縦方向（垂直方向）のみを個別に制御することもできます。
:::


# 透明度指定
- 要素の透明度を指定するには下記の2種類があります。
    - `opacity`
    - `rgba`
- それぞれの違いは、要素全体が透過されるかどうかと覚えておけばOKです。

## `opacity`プロパティ
- 要素の全体を透明にできるプロパティです。
- 指定した要素のボーダー、背景だけでなく子要素を含む全ての要素が投下されます。

### 設定値
- 値は 0〜1の数値で指定して、
0 に近づくほど透明に、1 に近づくほど不透明になります。

| 値     | 意味             |
| ----- | -------------- |
| `1`   | 完全に不透明（ふつうの状態） |
| `0.5` | 半分透明（うっすら見える）  |
| `0`   | 完全に透明（見えない）    |

:::note 
- `opacity`をかけると、その中の文字や子要素すべてが透けます。
- イベントは有効となります。
:::

## `rgba`
- Red（赤）、Green（緑）、Blue（青）の3原色に加えて、Alpha（アルファ、透明度） の値で、指定した色を透過させることができます。

```CSS
selector {
  color: rgba(red, green, blue, alpha);
}
```
- `R, G, B`
    - それぞれ0から255までの整数値で、色の明るさを指定します。
    - 0 はその色が最も暗い（含まれない）状態
    - 255 はその色が最も明るい（最大限含まれる）状態
- `alpha`
    - 透明度は0〜1の数値が指定でき、数字が小さいほど透明度が高くなります。

## 使用例
### 透過なし
```CSS
background-color: rgb(0,153,255)
```

### 透過あり
```CSS
background-color: rgb(0,153,255,0.5)
```