テック技報最新号へ →
CSS

margin 付きの全幅ボタンは width: 100% ではなく width: stretch にする

width: stretch は「margin を引いた残りの幅」いっぱいに広がるので、margin を付けた全幅ボタンがカードからはみ出さない。

@sanyampunia · 投稿 2026-11-07

どんな時に使う?

カードの下部に「購入する」のような横幅いっぱいのボタンを置き、周りに margin で余白を取りたいとき。width: 100% は親の幅そのものを要素の幅にするため、そこに左右の margin が足されて右側にはみ出す。calc(100% - 32px) と書けば直せるが、margin を変えるたびに計算も直す必要がある。

stretch は要素の margin box を親(包含ブロック)の幅に合わせる指定なので、margin の値が変わっても自動で残りの幅に収まる。

コード

css
.card button {
  display: block;
  margin: 16px;
  /* 古い Safari / Chrome 向けの接頭辞版 */
  width: -webkit-fill-available;
  /* Firefox 向けの接頭辞版 */
  width: -moz-available;
  /* 標準。対応ブラウザではこれが勝つ */
  width: stretch;
}
指定幅の決まり方margin 16px のとき
width: 100%親の幅そのもの(box-sizing の基準の箱に適用)親より 32px 広くなり、はみ出す
width: calc(100% - 32px)手計算で margin 分を引く収まるが、margin を変えると壊れる
width: stretchmargin を除いた残りの幅いっぱい自動で収まる

flex アイテムに付けると、内容の幅ではなく使える幅いっぱいに広げることもできる(height: stretch も同様)。

注意点・対応状況

  • 標準の stretch は Chrome / Edge 138+(2025-06)、Safari 27+(2026-09)。Firefox は標準キーワード未対応で、Baseline には未到達(Limited availability)。
  • そのため上の例のように -webkit-fill-available → -moz-available → stretch の順で重ねて書くのが実用的。ブラウザは理解できない値の宣言を捨て、最後に理解できたものを使う。
  • display: block の要素は width: auto でも margin を引いた幅に広がる。stretch が効いてくるのは、button や inline-block・flex アイテムのように auto だと内容の幅に縮む 要素。

出典

X の元の投稿を開く