Flexible Template は、CSS Flexible Box(CSS Flexbox) の基礎知識を使って、複雑なレイアウトのメッセージを構築できます。CSS Flexbox の Flex ボックスが Flexible Template のボックスに相当し、CSS Flexbox の Flex アイテムがFlexible Template のコンポーネントに相当します。
ここでは、全体のレイアウトを調整する方法と、ボックスに含まれているコンポーネント (子要素) のサイズと順番を調整する方法について説明します。JSON スキーマについて詳しくは、Flexible Template を参照してください。
ボックスの主軸方向を決めることで、子要素の配置を決めることができます。子要素をボックスに配置するには3つのレイアウトタイプがあります。
子要素の配置方向は ボックス の layout プロパティで指定します。
| レイアウトタイプ (layout プロパティの値) | 説明 |
|---|---|
| horizontal | 子要素を水平に配置します。 子要素を配置する方向は、バブル の direction プロパティで指定します。 ※ このようなレイアウトタイプのボックスを水平ボックス (horizontal box) といいます。 |
| vertical | 子要素を上から下に垂直に配置します。 ※ このようなレイアウトタイプのボックスを垂直ボックス (vertical box) といいます。 |
| baseline | 子要素を水平ボックスと同じ方法で配置します。 水平ボックスとの違いについて詳しくは、ベースラインボックスの特徴 を参照してください。 ※ このようなレイアウトタイプのボックスをベースラインボックス (baseline box) といいます。 |
ボックスのタイプによって、子要素として使用できるコンポーネントが異なります。
| 水平ボックス (horizontal box) | 垂直ボックス (vertical box) | ベースラインボックス (baseline box) | |
|---|---|---|---|
| ボックス (box) | O | O | X |
| ボタン (button) | O | O | X |
| 画像 (image) | O | O | X |
| アイコン (icon) | X | X | O |
| テキスト (text) | O | O | O |
| スパン (span) ※ 子要素またはテキストとして使用できます。 | X | X | X |
| セパレータ (separator) | O | O | X |
| フィラー (filler) | O | O | O |
ベースラインボックスは水平ボックスと同様に動作します。ただし、以下の点において水平ボックスとは動作が異なります。
垂直方向の配置位置がテキストのベースラインに固定されます。さまざまな文字サイズのテキストが混在しても、ベースラインが揃うように垂直位置が調整されます。
アイコン のベースラインは、アイコン画像の底辺です。

ベースラインボックスでは、以下のプロパティは使用できません。
position プロパティを relative に設定したコンポーネントの幅または高さは、各コンポーネントの flex プロパティで決定されます。
水平ボックスでは、コンポーネントの flex プロパティを 1 以上の値に設定した場合には、その値を基準にコンポーネント間で余白を分配します。水平ボックス内のコンポーネントでは、flex プロパティのデフォルト値は 1 です。
例えば、水平ボックス内に2つのコンポーネントがあり、flex プロパティの値が 2 と 3 の場合には、余白(以下の例では、ボックスの幅)は 2:3 の比率で分割され、各コンポーネントに割り当てられます。

上の Flexible Template を表現するには以下の JSON データを指定します。
{ "type": "bubble", "body": { "type": "box", "layout": "horizontal", "contents": [ { "type": "text", "text": "The work site begins to move; the work site is coming in sight; the work is going on. Expand business communications with us!", "wrap": true, "color": "#ff0000", "flex": 2 }, { "type": "text", "text": "The work site begins to move; the work site is coming in sight; the work is going on. Expand business communications with us!", "wrap": true, "color": "#0000ff", "flex": 3 } ] }}flex プロパティの値に 0 を指定した場合には、コンポーネントの幅がコンテンツ全体のサイズに拡大されます。ただし、ボックス幅を超える部分は表示されません。
以下の例では、ボックス内に 3 つのコンポーネントがあり、flex プロパティの値は 0、2、3 が指定されています。1 番目のコンポーネントは flex プロパティの値が 0 であるため、含まれるテキスト "Hello" を表示できる幅が確保されます。そして余白 (以下の例では、ボックスの幅から 1 番目のコンポーネントの幅を除いた部分) が 2 : 3 の比率で分割され、2番目、3番目のコンポーネントに割り当てられます。

上の Flexible Template を表現するには以下の JSON データを指定します。
{ "type": "bubble", "body": { "type": "box", "layout": "horizontal", "contents": [ { "type": "text", "text": "Hello", "color": "#00ff00", "flex": 0 }, { "type": "text", "text": "The work site begins to move; the work site is coming in sight; the work is going on. Expand business communications with us!", "wrap": true, "color": "#ff0000", "flex": 2 }, { "type": "text", "text": "The work site begins to move; the work site is coming in sight; the work is going on. Expand business communications with us!", "wrap": true, "color": "#0000ff", "flex": 3 } ] }}CSS Flexbox の flex との対応
- 水平ボックス内のコンポーネントの flex プロパティは、CSS Flexbox の flex に、以下のように対応します。
- flex = 0 の場合:CSS Flexboxの flex: 0 0 auto; と同等のレイアウト
- flex = 0 以上の場合:CSS Flexboxの flex: X 0 0; と同等のレイアウト (X は flex プロパティで指定した値)
垂直ボックスでは、コンポーネントの flex プロパティを 1 以上の値に設定した場合には、その値を基準にコンポーネント間で余白を分配します。垂直ボックス内のコンポーネントでは、flex プロパティのデフォルト値は 0 です。

各コンポーネントは次のルールでレイアウトされています。
上の Flexible Template を表現するには以下の JSON データを指定します。
{ "type": "bubble", "body": { "type": "box", "layout": "horizontal", "contents": [ { "type": "box", "layout": "vertical", "contents": [ { "type": "text", "wrap": true, "text": "TEXT\nTEXT\nTEXT\nTEXT\nTEXT" } ], "backgroundColor": "#c0c0c0" }, { "type": "box", "layout": "vertical", "contents": [ { "type": "separator", "color": "#ff0000" }, { "type": "text", "text": "flex=2", "flex": 2 }, { "type": "separator", "color": "#ff0000" }, { "type": "text", "text": "flex=3", "flex": 3 }, { "type": "separator", "color": "#ff0000" } ] } ] }}CSS Flexbox の flex との対応
- 垂直ボックス内のコンポーネントの flex プロパティは、CSS Flexbox の flex に、以下のように対応します。
- flex = 0 の場合:CSS Flexboxの flex: 0 0 auto; と同等のレイアウト
- flex = 0 以上の場合:CSS Flexboxの flex: X 0 auto; と同等のレイアウト (X は flex プロパティで指定した値)
ボックスの幅は、width プロパティで指定できます。% (親要素の幅を基準とした割合) またはピクセルで指定します。
なお、水平ボックスまたはベースラインボックスで width プロパティを指定すると、flex プロパティは 0 に設定されます。
width プロパティをピクセルで指定する場合
- バブルの幅は、バブルを表示する端末の画面サイズによって異なります。バブル全体のレイアウトを調整するために width プロパティをピクセルで指定すると、受信した端末によっては、予期せぬレイアウトになることがあります。画面サイズの影響を抑えるためには flex プロパティを使用してください。
ボックスの高さは、height プロパティで指定できます。% (親要素の高さを基準とした割合) またはピクセルで指定します。
なお、垂直ボックスで height プロパティを指定すると、flex プロパティは 0 に設定されます。
ボタンや画像などのコンポーネントのサイズは、flex プロパティと異なるプロパティで指定できます。JSON スキーマについて詳しくは、Flexible Template を参照してください。
ボックスに余白がある場合には、水平方向と垂直方向の配置位置をコンポーネントごとに指定できます。
水平方向の配置位置を align プロパティで指定できます。 align プロパティは親要素のボックスに関係なく、常に水平方向 (左右) の位置に影響します。 以下のいずれかの値を指定します。

上の Flexible Template を表現するには以下の JSON データを指定します。
{ "type": "bubble", "body": { "type": "box", "layout": "vertical", "contents": [ { "type": "text", "text": "align=start", "align": "start" }, { "type": "separator", "color": "#ff0000" }, { "type": "text", "text": "align=center", "align": "center" }, { "type": "separator", "color": "#ff0000" }, { "type": "text", "text": "align=end", "align": "end" } ] }}垂直方向の配置位置を gravity プロパティで指定できます。 gravity プロパティは親要素のボックスに関係なく、常に垂直方向 (上下) の位置に影響します。 以下のいずれかの値を指定します。
参考
- このプロパティは ベースラインボックス には適用されません。

上の Flexible Template を表現するには以下の JSON データを指定します。
{ "type": "bubble", "body": { "type": "box", "layout": "horizontal", "contents": [ { "type": "box", "layout": "vertical", "contents": [ { "type": "text", "wrap": true, "text": "TEXT\nTEXT\nTEXT\nTEXT\nTEXT" } ], "backgroundColor": "#c0c0c0" }, { "type": "text", "text": "top", "gravity": "top" }, { "type": "text", "text": "center", "gravity": "center" }, { "type": "text", "text": "bottom", "gravity": "bottom" } ] }}ボックスのパディングは、paddingAll、paddingTop、paddingBottom、paddingStart、paddingEnd プロパティで指定します。 ボックスのパディングとは、ボックスの境界線と子要素の間にある余白のサイズを表します。値は % (ボックスの幅を基準とした割合) またはピクセルで指定するか、none、xs、sm、md、lg、xl、xxl のいずれかの値を指定できます。none の場合にはスペースが設定されず、それ以外は列挙した順に余白のサイズが大きくなります。
paddingAll プロパティのほかに、paddingTop、paddingBottom、paddingStart、paddingEnd プロパティを設定した場合には、paddingAll の設定が上書きされます。

上の Flexible Template を表現するには以下の JSON データを指定します。
{ "type": "bubble", "body": { "type": "box", "layout": "horizontal", "contents": [ { "type": "box", "layout": "horizontal", "contents": [ { "type": "text", "text": "hello, world" } ], "backgroundColor": "#ffffff" } ], "backgroundColor": "#ffd2d2", "paddingTop": "20px", "paddingAll": "80px", "paddingStart": "40px" }}なお、上の Flexible Template のテキストを変更すると、以下のようにレイアウトされます。

コンポーネント間の最小スペースは、コンポーネントを含むボックス (親要素) の spacing プロパティで指定します。spacing プロパティは、none、xs、sm、md、lg、xl、xxl のいずれかの値を指定できます。none の場合にはスペースが設定されず、それ以外は列挙した順に余白のサイズが大きくなります。
以下の Flexible Template には、水平ボックスに3つの垂直ボックスが等間隔 (md) で配置されています。

上の Flexible Template を表現するには以下の JSON データを指定します。
{ "type": "bubble", "body": { "type": "box", "layout": "horizontal", "spacing": "md", "contents": [ { "type": "box", "layout": "vertical", "contents": [ { "type": "text", "text": "TEXT1" } ], "backgroundColor": "#80ffff" }, { "type": "box", "layout": "vertical", "contents": [ { "type": "text", "text": "TEXT2" } ], "backgroundColor": "#80ffff" }, { "type": "box", "layout": "vertical", "contents": [ { "type": "text", "text": "TEXT3" } ], "backgroundColor": "#80ffff" } ] }}※ 特定のコンポーネントについてこの設定を上書きするには、そのコンポーネントで margin プロパティを設定します。
親要素内での、このコンポーネントの前に挿入する余白の最小サイズは、margin プロパティで指定します。 margin プロパティは、none、xs、sm、md、lg、xl、xxl のいずれかの値を指定できます。none の場合にはスペースが設定されず、それ以外は列挙した順に余白のサイズが大きくなります。
参考
- margin プロパティは、親要素の spacing プロパティより優先されます。また、ボックス内の先頭に挿入されたコンポーネントで margin プロパティを指定した場合には、スペースはレイアウトに反映されません。
以下の Flexible Template には、水平ボックスに 3 つのの垂直ボックスが配置されています。水平ボックスの spacing プロパティは md に設定されており、3 つ目の垂直ボックスの margin プロパティが xxl に設定されています。

上の Flexible Template を表現するには以下の JSON データを指定します。
{ "type": "bubble", "body": { "type": "box", "layout": "horizontal", "spacing": "md", "contents": [ { "type": "box", "layout": "vertical", "contents": [ { "type": "text", "text": "TEXT1" } ], "backgroundColor": "#80ffff" }, { "type": "box", "layout": "vertical", "contents": [ { "type": "text", "text": "TEXT2" } ], "backgroundColor": "#80ffff" }, { "type": "box", "layout": "vertical", "contents": [ { "type": "text", "text": "TEXT3" } ], "backgroundColor": "#80ffff", "margin": "xxl" } ] }}コンポーネントの配置は、以下のプロパティを指定することによっても調整できます。
ここでは、オフセットの効果を説明するために、以下の Flexible Template を基準にして、 "TARGET" と表示されている水平ボックスの設定を変更して説明します。

上の Flexible Template を表現するには以下の JSON データを指定します。
{ "type": "bubble", "body": { "type": "box", "layout": "vertical", "contents": [ { "type": "box", "layout": "horizontal", "contents": [ { "type": "text", "text": "REFERENCE BOX\n1\n2\n3", "align": "center", "wrap": true } ], "backgroundColor": "#80ffff" }, { "type": "box", "layout": "horizontal", "contents": [ { "type": "text", "text": "TARGET" } ], "backgroundColor": "#ff8080" } ] }}本来のコンポーネントの位置を基準として配置するには、position プロパティを relative に指定してから、以下側のオフセットプロパティを指定します。CSS Positioned Layout Module Level 3 > Relative positioning と同様の考え方で位置を決定できます。
| プロパティ | 説明 |
|---|---|
| offsetBottom | 通常の位置から上に移動する量を指定します。 |
| offsetStart | 通常の位置から下に移動する量を指定します。 |
| offsetEnd | 通常の位置から左に移動する量を指定します。 |
| offsetTop | 通常の位置から右に移動する量を指定します。 |
ここで、"TARGET" と表示されている水平ボックスの設定を以下のように変更した例を紹介します。
| プロパティ | 値 |
|---|---|
| position | "relative" |
| offsetTop | 10px |
| offsetBottom | - |
| offsetStart | 40px |
| offsetEnd | - |
1 つ目のバブルは設定変更前、2 つ目のバブルは設定変更後です。

コンポーネントを親要素の境界線を基準として配置するには、position プロパティを absolute に指定してから、以下側のオフセットプロパティを指定します。CSS Positioned Layout Module Level 3 > Absolute positioning と同様の方法でレイアウトできます。
| プロパティ | 説明 |
|---|---|
| offsetTop | 親要素の上端からコンポーネントの上端までの相対位置を指定します。 |
| offsetBottom | 親要素の下端からコンポーネントの下端までの相対位置を指定します。 |
| offsetStart | 親要素の左端からコンポーネントの左端までの相対位置を指定します。 |
| offsetEnd | 親要素の右端からコンポーネントの右端までの相対位置を指定します。 |
参考
- offset プロパティを指定しない場合には、コンポーネントの位置が画面によって異なる場合があります。そのため、オフセットを垂直方向 (offsetTop または offsetBottom) および水平方向 (offsetStart または offsetEnd) で明確に指定することを推奨します。
ここで、"TARGET" と表示されているボックスの位置をオフセットの設定変更によって以下のように変更した例を紹介します。
| プロパティ | 値 |
|---|---|
| position | "absolute" |
| offsetTop | 10px |
| offsetBottom | 20px |
| offsetStart | 40px |
| offsetEnd | 80px |
1 つ目のバブルは設定変更前、2 つ目のバブルは設定変更後です。

position プロパティの値が absolute に設定されたボックスは、親要素のサイズに影響を与えなくなり、さらに親要素の影響を受けなくなります。そのため、コンポーネントのサイズが親要素より大きい場合には、コンポーネントの一部は表示されません。親要素 (余白) の影響によりコンポーネントのサイズが大きくなっていた場合には、元のサイズに戻ります。
ここで、"REFERENCE BOX" と表示されている水平ボックスの設定を以下のように変更した例を紹介します。
| プロパティ | 値 |
|---|---|
| position | "absolute" |
1 つ目のバブルは設定変更前、2 つ目のバブルは設定変更後です。

"REFERENCE BOX" のサイズは親要素 (垂直ボックス) のサイズに影響を与えなくなり、さらに親要素の影響を受けなくなります。そのため、親要素より大きい部分 ("2" と "3" が表示されてる行) は表示されません。また、親要素 (余白) の影響で大きくなっていた左右の余白部分は、元のサイズ(テキスト "REFERENCE BOX" の幅)に戻ります。
コンポーネントは、JSON データの順に描画されます。つまり、JSON データで先頭に書いたコンポーネントがバブルの最背面に描画され、最後に書いたコンポーネントはバブルの最前面に描画されます。
描画される順序を変更するには、JSON データに書くコンポーネントの順序を変更してください。