UnityのUI Toolkitにおけるflex-growとflex-shrinkの仕様をまとめました。
Unity 2022.2.17
はじめに
UI ToolkitはFlexboxの概念に準じたレイアウトシステムを採用しています。
Flexboxでは、flex-growやflex-shrinkといったプロパティを使うことで各アイテム(UI ToolkitでいうVisualElement)を柔軟に配置することができます。
本記事ではこのflex-growとflex-shrinkの仕様についてまとめます。
flex-growの仕様
いま、以下のように赤、緑、青の三つのVisualElementが横並びに配置されたレイアウトを考えます。
flex-growは最初はゼロにしておきます。
それぞれのサイズは300px, 200px, 100pxに設定してあるのでそのサイズで配置されています。
また、全体の横幅が900pxなので余りスペースが300pxあります。
この状態からflex-growを設定していきます。
flex-growを設定すると、各VisualElementに設定したflex-growの値を「重み」として、「余り」部分のサイズをそれぞれのVisualElementのサイズとして振り分けます。
例えば、全てのVisual Elementのflex-growを1に設定すると、300pxあった余りがそれぞれ100ずつ各VisualElementに分配され、以下のようなレイアウトになります。
つまり、flex-growを1にしたまま各VisualElementのwidthをゼロに設定すると、以下のように全てのVisualElementが均等にレイアウトされます。
また、VisualElementのサイズは子要素によっても変わります。
例えば上記の状態から、下図のように、緑のVisualElementの子要素として幅が300pxのボタンを配置します。
この場合は緑のVisualElementのサイズが300になるため、残りの900 - 300 = 600pxが200pxずつ各要素に割り振られます。
また、上述の通りflex-growは「重み」を表すため、下図のようにVisualElement毎に値を変えるとその値に基づいてレイアウトが変わります。
flex-shrinkの仕様
上述の通り、flex-growは「余り」部分をどのように振り分けるかという意味を持ちました。
これに対してflex-shrinkは「はみ出し」部分をどのように処理するかを意味します。
例として、下図のように300pxはみ出しているレイアウトを考えます。
親の横幅が900なのに対して、3つの子のVisualElementがそれぞれ400pxなので、300px分親からはみ出してしまっています。
flex-shrinkは全てゼロです。
このようなケースで各VisualElementにflex-shrinkを設定すると「はみ出さないようにするためにどのくらい縮小するか」の重みを指定することができます。
たとえば上図の状態から、それぞれflex-shrinkを1, 2, 3のように設定した状態が下図です。
はみ出さないように各要素が縮小されていることと、その縮小率はflex-shrinkの値が大きいほど大きくなっていることがわかります。
flex-basis
上記二つのプロパティの他にflex-basisというプロパティがあります。
これを指定すると、flex-growやflex-shrinkを計算する際に使う各VisualElementの基準サイズを上書きできます。
例えばいま、下図のようなレイアウトを考えます。
赤と青の基準サイズはゼロで、緑の基準サイズが300の状態でflex-growを全て1にしています。
このとき、Greenのflex-basisに0と設定するとそのVisualElementのサイズを0としてflex-growを計算します。
上述の通り赤と青の基準サイズは元々ゼロなので、緑の基準サイズもゼロにすることで三つのVisualElementが全て均等にレイアウトされる結果となります。