【Unity】【UI Toolkit】flex-growとflex-shrinkの仕様をちゃんと理解する

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-shrinkの値が大きいほど大きくなっていることがわかります。

flex-basis

上記二つのプロパティの他にflex-basisというプロパティがあります。
これを指定すると、flex-growやflex-shrinkを計算する際に使う各VisualElementの基準サイズを上書きできます。

例えばいま、下図のようなレイアウトを考えます。
赤と青の基準サイズはゼロで、緑の基準サイズが300の状態でflex-growを全て1にしています。

レイアウト

このとき、Greenのflex-basisに0と設定するとそのVisualElementのサイズを0としてflex-growを計算します。
上述の通り赤と青の基準サイズは元々ゼロなので、緑の基準サイズもゼロにすることで三つのVisualElementが全て均等にレイアウトされる結果となります。

flex-basisをゼロに設定

参考

docs.unity3d.com

memowomome.hatenablog.com