この記事は 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のレイアウトに活用する際にこの記事がお役に立てると嬉しく思います。