“なんとなく”で使わない
inline-block

2016-05-20 pixiv社内勉強会 LT

@hakatashi

inline-block

ちゃんと理解してますか?

“なんとなく”で
使ってませんか???

たとえばこういう案件

display: inline-block;

「おっこれ

でいけんじゃん」

正しく理解して
正しく使おう

第1章

inline-blockとは

は、ひとことで言うと
inline要素と
block要素の中間

display: inline-block;

display: inline-block; は
inlineレベルの要素を形成する

理解してないとハマる

事例1: inline-blockによる
要素の横並び

<div class="wrap">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>
.item {
  display: inline-block;
  width: 80px;
  height: 60px;
  background: darkcyan;
}

何pxかの隙間ができる

[CSS 横並び]とかでググると
このinline-blockを使った方法が出てくる

謎じゃない!!!!!!!!

は、ひとことで言うと

display: inline-block;

「でかい1文字」

これは……

<div class="wrap">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

こう書いてるのと同じ

<div class="wrap">
  A
  A
  A
  A
</div>
<div class="wrap">
  A
  A
  A
  A
</div>

HTML上の文字間の空白文字や改行は、
表示される際にスペースひとつに置き換えられる

この挙動は white-space 属性で制御される

さっきのは、仮想的にこういう状態

つまり、この「謎の隙間」はスペース文字1つぶんの空白
文字サイズやフォントによって幅が左右される!!!

<div class="wrap">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>
.wrap {
  width: 350px;
  padding: 5px;
  text-align: justify;
  text-align-last: justify;
  background: skyblue;
  
  .child {
    display: inline-block;
    height: 50px;
    vertical-align: bottom;
    background: darkcyan;
    
    &:nth-child(3n+1) {width: 60px;}
    &:nth-child(3n+2) {width: 80px;}
    &:nth-child(3n+3) {width: 30px;}
  }
}

「文字」なので
text-align: justify; で
均等割り付けもできる

<div class="wrap">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>
.wrap {
  white-space: pre-line;
}

.item {
  display: inline-block;
  width: 80px;
  height: 60px;
  background: darkcyan;
}

white-spaceの値を変更すると
横に並びすらしなくなる

要点 1

inline-blockは
「でかい1文字」

第2章

vertical-alignとは

事例2: inline-blockの
折り返し

<div class="wrap">
  <div class="small"></div>
  <div class="big"></div>
  <div class="small"></div>
</div>
.wrap {
  padding: 5px;
  width: 300px;
  font-size: 0;
  background: skyblue;
  
  & > div {
    display: inline-block;
    width: 100px;
    vertical-align: top;
  }
  
  .small {
    height: 50px;
    background: darkcyan;
  }
  
  .big {
    height: 100px;
    background: green;
  }
}

横幅300pxの要素に
横幅100pxのinline-block要素が
3つ詰め込まれている

これにもう1つ
.small を詰め込んだら
どこに来る?

ここです。

謎じゃない!!!!!!!!!!!!!!!

「文章」には
「流れ」が存在する

  • 横方向に進み、
  • 端まで来たら折り返して
    次の行に向かう

この一連の「流れ」のことを、CSSでは

inline formatting context

と呼ぶ。

inline要素と
block要素の違いは、

この inline formatting context の流れの中に
「存在するか」
「存在しないか」

の違いである。

inline-blockは
inline要素なので、
inline formatting context の
中に存在する

図示するとこうなる

それぞれのinline-blockは、
本当にただの文字だと思ったほうがいい。

inline-blockは「行」を形成し、
端まで行ってあふれたinline-blockは
折り返して次の行に進む。

要点 2

inline-blockは
「行」を形成する

この「行」内でのinline要素の
位置を決定するのが
vertical-align属性

なんでもかんでも
「縦方向に揃える」属性ではない

block要素に指定してもまったく無意味

要点 3

vertical-alignは
「行」内での位置を
決める

第3章

文字を含むinline-blockの挙動

<div class="wrap">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>
.wrap {
  display: inline-block;
  padding: 5px;
  background: skyblue;
}
  
.item {
  display: inline-block;
  width: 100px;
  height: 100px;
  background: darkcyan;
}

inline-blockが空っぽなら
普通の横並びになる

<div class="wrap">
  <div class="item"></div>
  <div class="item">hogehoge</div>
  <div class="item"></div>
</div>

テキストが入ると
どうなる?

!?!?!?!?!?

……謎じゃない!!

vertical-align属性の
初期値は、

vertical-align: baseline;

baselineとは、
アルファベットを記述する際の
「基準線」

テキストを含む要素では
最終行のbaselineが
その要素のbaselineとなる

baseline

テキストを含まない要素には
baselineは存在しない

vertical-alignの仕様によると、

baseline

Align the baseline of the box with the baseline of the parent box. If the box does not have a baseline, align the bottom margin edge with the parent's baseline.

※下線引用者

仮想的に要素の下端
その要素のbaselineとなる

baseline

要素ごとのbaselineを揃えるとこうなる

キモい!!!

<div class="wrap">
  <div class="item"></div>
  <div class="item">hogehoge</div>
  <div class="item"></div>
</div>
.wrap {
  display: inline-block;
  padding: 5px;
  background: skyblue;
}
  
.item {
  display: inline-block;
  width: 100px;
  height: 100px;
  vertical-align: bottom;
  background: darkcyan;
}

vertical-alignに
baseline以外の値を指定すると
ちゃんと横に並ぶ

要点 4

vertical-alignの
初期値は
すごくキモい

まとめ

  1. inline-blockは「でかい1文字」
  2. inline-blockは「行」を形成する
  3. vertical-alignは「行」内での位置を決める
  4. vertical-alignの初期値はすごくキモい

一番重要なこと

inline-blockでできることは
だいたいflexboxでできる

inline-blockが真価を発揮するのは
まさしく要素を「文字のように」扱いたいとき

Emojiの画像polyfillやiconなど

flexboxが使える21世紀において
レイアウト用途にinline-blockを
使用するべきではない

よいinline-blockで
よいCSSライフを

おわり

なんとなくで使わないinline-block

By Koki Takahashi

なんとなくで使わないinline-block

2016-05-20 pixiv社内勉強会 LT

  • 2,165