初心に帰ってCSSで当てられる余白について考える


## この記事の目的

コードがわからないデザイナーさんや
マークアップ初学者さんが

**「余白ってこうやってコーディングできるんだ！ふ〜ん！」**

てなること


## 余白とは
wikipedia曰く、
>余白（よはく）とは、文字通り余った白い部分。ただし漢字では余った白と表現するが、必ずしも余白の余った部分は白色ではない時もある。英語ではNegative spaceという。

はい、上記の通り、余白とは何もない文字もない画像もない空いた空間のことです。
(wikipedia以外でも大体同じことが書いてありました...)
今回作るのはそれです👀

## 今回余白の作り方を確認するために使用するデザインはこちら

https://code-step.com/profile-menu/

**「Webサイト制作の実践力をつけるための、コーディング学習サイト」**
の**Codestep**さんから、余白の実装のお試しにちょうど良さそうなデザインをお借りしました。
※こちらのサイトは、著作権フリーの素材となっており、コーディングしたものをポートフォリオに乗せてもいいよと言ってくれているサイトとなっておりますmm

https://code-step.com/demo/html/store2/

## 早速始めるための準備
今回は、手軽に手を動かしやすいように、ローカルでのガッツリした環境構築は行いません🙅‍♀️
代わりに、以下のプレイグラウンドを使用します！
(デデン！)

https://codepen.io/

**codepen**を使用していきます！(こちら、サインアップなしで使えます！)

※今回は、codepenとはなんなのかやライブラリ導入などの細かい使い方は省いていきますmm

 1. まず最初に上記リンクから、codepenを開く
 1. 次に、以下の赤枠をクリック
![スクリーンショット 2022-09-05 19.42.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319623/64307067-a6b4-a1ef-6420-12d6ae66eeb7.png)

すると、以下のような画面が表示されます！
それぞれの枠の説明は以下のような感じです。
 - 赤：HTMLのコードを書きます
 - 青：CSSのコードを書きます（つまり、デザイン(スタイル)を指定する箇所です）
 - 黄：Javascriptのコードを書きます(アニメーションをつけたりするときなどに使いますが、今回は一旦使いません🙅‍♀️)
 - 緑：書いたコードが反映される箇所です！ここで、書き終わったデザインを確認できます！

![スクリーンショット 2022-09-05 19.45.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319623/cc3d7d95-85b6-0954-1634-e0979d170390.png)


## 余白の開け方の種類
**CSS 余白**って調べると、`margin`や`padding`なんて検索結果が上の方に上がってきます。
また、`margin`や`padding`では難しい箇所については、`flex-box`というレイアウトモード(要素を整頓して配置できる素敵な箱)を使用して、要素と要素の間だけに余白をつけるといったことも可能です。
まずは初級編！`margin`や`padding`とは何か、違いはなんなのでしょうか？ 詳しく見ていきましょう！
(コードを一緒に載せるので、ぜひcodepenに貼り付けながら実際に確認してみてください👍)

### marginってなんぞ🤔
`margin`というのは、要素の外側に余白をつけます。
今回は、青い四角の中の水色の四角を配置して、水色の四角に余白をつけて確認していこうと思います！

先ほど説明した、codepenの赤い枠(HTML)に以下をコピペしてください。
```html
<div class="blue">
  <div class="skyblue">
  </div>
</div>
```
先ほど説明した、codepenの青い枠(CSS)には以下をコピペしてください。
```css
* {
  margin: 0;
  padding: 0;
}

.blue {
  background-color: blue;
}

.skyblue {
  width: 300px;
  height: 150px;
  background-color: skyblue;
}
```
まず初期状態を確認！左上によってるのがわかると思います！
![スクリーンショット 2022-09-05 21.40.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319623/9f5a3dc0-ed97-5b20-d111-7e5f7becdf30.png)



次に、青色の箱に`margin`をつけます。
以下コードをコピーして、先ほど説明した、codepenの青い枠(CSS)に以下を上書きしてください。
```css
* {
  margin: 0;
  padding: 0;
}

.blue {
  background-color: blue;
  margin: 20px;
}

.skyblue {
  width: 300px;
  height: 150px;
  background-color: skyblue;
}
```

すると、お分かりでしょうか、青色の四角の周りに余白ができました。
![スクリーンショット 2022-09-05 21.41.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319623/bb01947f-0949-e3eb-fe36-7d2fed3643ac.png)

これが、`margin`です。
主に。隣り合う要素との余白を取る時に使用します。
例えば、以下のように、青色と水色のセットをもう一個増やします。
記事序盤説明した、codepenの赤い枠(HTML)に以下をコピペしてください。
```html
<div class="blue">
  <div class="skyblue">
  </div>
</div>
<div class="blue">
  <div class="skyblue">
  </div>
</div>
```
例えば、こんな感じ。
![スクリーンショット 2022-09-05 21.42.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319623/55b7279b-06d0-3139-5cdc-15ad1695a921.png)

`margin`には、要素の中央よせの際にも利用することがあります。
例えば、先ほどのhtmlのまま水色の四角に余白をつけます。
記事序盤で説明した、codepenの青い枠(CSS)に以下をコピペしてください。
```css
* {
  margin: 0;
  padding: 0;
}

.blue {
  background-color: blue;
  margin: 20px;
}

.skyblue {
  width: 300px;
  height: 150px;
  background-color: skyblue;
  margin: 0 auto;
}
```
すると、水色の箱が中央寄せになるかと思います。
詳しくは一旦割愛しますが、`margin`は`margin: 上下 左右;`という指定ができ、
左右に`auto`と指定することで、自動で中央に寄せてくれているのです。

:::note warn
`margin`は相殺されることがあります。
例えば、上下に要素が存在し、上の要素の`margin-bottom`に`10px`の指定、
下の要素の`margin-top`に`5px`の指定を入れたとします。
この場合、上下の要素間の余白はいくつになると思いますか？

正解は、`10px`です。
`margin`の相殺が起きた結果、大きい方の値と小さい方の値が被った状態になるので、結果として大きい方の`margin`の値になります。
:::


### paddingってなんぞ🤔
`padding`というのは、`margin`とは違い、要素の中側に余白をつけるというものです。
中側に余白と言われても、いまいちわかりにくいかと思いますので、早速実際に見ていきましょう！
先ほどと同じく青い四角の中の水色の四角を配置して、青色の四角に余白をつけて確認していこうと思います！

記事序盤で説明した、codepenの赤い枠(HTML)は以下をコピペしてください。
```html
<div class="blue">
  <div class="skyblue">
  </div>
</div>
```
記事序盤で説明した、codepenの青い枠(CSS)に以下をコピペしてください。
```css
* {
  margin: 0;
  padding: 0;
}

.blue {
  background-color: blue;
}

.skyblue {
  width: 300px;
  height: 150px;
  background-color: skyblue;
}
```
すると、余白も当てていないので、青い四角の上下と左には、余白がない状態になっているかと思います。
![スクリーンショット 2022-09-05 21.49.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319623/2bc9aca8-f967-5b64-8d4e-3f722e0d9414.png)


次に、青色の四角に以下のように`padding`をつけます。
```css
* {
  margin: 0;
  padding: 0;
}

.blue {
  background-color: blue;
  padding: 20px;
}

.skyblue {
  width: 300px;
  height: 150px;
  background-color: skyblue;
}
```

すると、以下のように水色の四角の周りに余白ができているかと思います。
これが、青い四角の内側に余白をつける(つまり`padding`をつける)状態です。
![スクリーンショット 2022-09-05 21.52.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319623/4ffb0a2a-c42c-7763-acd3-05f8b756ae0c.png)

:::note warn
よく見てみると、青い枠、`padding`をつける前と後で、高さが異なっているのがわかるでしょうか？？
`padding`をつける前までは、特に高さを指定していなかったので、水色の四角と同じ高さでした。
`padding`をつけると、水色の四角の高さ+`padding`で指定した高さになります。
デザインの高さと同じに実装しているつもりが、最終的な高さが合わないという場合、
今回の見た目で言う水色に当たる部分の高さと指定されている余白を足した高さは、
本当に青い四角の高さになるのかを一度ご確認いただくと良いかと思います。
これは、四角のような要素以外にも水色の部分がテキストの場合にも、言えることですので、あらゆる要素で気を配る必要がありそうですね。
:::

### ちょっとレベルアップ！ flex-boxを使ってみよう！
「序盤で紹介したデザイン、全然使ってないじゃないの」そう思ったあなた！！
お待たせいたしました！

と言いたいところなのですが、まず`flex-box`とはなんなのかについて軽く説明していきます。

`flex-box`というのは、簡単に要素を整頓して配置できる素敵な箱です。
エンジニアっぽくいうと、短く簡潔なコードで柔軟にレイアウトを組むことができる`レイアウトモード`のことです。

今回、`flex-box`の細かい仕様については、割愛します。
(エンジニアのみなさんは、ぜひ`flex-box`の仕様を自分で調べてみてください🙇‍♀️)

が、最低限の知識として...
①横並び、縦並び、並び替えが簡単にできるよ！
②要素間の余白が簡単に指定できるよ！

を覚えていただければ、ちょっと`flex-box`触れるようになった感じになれるのではないでしょうか？！！

#### 早速、問題です。
以下のデザインの赤枠の部分、皆さんならどうやって実装しますか？？
(※今回はHTMLについては特に本腰入れて説明とかはしません)
デザインカンプは[こちら](https://xd.adobe.com/view/0a578f50-e53e-4c87-b237-b95ce8e17405-5f04/?hints=off)
![site-image-pcのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319623/8fe3551b-3901-06c9-cb44-543cc160afdc.png)


HTMLは記事序盤で説明した、codepenの赤い枠(HTML)は以下をコピペしてください。
(本当はリンクなので、`a`要素を使うなどありますが、スタイルを当てやすいよう一旦簡易的な構造でお送りいたします🙇‍♀️)
```html
<ul>
  <li>
    <img src="エラー画像" alt="商品画像" width="294" height="294">
    <p class="txt1">プロダクトタイトルプロダクトタイトル</p>
    <p>¥99,999 +tax</p>
  </li>
  <li>
    <img src="エラー画像" alt="商品画像" width="294" height="294">
    <p class="txt1">プロダクトタイトルプロダクトタイトル</p>
    <p>¥99,999 +tax</p>
  </li>
  <li>
    <img src="エラー画像" alt="商品画像" width="294" height="294">
    <p class="txt1">プロダクトタイトルプロダクトタイトル</p>
    <p>¥99,999 +tax</p>
  </li>
  <li>
    <img src="エラー画像" alt="商品画像" width="294" height="294">
    <p class="txt1">プロダクトタイトルプロダクトタイトル</p>
    <p>¥99,999 +tax</p>
  </li>
  <li>
    <img src="エラー画像" alt="商品画像" width="294" height="294">
    <p class="txt1">プロダクトタイトルプロダクトタイトル</p>
    <p>¥99,999 +tax</p>
  </li>
  <li>
    <img src="エラー画像" alt="商品画像" width="294" height="294">
    <p class="txt1">プロダクトタイトルプロダクトタイトル</p>
    <p>¥99,999 +tax</p>
  </li>
  <li>
    <img src="エラー画像" alt="商品画像" width="294" height="294">
    <p class="txt1">プロダクトタイトルプロダクトタイトル</p>
    <p>¥99,999 +tax</p>
  </li>
  <li>
    <img src="エラー画像" alt="商品画像" width="294" height="294">
    <p class="txt1">プロダクトタイトルプロダクトタイトル</p>
    <p>¥99,999 +tax</p>
  </li>
</ul>
```

ヒント：横並びには、`float:left;`を使用するか`display:flex;`を使用する選択肢があります👀


先ほど説明した、`margin`や`padding`の指定と、上記ヒントを組み合わせれば、
なんとかデザインのような形までたどり着けるかもしれません。


=== 一旦やってみよう！ できなかったら、続きを読もう！ ===



が、ここで活躍するのが、`flex-box`です。
まず、以下は`margin`など使ってゴリゴリ書いたコードです。
`li`に何やらくっつけて、なんかしてますね。
```css
* {
  margin: 0;
  padding: 0;
}
ul {
  width: 1280px;
}
li {
  list-style: none; 
  float: left;
  margin-top: 40px;
}
li:not(:first-of-type):not(:nth-of-type(5n)) {
  margin-left: 33px;
}
img {
  display: block;
  background-color: gray;
}
.txt1 {
  margin-top: 10.61px;
}
```
ちなみに、上記コードの場合、無理矢理何番目の要素というのを指定しているので、
あんまり美味しくないと思います。
今回のデザインでは起こりにくいかもですが、何番目の要素という指定の仕方は、デザインによっては要素が一個減った時や指定している番号で来るはずの要素と違うサイズ感の要素が入ってきたときにデザインが崩れる可能性がありますよね。(多分...👀)
また、何番目の要素には余白がつかないって、コードとして可読性もあまり良くない気がしますね><

次に、`flex-box`で書いたものを見ていきましょう！
```css
* {
  margin: 0;
  padding: 0;
}
ul {
  width: 1280px;
  display: flex;
  flex-wrap: wrap;
  gap: 40px 33px;
}
li {
  list-style: none; 
}
img {
  display: block;
  background-color: gray;
}
.txt1 {
  margin-top: 10.61px;
}
```

`ul`に`display:flex;`で`flex-box`を指定し、`flex-wrap: wrap;`で端っこまで来たら折り返してねの指定、`gap: 40px 33px;`で縦に見た時の要素間の余白には`40px`、横に見た時の要素間の余白には`33px`指定してねという指定を入れています。

すると、細かい「何番目の要素は〜」というような指定を入れずとも、綺麗に余白が入ったのが確認できるかと思います！

そんな柔軟な`flex-box`にも、指定が難しい場合があるのですが、それも今回は割愛させていただきますので、実際に壁にぶち当たった際には色々試してみてください！

## まとめ
ぜひ、以下覚えておいてください🌟
 - `margin`は要素の外側につける余白
 - `padding`は要素の内側につける余白
 - `padding`をつけた要素の高さは、中の要素 + `padding`になる
 - ややこしい指定なしにレイアウトを指定できる`flex-box`


マークアップをしていて、余白をどう指定するかに迷うことは最初はよくあるかと思います。
(実際、自分は今でもたまに迷うことあります。)

そういうときは、それぞれの余白の特徴と得意なこと、コーディングしているデザインではどの余白の取り方が、実装的に、デザイン的に、挙動的に、運用的により良いかなを考えて選択できるといいですね👍

## 参考
この記事は、以下の記事を参照しています。
[余白](https://ja.wikipedia.org/wiki/%E4%BD%99%E7%99%BD)

=== 終わり. ===