Flexアイテムで垂直方向のmarginやpaddingの描画がブラウザによって異なる

Flexboxでレイアウトをしているときに、 ガターempx などの固定値を指定するのではなく、 % 値を指定したいときに起きる問題です。

ブラウザの差異


<div class="grid">
  <div class="item">
    <div class="inner">1</div>
  </div>
  <div class="item">
    <div class="inner">2</div>
  </div>
</div>

.grid {
  display: flex;
  width: 500px;
}
.item {
  padding-top: 10%;
  padding-right: 10%;
  width: 50%;
  background-color: #c4ddb9;
}
.inner {
  background-color: #a1c6e7;
}

分かりやすいように簡単なHTMLとCSSを用意しました。これを各ブラウザで表示すると以下のようになります。

IEやChrome では padding-top: 10%; が描画されていますが、 EdgeやFirefox では描画されていません。実際には EdgeやFirefox でも描画されています。IEやChromeでは垂直方向の padding要素の横幅 を基準に計算されるのに対し、EdgeやFirefoxでは 要素の高さ を基準に計算されてしまうためです。ちなみに Flexアイテム だけでなく Gridアイテム でも同じ現象が起きます。

解決策


.grid {
  display: flex;
  margin: 0 auto;
  max-width: 500px;
}
.item {
  padding-right: 10%;
  width: 50%;
  background-color: #c4ddb9;
}
.item::before {
  display: block;
  padding-top: 20%;
  content: '';
}
.inner {
  background-color: #a1c6e7;
}

Flexアイテム ではなくその子要素であればこの問題は発生しないので、 擬似要素 を使って padding-top を指定しています。CSSでアスペクト比を固定するテクニックと同じような仕組みですね。