CSS

on Note

flex-basis flexアイテムのコンテンツ幅及び高さを定義する

flex-basisでは、flexアイテムのコンテンツ領域の横幅や高さを定義します。flex-growなどが適用される前の、初期の寸法を定義するプロパティです。

「basis」は「基礎」や「基準」といった意味で、flex-basisではflexアイテムの基準の横幅または高さを定義します。

ここでは、flex-basisプロパティの概要から、実際にflex-basisを使用した場合の見本までを記事にしています。ただ、横幅と高さ、両方に触れながらでは混乱しますので、まずは横幅の定義にフォーカスして説明しています。

flex-basisプロパティの概要

flexアイテムにflex-basisプロパティを指定することで、そのflexアイテムのコンテンツ横幅や高さを定義することができます。

書式
flex-basis: 値;
初期値
auto(そのままコンテンツ分の幅になる)
値の指定
数値と単位
数値とパーセント
継承
しない
指定先
flexアイテム

flex-basisを指定する

メニューリストにdisplay: flex;を適用してメニューそれぞれが横並びになるパターンで説明していきます。HTMLは次のように書きます。

<ul class="flex_container">
    <li>メニュー</li>
    <li>メニュー</li>
    <li>メニュー</li>
</ul>

li要素にflex-basisプロパティを適用します。値は「100px」にします。わかりやすくする為に余白や枠線も指定しています。

.flex_container {
    display: flex;
    background-color: #eee;
    list-style-type: none;
}
.flex_container li {
    flex-basis: 100px;
    padding: 5px;
    border: solid 1px #888;
    background-color: #ffb;
}

表示結果は次のようになります。

  • メニュー
  • メニュー
  • メニュー

各メニューのコンテンツ幅が100pxになりました。ただ今回の例では、padding: 5px;border: solid 1px #888;も同時に指定しています。余白と枠線もつけたわけです。それによって、li要素の横幅はというと112pxになりました。

flex-basisはあくまでコンテンツ幅を定義するプロパティです。なので今回の li要素の横幅は、下の図のように、flex-basis: 100px;よりも余白と枠線の分プラスされた幅になります。

余白や枠線を持ったli要素全体の横幅。
li要素全体の幅のイメージ

box-sizing: border-box;でボーダーまで含めた幅とする

flex-basisの値は、flexアイテムのコンテンツ幅に対してのものです。なのでパディングやボーダーを指定すると、その分大きくなります。

ここで、box-sizing: border-box;も同時に指定すると、この問題を解決できます。box-sizing: border-box;を指定することで、ボーダーまでを含めたものになるわけです。

先ほどと同じHTMLを使って説明します。

<ul class="flex_container">
    <li>メニュー</li>
    <li>メニュー</li>
    <li>メニュー</li>
</ul>

flexアイテムにbox-sizing: border-box;も指定します。

.flex_container {
    display: flex;
    中略
}
.flex_container li {
    flex-basis: 100px;
    box-sizing: border-box;
    padding: 5px;
    border: solid 1px #888;
    中略
}

これで、paddingborderの幅も含めた、li要素の横幅が100pxとなります。

  • メニュー
  • メニュー
  • メニュー

個々のflex-basisを異なる値にすると

flexアイテムごとに flex-basisプロパティの値を変えてみます。

<ul class="flex_container">
    <li>メニュー</li>
    <li>メニュー</li>
    <li>メニュー</li>
</ul>
.flex_container {
    display: flex;
    中略
}
.flex_container li {
    box-sizing: border-box;
    padding: 5px;
    border: solid 1px #888;
    中略
}
.flex_container li:nth-of-type(1) {
    flex-basis: 20%;
}
.flex_container li:nth-of-type(2) {
    flex-basis: 30%;
}
.flex_container li:nth-of-type(3) {
    flex-basis: 50%;
}

擬似クラスを使って、各li要素のflex-basisプロパティに異なる値を指定しました。flexコンテナに対する、各flexアイテムの割合が異なることになります。1番目のli要素はul要素に対して「20%」、2番目のli要素は「30%」、3番目のli要素は「50%」の横幅です。

  • メニュー
  • メニュー
  • メニュー

flex-basisとwidthの違い

要素の幅を指定するプロパティにwidthがあります。flex-basiswidth、双方ともコンテンツの幅を定義するプロパティですし、box-sizing: border-box;を指定した場合の挙動も同じです。値の指定方法にも違いはありません。ではどこが違うのでしょうか。

flex-basisプロパティでは、flexアイテムの幅と高さ、どちらの指定も可能ですが、widthプロパティは幅を定義するものです。同様に高さを定義したい場合は heightプロパティを使うことになります。

widthで上書きできない

flex-basisプロパティで幅を定義したflexアイテムに対して、widthで上書きをしようとしてもそれはできません。例え、widthプロパティが優先されるようにwidthを後に書いても、flex-basisが優先されます。

<ul class="flex_container">
    <li>メニュー</li>
    <li>メニュー</li>
    <li>メニュー</li>
</ul>
.flex_container {
    display: flex;
    中略
}
.flex_container li {
    flex-basis: 100px;
    中略
}
.flex_container li {
    width: 200px;
}

flex-basis: 100px;と指定したflexアイテムに、widthで200pxに上書きしても、表示は次の通り、コンテンツ幅100pxのままです。

  • メニュー
  • メニュー
  • メニュー

横幅と高さのどちらを定義するかはflex-directionの値による

flex-basisプロパティの効果は、flexコンテナの主軸の方向(つまりflexアイテムが並ぶ方向)に関係します。flexコンテナの主軸の方向は、flex-directionプロパティで定義します。flex-directionの値が「row」ならば左から右への水平軸とし、「column」ならば上から下への縦軸とします。

よって、flexコンテナに flex-direction: column; を指定すると、flex-basisの値はflexアイテムの高さを定義することになります。

この記事でのこれまでの例ではflex-directionは指定しませんでした。flex-directionプロパティの初期値が「row」なので、主軸がデフォルトで水平方向となり、結果、flex-basisの値は幅を定義したものになっていたわけです。

flex-basisで高さを指定する

flexコンテナにflex-direction: column;を指定して主軸を縦方向とし、flex-basisで高さを指定します。

<ul class="flex_container">
    <li>メニュー</li>
    <li>メニュー</li>
    <li>メニュー</li>
</ul>
.flex_container {
    display: flex;
    flex-direction: column;
    中略
}
.flex_container li {
    flex-basis: 70px;
    中略
}

この場合は次のように表示されます。

  • メニュー
  • メニュー
  • メニュー

flex-direction: column;の指定でflexコンテナの主軸が縦方向となり、flexアイテムは縦に並びます。よって必然的に、今回のflex-basisプロパティは高さを定義することになります。

このままだと li要素は横幅いっぱいに広がった状態です。この状態で各 li要素の幅も縮めたいとした時、その場合はwidthプロパティで横幅を指定します。

次のように、flexアイテムにwidth: 100px;を加えます。

.flex_container {
    display: flex;
    flex-direction: column;
    中略
}
.flex_container li {
    flex-basis: 70px;
    width: 100px;
    中略
}

次のように表示されます。

  • メニュー
  • メニュー
  • メニュー

li要素のコンテンツの幅が100pxになりました。

まとめ

flex-basisプロパティでは、flexアイテムのコンテンツの幅や高さを定義します。指定はflexアイテムで行います

flex-basis: 値;の形で書き、値には、単位付きの数値、または数値とパーセントの形で指定します。

flex-basisプロパティは本来、コンテンツに対して幅や高さを定義するもので、flex-basisの値はコンテンツ領域に対する数値となります。よってパディングやボーダーは含まれません。ただ、flexアイテムに同時にbox-sizing: border-box; を指定すれば、flex-basisプロパティの値を、ボーダーまで含めたものとすることができます。

flexアイテムにflex-direction: column; を指定してアイテムの並びを縦方向とした時、flex-basisの値はアイテムの高さに対するものとなります。