この記事は LINE DC Advent Calendar 2021 18日目の記事です。
はじめに
Messaging APIのドキュメントによると、Flex Messageは、CSS Flexible Box(CSS Flexbox)の基礎知識を使って、レイアウトを自由にカスタマイズできるメッセージです。
Flex Messageを使って自由なレイアウトのメッセージを作りたいと思ったとき、ドキュメントには分かりやすいチュートリアルや豊富なサンプル、Flex Message Simulatorという便利なシミュレータが用意されているので手軽にリッチなメッセージを作成できるようになっています。
一方で、サンプルに無いレイアウトを検討するときにはCSS Flexboxの知識が無いと思い通りのレイアウトが実現できず苦労します。
そこで、本記事ではFlex Message Simulatorを使いながらMDN Web Docのフレックスボックスの基本概念に対応する形でFlex Messageの対応するプロパティを紹介し、Flex Messageを理解する助けになることを目指します。
フレックスボックス 2 つの軸
フレックスボックスには flex-direction プロパティによって定義される 主軸 と、主軸と垂直に交わる 交差軸 と呼ばれる2つの軸があります。
Flex Messageではボックスの layout プロパティがこれに該当します。
flex-direction には
- row
- row-reverse
- column
- column-reverse
の4種類の値が存在しますが、Flex Messageの layout プロパティでは
- horizontal
- vertical
- baseline
の3種類の値をとります。この3種類のうち、 baseline はやや特殊なのでここでの説明は割愛します。
horizontal は フレックスボックスの row に該当し、主軸の向きは水平方向です。
例えば、以下の構成でボックスとコンポーネントを配置した場合、
bubble
├── header
├── hero
├── body
│ └── box[horizontal]
│ ├── box[vertical]
│ │ └── text[hello, world]
│ ├── box2[vertical]
│ │ └── text[hello, world]
│ └── box3[vertical]
│ └── text[hello, world]
└── footer
表示は
のようになります。
上記例のJSON
{
"type": "bubble",
"body": {
"type": "box",
"layout": "horizontal",
"contents": [
{
"type": "box",
"layout": "vertical",
"contents": [
{
"type": "text",
"text": "hello, world"
}
],
"backgroundColor": "#ecd6c7"
},
{
"type": "box",
"layout": "vertical",
"contents": [
{
"type": "text",
"text": "hello, world"
}
],
"backgroundColor": "#e79686"
},
{
"type": "box",
"layout": "vertical",
"contents": [
{
"type": "text",
"text": "hello, world"
}
],
"backgroundColor": "#a39391"
}
],
"height": "300px"
}
}
一方でvertical は フレックスボックスの column に該当し、主軸の向きは垂直方向です。
先ほどの例の、body直下にあるボックスの layout プロパティを vertical に変更すると
のように表示されます。
行の先頭と末尾
フレックスボックスでは flex-direction が row のとき、書字方向によって主軸の先頭が右側に来ることがあるようです。
Flex Messageでは書字方向が自動で識別されることは無いですが、 bubble の direction プロパティによって制御することが出来ます。
direction プロパティを rtl に設定すると以下のように表示されます。
(雰囲気を出すために hello, world をGoogle翻訳でアラビア語にしてみましたが、書字方向が正しいのかは判断できません。)
上記例のJSON
{
"type": "bubble",
"direction": "rtl",
"body": {
"type": "box",
"layout": "horizontal",
"contents": [
{
"type": "box",
"layout": "vertical",
"contents": [
{
"type": "text",
"text": "مرحبا بالعالم"
}
],
"backgroundColor": "#ecd6c7"
},
{
"type": "box",
"layout": "vertical",
"contents": [
{
"type": "text",
"text": "مرحبا بالعالم"
}
],
"backgroundColor": "#e79686"
},
{
"type": "box",
"layout": "vertical",
"contents": [
{
"type": "text",
"text": "مرحبا بالعالم"
}
],
"backgroundColor": "#a39391"
}
],
"height": "300px"
}
}
フレックスコンテナー
フレックスボックスではレイアウトされる文書の領域を フレックスコンテナー 、その直下に配置される子要素を フレックスアイテム と呼びます。
これらの要素はFlex Messageではそれぞれ ボックス と コンポーネント に該当します。
MDN Web Doc ではフレックスアイテムの振る舞いを決定するフレックスコンテナーのプロパティとして flex-direction プロパティと flex-wrap プロパティ、2つのプロパティを一括指定出来る flex-flow プロパティが解説されていますが、Flex Messageにはそれに該当するプロパティは存在せず、
-
flex-direction:layoutプロパティに応じて決定(reverseは存在しない) -
flex-wrap:nowrapに固定
となっています。
したがって、Flex Messageでコンポーネントがボックスに収まらない場合には以下のように折り返されずにあふれます。
上記例のJSON
{
"type": "bubble",
"body": {
"type": "box",
"layout": "horizontal",
"contents": [
{
"type": "box",
"layout": "vertical",
"contents": [],
"width": "50px",
"height": "50px",
"backgroundColor": "#ecd6c7"
},
{
"type": "box",
"layout": "vertical",
"contents": [],
"width": "50px",
"height": "50px",
"backgroundColor": "#e79686"
},
{
"type": "box",
"layout": "vertical",
"contents": [],
"width": "50px",
"height": "50px",
"backgroundColor": "#a39391"
},
{
"type": "box",
"layout": "vertical",
"contents": [],
"width": "50px",
"height": "50px",
"backgroundColor": "#ecd6c7"
},
{
"type": "box",
"layout": "vertical",
"contents": [],
"width": "50px",
"height": "50px",
"backgroundColor": "#e79686"
},
{
"type": "box",
"layout": "vertical",
"contents": [],
"width": "50px",
"height": "50px",
"backgroundColor": "#a39391"
}
]
}
}
フレックスアイテムに適用されるプロパティ
フレックスボックスではアイテムの幅や高さを制御するために flex-grow、flex-shrink、flex-basisとこれらを一括指定出来る flex プロパティが用意されています。Flex Messageでこれに該当するプロパティは flex となっており、
-
flexプロパティに0を指定 : フレックスボックスのflex: 0 0 auto;と同等のレイアウト -
flexプロパティに0以上を指定 : フレックスボックスのflex: X 0 0;と同等のレイアウト(Xはflexプロパティで指定した値)
のように対応しています。
また、 flex プロパティのデフォルト値はボックスの layout プロパティによって異なっており、
-
layoutプロパティにhorizontalを指定 :flexプロパティのデフォルト値は1 -
layoutプロパティにverticalを指定 :flexプロパティのデフォルト値は0
となっています。
フレックスボックス 2 つの軸 で layout プロパティの違いを紹介した際に、主軸が水平方向の際には3つのコンポーネントが余白を均等に分配していたのに対し、主軸が垂直方向の際にはコンポーネントの高さは文字の高さとなっており、余白を残していました。
この違いは上記の flex プロパティのデフォルト値の違いからきており、 layout プロパティを vertical に指定した場合も flex プロパティを 1 に指定すると同様のレイアウトにすることが出来ます。
上記例のJSON
{
"type": "bubble",
"body": {
"type": "box",
"layout": "vertical",
"contents": [
{
"type": "box",
"layout": "vertical",
"contents": [
{
"type": "text",
"text": "hello, world"
}
],
"backgroundColor": "#ecd6c7",
"flex": 1
},
{
"type": "box",
"layout": "vertical",
"contents": [
{
"type": "text",
"text": "hello, world"
}
],
"backgroundColor": "#e79686",
"flex": 1
},
{
"type": "box",
"layout": "vertical",
"contents": [
{
"type": "text",
"text": "hello, world"
}
],
"backgroundColor": "#a39391",
"flex": 1
}
],
"height": "300px"
}
}
アイテム間での位置合わせ、端揃え、余白分配
フレックスボックスでは主軸および交差軸においての位置合わせや端揃えを align-items プロパティや justify-content プロパティによって制御します。
Flex Messageでは alignItems プロパティと justifyContent プロパティがこれに該当します。
align-items
align-items プロパティは交差軸におけるアイテムの位置合わせを行います。
Flex Messageの alignItems プロパティとの対応は以下の通りです。
| フレックスボックス | Flex Message | イメージ |
|---|---|---|
| stretch | (デフォルト値) | ![]() |
| flex-start | flex-start | ![]() |
| flex-end | flex-end | ![]() |
| center | center | ![]() |
justify-content
justify-content プロパティは主軸におけるアイテムの配置を制御します。Flex Messageでは justifyContent プロパティがこれに該当しており、とりうる値の種類は一致しています。
|justifyContent プロパティ|イメージ|
|:-:|:-:|:-:|
|flex-start|
|
|flex-end|
|
|center|
|
|space-around|
|
|space-between|
|
|space-evenly|
|
まとめ
本記事ではフレックスボックスとFlex Messageのプロパティを対応付けながら紹介していきました。
対応付けを見ると flex-direction プロパティ と flex-wrap プロパティ は存在せず、 flex プロパティも若干の制限が存在する一方で、十分に自由なレイアウトを作れるだけのプロパティがサポートされていることが分かりました。
世の中には多くのフレックスボックスを活用したレイアウト例が存在しており、それらをFlex Messageのレイアウトに活用する際にこの記事がお役に立てると嬉しく思います。







