フレックスアイテムのサイズ
フレックスアイテムのサイズは、flex-grow
、flex-shrink
、flex-basis
の3つのプロパティによって決まります。
flex-basis
flex-basis は、フレックスアイテムの初期サイズ(ベースサイズ)を指定するプロパティです。 このプロパティは、flex-growやflex-shrinkが適用される前の、アイテムの理想的なサイズを定義します。
.flex-item {
flex-basis: 200px; /* 初期サイズを200pxに設定 */
}
flex-basis の値
auto
(デフォルト): アイテムのコンテンツサイズに基づく<length>
(px, em, remなど): 具体的な長さを指定<percentage>
(%): コンテナのサイズに対する割合content
: コンテンツのサイズに基づく
flex-basis の例
auto(デフォルト)
コンテンツのサイズに基づいてサイズが決まります。
固定サイズ
具体的なサイズを指定した場合:
flex-grow
flex-grow は、フレックスコンテナに余剰スペースがある場合に、アイテムがどれくらい拡大するかを指定するプロパティです。 値が大きいほど、より多くの余剰スペースを占有します。
フレックスコンテナーに余剰スペースがある場合、これを 正の余白 と呼びます。 正の余白はフレックスアイテム間で分配され、flex-grow に設定された値で按分された比率で拡大されます。
.flex-item {
flex-grow: 1; /* 他のアイテムと同じ比率で拡大 */
}
flex-grow の値
0
(デフォルト): 拡大しない<number>
(正の数): 拡大の比率を指定
flex-grow の例
すべて同じ値
すべてのアイテムに flex-grow: 1
を設定すると、等しく拡大します。
異なる値
異なる flex-grow
値を設定すると、比率に応じて拡大します。
拡大しない要素
flex-grow: 0
のアイテムは拡大せず、他のアイテムが余剰スペースを占有します。
flex-shrink
flex-shrink は、フレックスコンテナのスペースが不足している場合に、アイテムがどれくらい縮小するかを指定するプロパティです。 値が大きいほど、より多く縮小されます。
フレックスコンテナからフレックスアイテムがはみ出すとき、はみ出した領域を 負の余白 と呼びます。 負の余白はフレックスアイテム間で分配され、flex-shrink に設定された値で按分された比率で縮小されます。
.flex-item {
flex-shrink: 1; /* 他のアイテムと同じ比率で縮小 */
}
flex-shrink の値
1
(デフォルト): 縮小可能0
: 縮小しない<number>
(正の数): 縮小の比率を指定
flex-shrink の例
縮小可能(デフォルト)
コンテナが狭い場合、アイテムは縮小されます。
縮小しない要素
flex-shrink: 0
のアイテムは縮小せず、固定サイズを保ちます。
異なる縮小率
異なる flex-shrink
値を設定すると、比率に応じて縮小します。
flex ショートハンド
flex
プロパティは、flex-grow
、flex-shrink
、flex-basis
をまとめて指定できるショートハンドプロパティです。
flex プロパティは 1 つ、2 つ、3 つの値を取ることができます。
flex: <flex-grow> <flex-shrink> <flex-basis>;
flexによる一括指定を使用する方が、個別に flex-grow、flex-shrink、flex-basis の宣言を使用するよりも推奨されています。
.flex-item {
flex: 1 1 200px; /* flex-grow: 1, flex-shrink: 1, flex-basis: 200px */
}
- 1 つの値の場合: 値は以下のうちの 1 つです。
flex-grow
として有効な値の場合、すべてのブラウザーで、この一括指定は flex:<flex-grow> 1 0%
と展開されます。ただし、仕様書では flex:<flex-grow> 1 0
と展開すべきであるとしています。flex-basis
として有効な値の場合、一括指定はflex: 1 1 <flex-basis>
と展開されます。
- 2 つの値の場合:
- 1つめの値は
flex-grow
- 2つめの値は
flex-shrink
として有効な値の場合、この一括指定はflex: <flex-grow> <flex-shrink> 0%
と展開されます。flex-basis
として有効な値の場合、この一括指定はflex: <flex-grow> 1 <flex-basis>
と展開されます。
- 1つめの値は
- 3 つの値の場合:
flex: <flex-grow> <flex-shrink> <flex-basis>;
(例:flex: 1 1 0%;
)
よく使用される flex の値
flex: 1
flex: 1
は flex: 1 1 0%
の省略形で、等しく拡大・縮小するアイテムを作成します。
実は、flex: 1
の動作には仕様とブラウザ実装で微妙な違いがあります:
- CSS仕様上:
flex: 1
はflex: 1 1 0
に展開されるべき - ブラウザ実装: 多くのブラウザは
flex: 1 1 0%
として実装
この違いは、flex-basis
の値が 0
(絶対値)か 0%
(パーセンテージ)かという重要な差を生み出します。現在のブラウザはより予測可能な動作のために 0%
を採用していますが、これが後述する「flex-basis: 0 と 0% の違い」につながっています。
flex: auto
flex: auto
は flex: 1 1 auto
の省略形で、コンテンツサイズを基準に拡大・縮小します。
flex: none
flex: none
は flex: 0 0 auto
の省略形で、拡大も縮小もしません。
flex-basis: 0 と 0% の違い
前述した通り、CSS仕様では flex: 1
は flex: 1 1 0
に展開されるべきですが、多くのブラウザは flex: 1 1 0%
として実装しています。では、flex-basis: 0
と flex-basis: 0%
は実際に何が違うのでしょうか?
多くの開発者が見落としがちな重要な違いがあります。見た目は似ていますが、内部的な計算方法が異なり、特定の状況で異なる結果を生み出すことがあります。
技術的な違い
flex-basis: 0
- 絶対値として常に0ピクセル
- コンテナのサイズに関係なく常に0
- アイテムは完全に縮小され、flex-growによる拡大のみに依存
flex-basis: 0%
- パーセンテージ値としてコンテナサイズの0%を計算
- コンテナのサイズが確定している場合は0ピクセルと同じ結果
- コンテナのサイズが不確定な場合は
content
サイズにフォールバック
通常のケース(確定したコンテナサイズ)
コンテナのサイズが確定している場合、両者の動作は同じです:
flex-basis: 0 を使用
flex-basis: 0% を使用
演習課題
カードレイアウト
異なるサイズのカードを含むレスポンシブなレイアウトを作成しましょう。
基本プラン
月額 ¥1,000
プレミアムプラン
月額 ¥2,000(推奨)
エンタープライズ
要お問い合わせ
解答例を見る
.card-container {
display: flex;
gap: 20px;
}
.card {
min-width: 200px;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.card h3 {
margin: 0 0 10px 0;
font-size: 18px;
}
.card p {
margin: 0;
color: #666;
}
.basic {
flex: 1;
background-color: #fff;
border: 1px solid #ddd;
}
.premium {
flex: 2;
background-color: #e3f2fd;
border: 2px solid #2196f3;
}
.enterprise {
flex: 1;
background-color: #fff;
border: 1px solid #ddd;
}
ポイント:
flex: 1
とflex: 2
の組み合わせで、プレミアムプランを2倍の幅にするmin-width: 200px
でカードの最小幅を保証し、レスポンシブ対応gap: 20px
でカード間の余白を統一
サイドバーレイアウト
固定幅のサイドバーと可変幅のメインコンテンツ
.layout-container {
display: flex;
}
.sidebar {
flex: 0 0 200px; /* 固定幅200px、拡大・縮小しない */
}
.main-content {
flex: 1; /* 残りのスペースを占有 */
}
サイドバー
(固定幅: 200px)
メインコンテンツ
(可変幅: 残りのスペースを占有)
これらのプロパティを組み合わせることで、様々なレイアウトパターンを実現できます。 特に、レスポンシブデザインにおいて、画面サイズに応じて柔軟に調整されるレイアウトの作成に威力を発揮します。