Flexbox:そのフレキシブルボックスの大きさはどれくらいですか?

公開: 2022-03-10
簡単なまとめ↬最後の2つの記事では、フレックスコンテナを作成するとどうなるか、また配置についても見てきました。 今回は、Flexboxでのサイズ設定のしばしば紛らわしい問題を探ります。 Flexboxはどのように大きなものが必要かを決定しますか?

これは、Flexboxに関する私のシリーズの第3部です。 過去2回の記事では、フレックスコンテナーを作成したときに何が起こるかを確認し、フレックスボックスで機能するときの配置について説明しました。 今回はサイジングについて見ていきます。 フレックスアイテムのサイズをどのように制御し、サイズを制御するときにブラウザはどのような選択をしますか?

フレックスアイテムの初期表示

内部に可変長のコンテンツを持つアイテムのセットがあり、その親をdisplay: flexに設定すると、アイテムは行として表示され、その軸の先頭に整列します。 以下の例では、私の3つのアイテムに少量のコンテンツがあり、各アイテムのコンテンツを途切れのない線で表示できます。 フレックスコンテナの端には、 flex-growグローの初期値が0であるため、アイテムが成長しないスペースがあります。成長しないでください。

最後にスペースがある3つのアイテム
フレックスアイテムには、それぞれを1行に表示する余地があります(大プレビュー)

これらのアイテムにさらにテキストを追加すると、最終的にコンテナがいっぱいになり、テキストが折り返され始めます。 ボックスには、各ボックスに含まれるテキストの量に対応するコンテナ内のスペースの一部が割り当てられます。テキストの文字列が長いアイテムには、より多くのスペースが割り当てられます。 これは、隣のアイテムに1つの単語しか含まれていない場合に、テキストが多い背の高い細い列になってしまうことがないことを意味します。

3つのアイテム、最後のアイテムには長いテキストがあり、テキストは折り返されます
スペースは、より長いアイテムにより多くのスペースを与えるために分散されます(大きなプレビュー)

Flexboxを使用したことがある場合、この動作はおなじみのようですが、複数の最新のブラウザを見ると、すべて同じことをしていることがわかるように、ブラウザがどのように機能しているか疑問に思っているかもしれません。 これは、このような詳細が仕様で解決されているという事実に基づいており、新しいブラウザまたは他のユーザーエージェントでFlexboxを実装する人は、この計算がどのように機能するかを認識していることを確認してください。 仕様を使用して、この情報を自分で見つけることができます。

ジャンプした後もっと! 以下を読み続けてください↓

CSSの固有および外部のサイジング仕様

Flexbox仕様でサイズ設定について何かを見ると、必要な情報の多くが別の仕様であるCSSIntrisnicおよびExtrinsicSizingにあることがすぐにわかります。 これは、配置プロパティがFlexboxに固有ではないのと同じように、使用しているサイズ設定の概念がFlexboxに固有ではないためです。 ただし、これらのサイジング構造がFlexboxでどのように使用されるかについては、Flexboxの仕様を確認する必要があります。 前後にジャンプしているように感じることがあるので、ここでいくつかの重要な定義をまとめます。これは、この記事の残りの部分で使用します。

推奨サイズ

ボックスの推奨サイズは、 widthまたはheight 、またはinline-sizeblock-sizeサイズのこれらのプロパティの論理エイリアスによって定義されるサイズです。 使用することによって:

 .box { width: 500px; }

または、論理エイリアスinline-size

 .box { inline-size: 500px; }

ボックスの幅を500ピクセル、またはインライン方向に500ピクセルにすることを指定しています。

最小コンテンツサイズ

最小コンテンツサイズは、オーバーフローを発生させずにボックスを作成できる最小サイズです。 ボックスにテキストが含まれている場合は、考えられるすべてのソフトラッピングの機会が利用されます。

最大コンテンツサイズ

max-content sizeは、ボックスにコンテンツを含めることができる最大サイズです。 ボックスに分割するための書式設定のないテキストが含まれている場合は、1つの長い途切れのない文字列として表示されます。

フレックスアイテムメインサイズ

フレックスアイテムの主なサイズは、主な寸法でのサイズです。 英語で連続して作業している場合、主なサイズは幅です。 英語の列では、主なサイズは高さです。

アイテムには、メインディメンションの最小min-widthまたはmin-heightで定義される最小および最大のメインサイズもあります。

フレックスアイテムのサイズを計算する

いくつかの用語が定義されたので、フレックスアイテムのサイズを確認できます。 flexプロパティの初期値は次のとおりです。

  • flex-grow: 0
  • flex-shrink: 1
  • flex-basis: auto

flex-basisは、サイジングが計算されるものです。 flex-basis0に設定し、 flex-growを1に設定すると、すべてのボックスに開始幅がないため、フレックスコンテナ内のスペースが均等に共有され、各アイテムに同じ量のスペースが割り当てられます。

ペンスマッシングフレックスボックスシリーズ3を参照してください。フレックス:1 1 0; CodePenのRachelAndrew(@rachelandrew)による。

ペンスマッシングフレックスボックスシリーズ3を参照してください。フレックス:1 1 0; CodePenのRachelAndrew(@rachelandrew)による。

一方、 flex-basisautoおよびflex-grow: 1の場合、コンテンツのサイズを考慮して、スペアスペースのみが分散されます。

CodePenのPenSmashing Flexbox Series 3:flex:1 1 auto short text by Rachel Andrew(@rachelandrew)を参照してください。

CodePenのPenSmashing Flexbox Series 3:flex:1 1 auto short text by Rachel Andrew(@rachelandrew)を参照してください。

空きスペースがない場合、たとえば1行に収まらないほど多くのコンテンツがある場合、配布するスペースはありません。

CodePenのPenSmashing Flexbox Series 3:flex:1 1 auto long text by Rachel Andrew(@rachelandrew)を参照してください。

CodePenのPenSmashing Flexbox Series 3:flex:1 1 auto long text by Rachel Andrew(@rachelandrew)を参照してください。

これは、Flexboxがボックスのサイズをどのように計算するかを知りたい場合、 autoの意味を理解することが非常に重要であることを示しています。 autoの価値が私たちの出発点になります。

自動の定義

autoがCSSで何かの値として定義されている場合、そのコンテキストでは非常に具体的な意味があり、一見の価値があります。 CSSワーキンググループは、スペックエディターFantasaiのこの講演で説明されているように、どのような状況でもautoが何を意味するのかを理解するために多くの時間を費やしています。

仕様のflex-basisとして使用された場合のautoの意味に関する情報を見つけることができます。 上で定義された用語は、このステートメントを分析するのに役立つはずです。

「フレックスアイテムに指定すると、autoキーワードは、使用されている `flex-basis`としてメインサイズプロパティの値を取得します。 その値自体がautoの場合、使用される値は `content`です。"

したがって、 flex-basisautoの場合、Flexboxは定義されたメインサイズプロパティを調べます。 フレックスアイテムのいずれかにwidthを指定した場合、メインサイズになります。 次の例では、アイテムの幅がすべて110pxであるため、flex-basisの初期値がautoであるため、これがメインサイズとして使用されています。

CodePenのRachelAndrew(@rachelandrew)によるPen Smashing Flexbox Series 3:幅のあるフレックスアイテムを参照してください。

CodePenのRachelAndrew(@rachelandrew)によるPen Smashing Flexbox Series 3:幅のあるフレックスアイテムを参照してください。

ただし、最初の例には幅のないアイテムがあります。これは、メインサイズがautoであるため、次の文に進む必要があります。「その値自体が自動の場合、使用される値はcontentです。」

次に、 contentキーワードについて仕様が何を示しているかを確認する必要があります。 これは、 flex-basisで(サポートブラウザで)使用できるもう1つの値です。次に例を示します。

 .item { flex: 1 1 content; }

仕様では、 contentを次のように定義しています。

「フレックスアイテムのコンテンツに基づいた自動サイズを示します。 (通常、最大コンテンツサイズと同等ですが、アスペクト比、固有のサイズ制限、および直交フローを処理するように調整されています。」

この例では、テキストを含むフレックスアイテムを使用して、より複雑な調整の一部を無視し、 contentを最大コンテンツサイズとして扱うことができます。

したがって、これは、各アイテムに少量のテキストがある場合に、テキストが折り返されない理由を説明しています。 フレックスアイテムは自動サイズ設定されているため、Flexboxは最大コンテンツサイズを確認し、アイテムはそのサイズでコンテナーに収まり、作業は完了です。

コンテンツを追加すると、ボックスが最大コンテンツサイズのままにならないため、話はここで終わりではありません。 そうした場合、フレックスコンテナから抜け出し、オーバーフローが発生します。 それらがコンテナを満たすと、コンテンツはラップを開始し、アイテムはその中のコンテンツに基づいて異なるサイズになります。

柔軟な長さの解決

仕様がかなり複雑に見えるのはこの時点ですが、実行する必要のある手順は次のとおりです。

まず、すべてのアイテムのメインサイズを合計し、コンテナ内の使用可能なスペースよりも大きいか小さいかを確認します。

コンテナのサイズが合計よりも大きい場合は、 flex-growファクターを考慮します。

最後に空きスペースがあるフレックスアイテム
最初のケースでは、アイテムに成長するための利用可能なスペースがあります。 (大プレビュー)

コンテナのサイズが合計よりも小さい場合は、収縮する必要があるため、 flex-shrink係数を考慮します。

コンテナがあふれるフレックスアイテム
2番目のケースでは、アイテムが大きすぎるため、コンテナに収まるように縮小する必要があります。 (大プレビュー)

柔軟性のないアイテムを凍結します。つまり、特定のアイテムのサイズをすでに決定できます。 flex-growを使用している場合、これにはflex-grow: 0を持つすべてのアイテムが含まれます。 これは、フレックスアイテムのコンテナにスペースが残っている場合のシナリオです。 flex-growの初期値は0であるため、最大幅と同じ大きさになり、メインサイズからそれ以上大きくなることはありません。

flex-shrinkを使用している場合、これにはflex-shrink: 0アイテムが含まれます。 フレックスアイテムのセットにフレックスflex-shrink係数を0にすると、このステップで何が起こるかがわかります。アイテムはmax-content状態でフリーズするため、フレックスしてコンテナに収まるように配置しないでください。

CodePenのRachelAndrew(@rachelandrew)によるPen Smashing Flexbox Series 3:flex:0 0autoを参照してください。

CodePenのRachelAndrew(@rachelandrew)によるPen Smashing Flexbox Series 3:flex:0 0autoを参照してください。

私たちの場合、フレックスアイテムの初期値を使用すると、アイテムが縮小する可能性があります。 したがって、手順は続行され、アルゴリズムはループに入り、割り当てまたは削除するスペースの量を計算します。 私たちの場合、アイテムの合計サイズがコンテナよりも大きいため、 flex-shrinkを使用しています。そのため、スペースを取り去る必要があります。

flex-shrink係数は、アイテムの内部ベースサイズ(この場合はmax-contentサイズ)で乗算されます。 これにより、スペースを削減するための値が得られます。 アイテムがflex-shrinkファクターに従ってのみスペースを削除した場合、小さなアイテムは基本的に消滅し、すべてのスペースが削除されますが、大きなアイテムにはまだ縮小するスペースがあります。

このループには、ターゲットのメインサイズよりも小さくなったり大きくなったりするアイテムをチェックするための追加の手順があります。この場合、アイテムは拡大または縮小を停止します。 繰り返しますが、これは、特定のアイテムが他のアイテムと比較して小さくなったり大きくなったりするのを防ぐためです。

エッジケースのシナリオのいくつかを見ていなかったので、仕様の点ですべてが単純化されました。Flexboxにそのことをさせて、ピクセルの後ではないと仮定すると、一般的には単純に頭の中でさらに深く考えることができます。完璧。 ほとんどの場合、次の2つの事実を覚えておくとうまくいきます。

autoから成長している場合、 flex-basisはアイテムの任意の幅または高さ、またはmax-contentサイズとして扱われます。 次に、そのサイズを開始点として使用して、 flex-growファクターに従ってスペースが割り当てられます。

autoから縮小する場合、 flex-basisはアイテムの任意の幅または高さ、またはmax-contentサイズとして扱われます。 次に、 flex-basisのサイズにflex-shrink係数を掛けた値に従ってスペースが削除されるため、アイテムの最大コンテンツサイズに比例してスペースが削除されます。

成長と縮小の制御

私はこの記事のほとんどを、Flexboxが独自のデバイスに任せたときに何をするかを説明するのに費やしました。 もちろん、 flexプロパティを使用することで、フレックスアイテムをより細かく制御できます。 彼らは、舞台裏で何が起こっているのかを理解することで、より予測可能に見えることを願っています。

独自のflex-basisを設定するか、アイテム自体にflex-basisとして使用されるサイズを指定することで、アルゴリズムから制御を取り戻し、この特定のサイズから拡大または縮小することをFlexboxに通知します。 flex-growまたはflex-shrinkを0に設定することで、成長または縮小を完全にオフにすることができます。ただし、この点では、適切なレイアウト方法を使用しているかどうかを確認する時間として、フレックスアイテムを制御することをお勧めします。 フレックスアイテムを2次元で並べようとしている場合は、グリッドレイアウトを選択した方がよい場合があります。

サイズ関連の問題のデバッグ

フレックスアイテムが予期しないサイズになってしまう場合、これは通常、フレックスベースが自動であり、そのアイテムに幅を与えるものがあり、それがフレックスベースとして使用されているためです。 DevToolsでアイテムを調べると、サイズがどこから来ているのかを特定するのに役立つ場合があります。 また、 flex-basis0に設定して、Flexboxにアイテムの幅がゼロとして扱われるようにすることもできます。 これが希望する結果ではない場合でも、使用中のflex-basisの値がサイジングの問題の原因であると特定するのに役立ちます。

フレックスギャップ

Flexboxの要望の多かった機能は、グリッドレイアウトや複数列のレイアウトでギャップを指定できるのと同じ方法で、フレックスアイテム間のギャップやガターを指定できることです。 この機能は、Box Alignmentの一部としてFlexboxに指定されており、最初のブラウザーの実装が進行中です。 Firefoxは、Firefox63でFlexboxのギャッププロパティを出荷することを想定しています。次の例はFirefoxNightlyで表示できます。

CodePenのRachelAndrew(@rachelandrew)によるPen Smashing Flexbox Series 3:flex-gapsを参照してください。

CodePenのRachelAndrew(@rachelandrew)によるPen Smashing Flexbox Series 3:flex-gapsを参照してください。
ガター間隔のある3列のアイテム
Firefox 63で見た画像(大きいプレビュー)

グリッドレイアウトと同様に、スペースがフレックスアイテムに分散される前に、ギャップの長さが考慮されます。

まとめ

この記事では、Flexboxがフレックスアイテムの大きさをどのように計算するかについて、いくつかの細かい点を説明しようとしました。 少しアカデミックに思えるかもしれませんが、これがどのように機能するかを理解するのに少し時間がかかると、レイアウトでFlexboxを使用するときに時間を大幅に節約できます。 Flexboxは、デフォルトで、さまざまなサイズの一連のアイテムの最も賢明なレイアウトを提供しようとしているという事実に戻ると、非常に役立ちます。 アイテムにさらに多くのコンテンツがある場合、より多くのスペースが与えられます。 あなたとあなたのデザインがFlexboxが最善だと考えるものに同意しない場合は、独自のflex-basisを設定することで制御を取り戻すことができます。