概要
display: inlineまたはdisplay: inline-blockの要素間に意図しない余白が生じる。これはHTMLの仕様上の挙動である。
display: inlineまたはdisplay: inline-blockの要素間に意図しない余白が生じる。これはHTMLの仕様上の挙動である。
以下の条件で発生する。
displayがinlineまたはinline-block(<span>、<a>、<img>、<iframe>など)<ul class="nav">
<li>ホーム</li>
<li>製品</li>
<li>お問い合わせ</li>
</ul>
.nav li {
display: inline-block;
padding: 10px 20px;
background: #eee;
}
このコードでは各<li>要素の間に数pxの隙間が生じる。
HTMLでは要素間の改行・空白・タブはテキストノードとして解釈される。
<li>ホーム</li>
<li>製品</li>
<li>お問い合わせ</li>
上記の</li>と<li>の間にある改行とインデントは、ブラウザで空白文字として認識される。インライン要素はテキストと同じ文脈で描画されるため、この空白文字が単語間スペースとして表示される。
空白の幅は親要素のfont-sizeとfont-familyに依存する。
FlexboxやGridが主流の現在でも、以下の状況で発生する。
| ケース | 具体例 |
|---|---|
| レガシーコードの保守 | 既存プロジェクトでinline-blockレイアウトが残っている |
| テキストとの混在 | 文中にアイコンやバッジをインラインで配置 |
| 既存CSSフレームワークの利用 | 古いフレームワークやライブラリに依存 |
| 意図的な使用 | テキストの折り返しに追従させたい場合など |
フレックス/グリッドコンテナでは空白テキストも匿名アイテムとして生成されるが、折り畳まれるため視覚的な隙間が発生しない。
.nav {
display: flex;
}
横並びレイアウトであれば、この方法を優先するとよい。
font-size: 0 を指定空白文字の幅を0にする方法である。ただし、子要素でfont-sizeを再指定する必要がある。
これは古くからある方法で、FlexboxやGridが普及する前によく使われていた。
.nav {
font-size: 0;
}
.nav li {
display: inline-block;
font-size: 16px; /* リセット */
}
空白の幅はfont-sizeに依存するため、これで解消できる。
注意点
emや%で指定されたフォントサイズは継承により0になるため、絶対値での再指定が必要line-heightなど)に注意が必要ソースコード上で空白がなければ発生しない。
要素を1行で記述:
<ul class="nav"><li>ホーム</li><li>製品</li><li>お問い合わせ</li></ul>
コメントで改行を吸収:
<ul class="nav">
<li>ホーム</li><!--
--><li>製品</li><!--
--><li>お問い合わせ</li>
</ul>
終了タグの省略(<li> の場合は有効):
<ul class="nav">
<li>ホーム
<li>製品
<li>お問い合わせ
</ul>
仕様上は有効だが、静的解析ツールや可読性の観点から、実務では避けるのが無難である。
いずれも可読性が低下するため、手動での記述は推奨されない。ただし、ビルドプロセスでテンプレートを自動圧縮する環境であれば、出力HTMLとして使用する選択肢はある。
| 方法 | メリット | デメリット |
|---|---|---|
| Flexbox / Grid | クリーン、副作用なし | レイアウトモデルが変わる |
font-size: 0 | 既存構造を維持できる | 子要素でリセットが必要 |
| HTML空白除去 | CSS変更不要 | 可読性が著しく低下 |
inlineおよびinline-block要素間の空白問題は、HTMLが空白文字をテキストノードとして扱う仕様に起因する。現在ではFlexboxやGridの普及により遭遇頻度は減ったものの、レガシーコードの保守やインライン要素を意図的に使う場面では依然として発生する。
新規実装であればdisplay: flexまたはdisplay: gridを採用することを推奨する。既存コードへの対処が必要な場合は、コードの文脈に応じてfont-size: 0やHTML修正を検討するとよい。