インライン要素とブロックレベル要素を完全に理解する

# なぜこの記事を書いたか
最近Webサイトのリニューアル案件をやっていて、ひたすらフロントコーディングしてるのですが、この辺ちゃんと理解していなかったし、ggってもイマイチな感じの記事だけだったので、思い切って書いてみました。

[ここ](https://developer.mozilla.org/ja/)を参考にして基本のおさらいと実践みたいなことをできれば。

# インライン要素とブロックレベル要素
HTMLにはたくさんタグがあるが、これらは「インライン要素」と「ブロックレベル要素」の二つに大別されます。
表面的には幅の考え方の違いとか改行の有無とかという話です。ただ、この理解があやふやな状態で、適当にタグ使っているとCSSがうまく効かないんだけど、みたいなことが発生します。

## インライン要素とは
[これ](https://developer.mozilla.org/ja/docs/Web/HTML/Inline_elements)の冒頭より重要な点は以下二つ

* インライン要素は、コンテンツの流れを分断せずに、要素を定義するタグで囲まれた範囲だけを占有するものです。
* インライン要素は新しい行から始まらず、必要な幅のみを占有します。

わかるようなわからないようなという具合ですが、多分この後のブロックレベル要素と比較したほうが理解がしやすいと思うので次に進みましょう。

## ブロックレベル要素とは

[これ](https://developer.mozilla.org/ja/docs/Web/HTML/Block-level_elements)冒頭より重要な点は以下二つ

* ブロックレベル要素は親要素 (コンテナー) の領域全体を占有して、「ブロック」を生成します。
* ブロックレベル要素は常に新しい行から始まり、利用可能な全幅を取ります (できる限り左右に伸びます)。

インライン要素と比較してみると少し理解しやすくなったとは思いますが、もう一声欲しい感じですね。

## 具体例で比較してみる
上記について、インライン要素であるspanとブロックレベル要素であるdivを実例を用いて比較してみましょう。結果は以下の通り。

<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="html,result" data-user="gitk47320" data-slug-hash="GRpqoMN" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="GRpqoMN">
  <span>See the Pen <a href="https://codepen.io/gitk47320/pen/GRpqoMN">
  GRpqoMN</a> by gitk47320 (<a href="https://codepen.io/gitk47320">@gitk47320</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

インライン要素二つとブロック要素二つから見てみます。spanかdivの違いだけですが、表示自体は大きく違っています。インライン要素は横並びですが、ブロック要素は2行に分かれています。また、インライン要素は背景色がついているのは文字がある箇所だけですが、ブロック要素は横幅一杯についています。

後半は文中のあるテキストに対してspanとdivどちらが定義されているかが違います。上記からなんとなく挙動は分かると思いますが、spanのほうはタグで囲まれた範囲で背景色がついていますが、divは改行された挙句、横幅一杯に背景色がついてしまっています。

実際のコード、それに対する挙動からも冒頭に紹介した以下の仕様が直感的にわかります。

* インライン要素は、コンテンツの流れを分断せずに、要素を定義するタグで囲まれた範囲だけを占有するものです。
* インライン要素は新しい行から始まらず、必要な幅のみを占有します。
* ブロックレベル要素は親要素 (コンテナー) の領域全体を占有して、「ブロック」を生成します。
* ブロックレベル要素は常に新しい行から始まり、利用可能な全幅を取ります (できる限り左右に伸びます)。

# displayプロパティの理解
次にCSSのdisplayプロパティについて簡単に取り上げます。
## inline,block
[ここ](https://developer.mozilla.org/ja/docs/Learn/CSS/CSS_layout/Introduction)の「displayプロパティ」項に記載があります。
この記載に注目。

>このような display のデフォルトのふるまいは変更できます。 例えば、&lt;li&gt; 要素はデフォルトで display: block です。 つまり、英語の文書ではリスト項目は上下に表示されます。 display の値を inline に変更した場合、単語が文中で行うように、それらは互いに隣接して表示されます。

これを見ると、htmlタグとしてはインライン要素であっても、CSSのdisplayプロパティでblockをセットすればblockと同じ振る舞いができる、というようにも読み取れます。先ほどの例を少しいじってみましょう。

<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="html,result" data-user="gitk47320" data-slug-hash="gOaMrMe" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="gOaMrMe">
  <span>See the Pen <a href="https://codepen.io/gitk47320/pen/gOaMrMe">
  gOaMrMe</a> by gitk47320 (<a href="https://codepen.io/gitk47320">@gitk47320</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


先ほどインラインとして表示されていたものがブロックレベルに、またはその逆になっています。
ちなみに、ただ、このような使い方は実際はやめた方がいいです。コードの可読性悪くなるし、保守もしにくいので。

## inline-blockとは
一言で言うと、inlineとblock両方の特徴を要素に設定できます。どういうことでしょうか。もう少し探ってみます。

例によって例のごとく[ここ](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/The_box_model#Types_of_CSS_boxes)の「Using display:inline-block」を参照しましょう。ちなみにここは英語なので注意。特に以下の記述。

>This is useful for situations where you do not want an item to break onto a new line, but do want it to respect width and height and avoid the overlapping seen above.

「改行したくないけど幅や高さをセットしたいというときに役立つ」的な事が書いてあります。幅とか高さってwidth,heightで設定するもんじゃないの、と思うかもしれませんが、実はinline要素はwidthやheightを指定できません。

<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="html,result" data-user="gitk47320" data-slug-hash="ExVyKXy" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="ExVyKXy">
  <span>See the Pen <a href="https://codepen.io/gitk47320/pen/ExVyKXy">
  ExVyKXy</a> by gitk47320 (<a href="https://codepen.io/gitk47320">@gitk47320</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

上記ではインライン要素にwidth,heightを設定していますが、その設定が効いていません。でもブロックレベル要素の方には効いていますね。理由はこちらの仕様に従っているから、ということになります。必要な幅というのはあくまでタグで囲まれた分の幅ということになるので、width等でその囲まれた分を変更するのはできないよ、と解釈できます。

* インライン要素は新しい行から始まらず、必要な幅のみを占有します。

一方ブロックレベル要素は、こちらの仕様に従っているから、となりますね。できる限りというのはCSSで色々と調整した「できる限り」とも読めます。

* ブロックレベル要素は常に新しい行から始まり、利用可能な全幅を取ります (できる限り左右に伸びます)。