CSSのflex-basisとwidthで幅が変わるのはどんなときか
flex アイテムの幅は、flex-basis で決めても width で決めても、伸びるときと縮むときの幅はほとんど同じになります。違いが出るのは、URL や長い英単語のような折り返せない中身が、指定した幅より長いときです。width は指定した幅を守って中身をはみ出させ、flex-basis は中身の幅まで広がります。横並びのカードやサイドバーの幅を決めるときに、どちらを書けばよいかの判断に使えます。
検証環境は Ubuntu 24.04、Node.js 22.23.4、Playwright 1.63.0、Chromium 153 です。HTML と CSS だけのページを Playwright で開き、getBoundingClientRect() で要素の幅を測りました。フォントは Noto Sans CJK JP の 16px で、アイテムには box-sizing: border-box を付けています。Firefox と Safari は試していません。
伸びるときも縮むときも、幅の計算は同じだった
2つのアイテム a と b を横に並べて、width で大きさを決めた場合と flex-basis で決めた場合を比べました。
<div class="row">
<div class="a">A</div>
<div class="b">B</div>
</div>
.row {
display: flex;
width: 600px; /* 縮むときは 300px */
}
.a {
width: 100px; /* ここを flex-basis: 100px に変えて比べる */
}
伸びるときは、行の幅を 600px にして、a と b に flex-grow: 1 を付けました。縮むときは、行の幅を 300px にして、flex-shrink は初期値の 1 のままにしました。
| 場面 | a と b に付けた指定 | a の幅 | b の幅 |
|---|---|---|---|
| 伸びる(行 600px) | a:width: 100px、b:width: 200px |
250px | 350px |
| 伸びる(行 600px) | a:flex-basis: 100px、b:flex-basis: 200px |
250px | 350px |
| 伸びる(行 600px) | a:width: 100px、b:flex-basis: 200px |
250px | 350px |
| 縮む(行 300px) | a:width: 400px、b:width: 200px |
200px | 100px |
| 縮む(行 300px) | a:flex-basis: 400px、b:flex-basis: 200px |
200px | 100px |
| 縮む(行 300px) | a:width: 400px、b:flex-basis: 200px |
200px | 100px |
どちらで書いても、混ぜて書いても、幅は同じでした。伸びるときは、余った 300px を半分ずつ足して 250px と 350px です。縮むときは、はみ出した 300px を元の大きさの比 2:1 で割り振り、a が 200px、b が 100px 縮みました。
同じになるのは、flex-basis の初期値が auto だからです。Flexbox の仕様にある flex-basis の auto の定義では、auto のときは並べる向き(主軸)の大きさのプロパティ、つまり横並びなら width、縦並び(flex-direction: column)なら height の値が、伸び縮みの元になる大きさとして使われます。width: 100px だけを書いても、flex-basis: 100px と書いても、計算の出発点は同じ 100px になります。
両方を書くと flex-basis が勝つ
同じアイテムに width と flex-basis を両方書いたときは、flex-basis の値で幅が決まりました。行の幅は 600px で、flex-grow は初期値の 0 です。
| 書いた指定 | 幅 |
|---|---|
width: 300px だけ |
300px |
width: 300px; flex-basis: 100px |
100px |
flex-basis: 100px; width: 300px(順番を入れ替え) |
100px |
width: 100px; flex-basis: 300px |
300px |
width: 300px; flex-basis: auto |
300px |
width: 300px; flex-basis: content |
9.7px |
書く順番を入れ替えても、結果は変わりませんでした。別のプロパティなので、後に書いたほうが勝つという話ではありません。MDN の flex-basis の説明にも、flex-basis が auto 以外で width も設定されているときは flex-basis が優先される、とあります。flex-basis: content にすると width は使われず、中身の「A」1文字の幅(9.7px)になりました。
中身が長いと、width ははみ出し、flex-basis は広がる
違いが出たのは、アイテムの中身が指定した幅より長いときです。a の中身を折り返せない URL(https://example.com/articles/2026、幅 257.8px)にして、a に 150px を指定しました。行の幅は 600px で、flex-grow は初期値の 0 なので、a は伸びない設定です。

| a に付けた指定 | a の幅 | 中身が a の枠からはみ出すか |
|---|---|---|
width: 150px |
150px | はみ出す |
flex-basis: 150px |
257.8px | はみ出さない |
flex-basis: 150px; min-width: 0 |
150px | はみ出す |
flex-basis: 150px; overflow: hidden |
150px | はみ出す(見えなくなる) |
width: 150px では、a は 150px のままで、URL は枠の外へはみ出して隣の b に重なりました。flex-basis: 150px では、伸びない設定なのに a が URL の幅の 257.8px まで広がりました。
この差は、flex アイテムの min-width の初期値 auto から来ています。Flexbox の仕様の自動最小サイズでは、flex アイテムが狭くなれる下限を、中身をいちばん細くした幅にしています。ただし、width(縦並びなら height)に幅が指定されていれば、下限はその幅で頭打ちになります。この頭打ちに使われるのは width だけで、flex-basis の値は使われません。
width: 150pxのとき:下限は、中身の 257.8px とwidthの 150px のうち小さい 150px。a は 150px より広がらないので、中身がはみ出すflex-basis: 150pxのとき:widthはautoなので、下限は中身の 257.8px。150px から始まっても下限に引き上げられ、257.8px になる
flex-basis のまま 150px に収めたいときは、min-width: 0 で下限を取り払います。overflow: hidden を付けた場合も、仕様にあるとおり下限が 0 になり、150px になりました。ただしこちらは、はみ出した URL の後半が見えなくなります。min-width: 0 で直すときの注意点は、別の記事「CSSのflexで子要素のはみ出しをmin-width: 0で直す方法」で確かめています。
行の幅を変えると、伸び縮みする範囲がずれる
a と b の両方に flex-grow: 1 と flex-shrink: 1 を付けて、伸びも縮みもする設定にしました。a の中身は上と同じ URL、b の中身は「B」です。2つに同じ 150px を width で付けた場合と flex-basis で付けた場合で、行の幅を 100px から 700px まで 25px ずつ変えて、a の幅を測りました。

| 行の幅 | width: 150px のときの a |
flex-basis: 150px のときの a |
|---|---|---|
| 200px | 150px | 257.8px |
| 300px | 150px | 257.8px |
| 400px | 200px | 257.8px |
| 500px | 250px | 257.8px |
| 550px | 275px | 275px |
| 700px | 350px | 350px |
行が広いときは、どちらも行の幅のちょうど半分になりました。元の大きさがどちらも 150px なので、余った幅を半分ずつ受け取るからです。
狭くなっていくと、width のほうは行の幅 300px で 150px に達し、それより狭くしても 150px から縮みませんでした。下限が width の 150px だからです。flex-basis のほうは、行の幅が 515.6px(257.8px の2倍)より狭くなると、半分の幅が中身の 257.8px を下回るので、257.8px で止まりました。25px 刻みの測定では、500px で 257.8px、525px で 262.5px でした。行の幅 400px では、width なら 200px ですが、flex-basis なら 257.8px です。同じ 150px を指定していても、狭い画面では幅が変わります。
縦並びでは、flex-basis は高さになる
flex-direction: column で縦に並べると、2つの違いはもっとはっきりします。コンテナーの幅を 600px、高さを 400px にして、a に指定を1つだけ付けました。
.row {
display: flex;
flex-direction: column;
width: 600px;
height: 400px;
}
.a {
width: 100px; /* ここを flex-basis: 100px や height: 100px に変えて比べる */
}
| a に付けた指定 | a の幅 | a の高さ |
|---|---|---|
width: 100px |
100px | 24px |
flex-basis: 100px |
600px | 100px |
height: 100px |
600px | 100px |
width: 100px は、縦並びでもそのまま横幅に効きました。一方、flex-basis: 100px は高さの 100px になり、height: 100px と同じ結果です。このとき幅が 600px なのは、横幅を指定していない a がコンテナーの幅いっぱいに広がったためです。仕様の主軸の大きさ(main size)の定義のとおり、flex-basis は並べる向き(主軸)の大きさを決めるので、横並びなら幅、縦並びなら高さになります。width は向きに関係なく、いつも横幅です。
max-width はどちらにも効く
max-width: 200px と一緒に書くと、width: 400px でも flex-basis: 400px でも flex: 1 でも、幅は 200px で止まりました。上限を決めたいときは、width と flex-basis のどちらを使っていても max-width が使えます。
どちらを書くかの目安
中身が長いときに中身に合わせて広がってほしいなら flex-basis、指定した幅より広がってほしくないなら width が向いています。ただし width でも、flex-grow を付けていれば余った幅の分だけ伸び、行の幅が足りなければ(flex-shrink の初期値 1 のまま)縮みます。また、はみ出した中身の扱いは別に決める必要があります。なお MDN では、flex-basis を単独で書くより、flex の一括指定を使うことが勧められています。flex の一括指定の展開のされ方は、別の記事「CSSのflex: 1は何の略かと、要素が伸び縮みするしくみ」で確かめています。





