HTMLのボックスモデルについて整理

## 記事を書こうと思った理由
業務で最近レイアウト周りのタスクを行っているのですが、
以下の悩みがあって今までなんとなくで書いてるなーという実感があったので今後のために自分の言葉で整理してみる
- margin？padding？どっち使えばいいの？
- このタグだとmargin適応されるけど、このタグだと適応されないのなんで？
- marginとpaddingのショートハンドってどの順だっけ


## ボックスモデルとは？
HTMLはmargin → border → padding → contentの順に箱が並んでる
この箱を並べてレイアウトを作成していく
全てのHTML要素はデフォルト左寄せなので、基本的に左上からこの箱を並べていく

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077384/19deac7c-0059-4d6e-89a3-3ff165b0c7fb.png)


### margin
要素の外側の余白の指定
要素と要素の間に距離を取りたい時に使う
以下のように指定する
margin: [top] [right] [bottom] [left];
ショートハンドで書ける
| 記述例                            | 上下左右の対応                         |
| ------------------------------ | ----------------------------------- |
| `margin: 10px;`                | 全方向 `10px`                          |
| `margin: 10px 20px;`           | 上下 `10px`、左右 `20px`                 |
| `margin: 10px 20px 30px;`      | 上 `10px`、左右 `20px`、下 `30px`         |
| `margin: 10px 20px 30px 40px;` | 上 `10px`、右 `20px`、下 `30px`、左 `40px` |

４つ指定したときは時計回りって覚えるといいかも

**上下のマージンは相殺が起こり得るから注意！**
#### 隣接する兄弟要素間のmargin
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077384/5bbafcb1-8432-45ef-a282-8b67dd397ba4.png)


#### 親要素と子要素に設定する同方向のmargin
上方向と下方向で挙動が異なる

#### 上方向
値が大きい方が適応される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077384/118668e9-83cf-4131-807d-a9ff47fef4a4.png)

#### 下方向
親要素の高さがautoの時相殺が起こる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077384/ea2981fd-0a74-43ef-8ff5-5d2e7d23fae3.png)

親要素に高さの指定がある場合は親要素のmargin-bottomが適応される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077384/71c41682-3b8f-4977-9974-c2f555631b00.png)





### border
要素の境界
paddingとcontentを囲む
以下の３つの要素を指定する
- 太さ（border-width）
- スタイル（border-style）
- 色（border-color）
初期値はnoneらしいので見た目上は見えない

https://developer.mozilla.org/ja/docs/Web/CSS/border



### padding
要素の内側の余白の指定
要素の中なので背景色が適応される！！！
以下のように指定する
padding: [top] [right] [bottom] [left];
ショートハンドも対応
※指定のルールはmarginと一緒


### content
テキストや画像など、HTMLで書かれている内容が表示される領域
widthで幅、heightで高さを指定できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077384/2a11f799-2924-45cc-baa9-03d7a6163e02.png)


box-sizeingプロパティをborder-boxに指定すると、
要素のwidthとheightにpaddingやborderのサイズが含まるようになるらしい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077384/dca7e7e9-89e9-4bc4-b3af-85d7b1394ec5.png)


https://zero-plus.io/media/box-sizing/




## ブロックボックス/インラインボックスとは？
ボックスにはボロックボックスとインラインボックスの２種類ある
タグによってデフォルト値が決まっている
displayプロパティを設定することによって任意のボックスに指定することが可能
![スクリーンショット 2025-05-18 22.37.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077384/4ca861ff-c324-4bc0-9f38-9218735919a4.png)




### ブロックボックス
横いっぱいに広がり次の要素が下に表示される
例：`<div>`や`<h1>`など

以下の特徴がある
- 要素が改行される
- width、heightが適用される
- padding、marginが適用される
- 親要素いっぱいの幅をとる


### インラインボックス
必要な幅だけ使用し、次の要素と同じ行に並んで表示される
例：`<span>`や`<a>`など

以下の特徴がある
- 要素が改行されず横に並ぶ
- width、heightが適用されない
- padding上下左右指定可能だが、marginは左右のみ指定可能。上下は指定不可
- 親要素の内容に応じた幅をとる(テキストや画像の大きさに応じて、ボックスの幅が自動的に決定)

### インラインブロック要素
`display: inline-block`って指定すると指定したタグはインラインブロック要素になる

以下の特徴がある
- 要素が改行されず横に並ぶ（インラインボックスと同じ)
- width、heightが適用される（ブロックボックスと同じ)
- padding、marginが適用される（ブロックボックスと同じ)





### まとめ
マージンが効かないって思ってた時は知らず知らずのうちに相殺が起こっていたかもしれません。
プロジェクト内でmarginを取る時のルール決めた方が複雑にならなくていいと思いました。
topだけ入れる等

インラインブロック要素は使い道がいまいちわからない。
(横並びにするならflexかgrid使えばいいのでは？)と思っていましたが、
flexやgridが出てくる前によく使われていたとのこと。

近年はflexとgridの方がよく使うと思うので改めて整理したいと思います。

### 参考記事
https://zenn.dev/youtuber/books/4781843d234022/viewer/04-04-boxmodel

https://snome.jp/engineer/css3/

https://moshashugyo.com/media/collapsing-margin