Flex Messageのレイアウト

Flex Messageは、CSS Flexible Box(CSS Flexbox)の基礎知識を使って、複雑なレイアウトのメッセージを構築します。CSS FlexboxのFlexボックスがFlex Messageのボックスに相当し、CSS FlexboxのFlexアイテムがFlex Messageのコンポーネントに相当します。

ここでは、レイアウトを調整するためのプロパティや、ボックスに含めたコンポーネント(子要素)のサイズと位置合わせを調整する方法の概要を説明します。JSONスキーマについて詳しくは、『Messaging APIリファレンス』の「Flex Message」を参照してください。

コンポーネントを配置する向き

ボックスの主軸の向きを決定し、子要素を配置する向きを決定します。ボックスの子要素を配置するレイアウト方式は3つあります。

配置する向きは、ボックスlayoutプロパティで指定します。

レイアウト方式
layoutプロパティの値)
説明
horizontal 子要素を水平に配置します。配置方向は、バブルdirectionプロパティで指定します。
このレイアウト方式が指定されたボックスを、水平ボックスと呼びます。
vertical 子要素を上から下へ垂直に配置します。
このレイアウト方式が指定されたボックスを、垂直ボックスと呼びます。
baseline 子要素を水平ボックスと同様に配置します。水平ボックスとの違いは、「ベースラインボックスの特徴」を参照してください。
このレイアウト方式が指定されたボックスを、ベースラインボックスと呼びます。

使用できるコンポーネント

ボックスの種類によって、子要素として使用できるコンポーネントが異なります。

水平ボックス 垂直ボックス ベースラインボックス
ボックス ×
ボタン ×
画像 ×
アイコン × ×
テキスト
スパン(テキストの子要素として使用できます) × × ×
セパレータ ×
フィラー
スペーサー(非推奨)

〇:ボックスの子要素として使用できる、×:ボックスの子要素として使用できない

ベースラインボックスの特徴

ベースラインボックスは水平ボックスと同様に動作します。ただし、水平ボックスとは、以下の点で動作が異なります。

垂直方向の揃え位置

垂直方向の揃え位置がテキストのベースラインに固定されます。さまざまなフォントサイズのテキストが混在しても、ベースラインが揃うように垂直位置が調整されます。

なお、アイコンのベースラインは、アイコン画像の底辺です。

ベースラインボックス

使用できないプロパティ

ベースラインボックスでは、以下のプロパティは使用できません。

  • gravityプロパティ
  • offsetBottomプロパティ(今後、使用できるようになる予定です)

コンポーネントの幅と高さ

positionプロパティをrelativeに設定したコンポーネントの幅または高さは、各コンポーネントのflexプロパティで決定されます。

水平ボックス内のコンポーネントの幅

水平ボックスでは、コンポーネントのflexプロパティに1以上の値を指定した場合は、その値をもとに、コンポーネントに余白が分配されます。水平ボックス内のコンポーネントでは、flexプロパティのデフォルト値は1です。

たとえば、水平ボックスに2つのコンポーネントがありflexプロパティの値が23であるとき、余白(以下の例では、ボックスの幅)が2:3に分割され、各コンポーネントに割り当てられます。

flexプロパティの例1

上のFlex Messageを表現するには以下のようなJSONデータを指定します。

{
  "type": "bubble",
  "body": {
    "type": "box",
    "layout": "horizontal",
    "contents": [
      {
        "type": "text",
        "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "wrap": true,
        "color": "#ff0000",
        "flex": 2
      },
      {
        "type": "text",
        "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "wrap": true,
        "color": "#0000ff",
        "flex": 3
      }
    ]
  }
}

flexプロパティに0を指定した場合は、そのコンポーネントの幅が維持されます。ただし、ボックスの幅を超える部分は表示されません。

以下の例では、ボックス内に3つのコンポーネントがあり、flexプロパティの値は023になっています。1番目のコンポーネントはflexプロパティの値が0であるため、含まれるテキスト「Hello」を表示できる幅が確保されます。そして、余白(以下の例では、ボックスの幅から1番目のコンポーネントの幅を除いた部分)が2:3に分割され、2番目、3番目のコンポーネントに割り当てられます。

flexプロパティの例2

上のFlex Messageを表現するには以下のようなJSONデータを指定します。

{
  "type": "bubble",
  "body": {
    "type": "box",
    "layout": "horizontal",
    "contents": [
      {
        "type": "text",
        "text": "Hello",
        "color": "#00ff00",
        "flex": 0
      },
      {
        "type": "text",
        "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "wrap": true,
        "color": "#ff0000",
        "flex": 2
      },
      {
        "type": "text",
        "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "wrap": true,
        "color": "#0000ff",
        "flex": 3
      }
    ]
  }
}
tip 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です。

以下のFlex Messageでは、水平ボックスの中に2つの垂直ボックスが配置されています。さらに、左側の垂直ボックスには1つのテキストが配置され、右側の垂直ボックスに2つのテキストと3つのセパレータが配置されています。

flexプロパティの例5

このとき、各コンポーネントは次のようなルールでレイアウトされています。

  1. 左側の垂直ボックスが5行分の高さがあるため、右側の垂直ボックスも同じ高さになります。
  2. 右側の垂直ボックスには、2つのテキスト(各1行)と3つのセパレータだけでは埋められない余白が発生します。
  3. 2つのテキストのflexプロパティの値(23)をもとに、余白が2:3に分割され、各コンポーネントに割り当てられます。

上のFlex Messageを表現するには以下のような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"
          }
        ]
      }
    ]
  }
}
tip 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に設定されます。

note `width`プロパティをピクセルで指定する場合

バブルの幅は、バブルを表示する端末の画面サイズによって異なります。バブル全体のレイアウトを調整するためにwidthプロパティをピクセルで指定すると、受信した端末によっては、予期せぬレイアウトになることがあります。画面サイズの影響を抑えるためにはflexプロパティを私用してください。

ボックスの高さ

ボックスの場合は、heightプロパティで高さを指定できます。%(親要素の高さを基準にした割合)またはピクセルで指定します。

なお、垂直ボックスでheightプロパティを指定すると、flexプロパティは0に設定されます。

その他のコンポーネントのサイズ

ボタンや画像などのコンポーネントでは、flexプロパティとは異なるプロパティでサイズを指定できます。JSONスキーマについて詳しくは、『Messaging APIリファレンス』の「Flex Message」を参照してください。

コンポーネントの位置

ボックス内に余白がある場合、水平方向と垂直方向の位置合わせをコンポーネントごとに指定できます。

水平方向の位置合わせ

垂直ボックスでは、水平方向(交差軸方向)の位置合わせ方式をalignプロパティで指定できます。以下のいずれかの値を指定します。

  • start:左揃え
  • end:右揃え
  • center:中央揃え(デフォルト値)

alignプロパティの例

上のFlex Messageを表現するには以下のような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プロパティで指定できます。以下のいずれかの値を指定します。

  • top:上揃え(デフォルト値)
  • bottom:下揃え
  • center:中央揃え
note 注意

ベースラインボックスではこの設定は無視されます。

gravityプロパティの例

上のFlex Messageを表現するには以下のような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": "separator",
        "color": "#ff0000"
      },
      {
        "type": "text",
        "text": "center",
        "gravity": "center"
      },
      {
        "type": "separator",
        "color": "#ff0000"
      },
      {
        "type": "text",
        "text": "bottom",
        "gravity": "bottom"
      },
      {
        "type": "separator",
        "color": "#ff0000"
      }
    ]
  }
}

ボックスのパディング

ボックスのパディングは、paddingAllpaddingToppaddingBottompaddingStartpaddingEndプロパティで指定します。ボックスのパディングは、ボックスの境界線と、子要素の間の余白のサイズを表します。サイズには、%(ボックスの横幅を基準にした割合)、ピクセル、またはnonexssmmdlgxlxxlのいずれかの値を指定できます。noneではスペースが設定されず、それ以外は列挙した順にサイズが大きくなります。

なお、paddingAllのほかに、paddingToppaddingBottompaddingStartpaddingEndも設定すると、paddingAllの設定が上書きされます。

paddingプロパティの例

上のFlex Messageを表現するには以下のような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"
  }
}

なお、上のFlex Messageのテキストを変更すると、以下のようにレイアウトされます。

paddingプロパティの例

ボックスのspacingプロパティ

コンポーネント間の最小スペースは、コンポーネントを含むボックス(親要素)のspacingプロパティで指定します。nonexssmmdlgxlxxlのいずれかの値を指定できます。noneではスペースが設定されず、それ以外は列挙した順にサイズが大きくなります。

以下のFlex Messageには、水平ボックスに3つの垂直ボックスが等間隔(md)で配置されています。

spacingプロパティの例

上のFlex Messageを表現するには以下のような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プロパティで指定します。nonexssmmdlgxlxxlのいずれかの値を指定できます。noneではスペースが設定されず、それ以外は列挙した順にサイズが大きくなります。

note 注意

marginプロパティは、ボックスのspacingプロパティより優先されます。また、ボックスの先頭に挿入したコンポーネントのmarginプロパティは、レイアウトに反映されません。

以下のFlex Messageには、水平ボックスに3つの垂直ボックスが配置されています。水平ボックスのspacingプロパティがmdに、3番目の垂直ボックスのmarginプロパティがxxlに設定されています。

marginプロパティの例

上のFlex Messageを表現するには以下のような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"
      }
    ]
  }
}

オフセット

コンポーネントの位置は、以下のプロパティを指定しても調整できます。

  • positionプロパティ

    オフセットの効果は、positionプロパティの設定によって異なります。なお、ブロックの直下にあるボックスでは、absoluteは指定できません。

  • offsetTopプロパティ、offsetBottomプロパティ、offsetStartプロパティ、offsetEndプロパティ

    %(ボックスの大きさを基準にした割合)、ピクセル、またはnonexssmmdlgxlxxlのいずれかの値を指定できます。

ここでは、オフセットの効果を説明するために、以下のFlex Messageを基準にして、「TARGET」と表示されている水平ボックスの設定を変更して説明します。

offsetプロパティの例1

上のFlex Messageを表現するには以下のような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の場合

コンポーネントの通常の位置を基準に配置するには、positionプロパティにrelativeを指定して、以下のオフセットプロパティを指定します。CSS Positioned Layout Module Level 3の「Relative positioning」と同様の考えかたで位置を決定できます。

プロパティ 説明
offsetTop 通常の位置から上に移動する量を指定します。
offsetBottom 通常の位置から下に移動する量を指定します。
offsetStart 通常の位置から左に移動する量を指定します。
offsetEnd 通常の位置から右に移動する量を指定します。

ここで、「TARGET」と表示されている水平ボックスの設定を以下のように変更した例を紹介します。

プロパティ
position relative
offsetTop 10px
offsetBottom -
offsetStart 40px
offsetEnd -

1つ目のバブルは設定変更前、2つ目のバブルは設定変更後です。

offsetプロパティの例1 offsetプロパティの例2

positionプロパティがabsoluteの場合

コンポーネントを、親要素の外枠を基準に配置するには、positionプロパティにabsoluteを指定して、以下のオフセットプロパティを指定します。CSS Positioned Layout Module Level 3の「Absolute positioning」と同様の方法でレイアウトできます。

プロパティ 説明
offsetTop 親要素の上端からコンポーネントの上端までの相対位置を指定します。
offsetBottom 親要素の下端からコンポーネントの下端までの相対位置を指定します。
offsetStart 親要素の左端からコンポーネントの左端までの相対位置を指定します。
offsetEnd 親要素の右端からコンポーネントの右端までの相対位置を指定します。
note 注意

オフセットプロパティを指定しない場合のコンポーネントの位置は、端末によって異なる可能性があります。そのため、縦方向(offsetTopまたはoffsetBottom)および横方向(offsetStartまたはoffsetEnd)のオフセットプロパティを明示的に指定することを推奨します。

ここで、「TARGET」と表示されている水平ボックスの設定を以下のように変更した例を紹介します。

プロパティ
position absolute
offsetTop 10px
offsetBottom 20px
offsetStart 40px
offsetEnd 80px

1つ目のバブルは設定変更前、2つ目のバブルは設定変更後です。

offsetプロパティの例1 offsetプロパティの例3

親要素とコンポーネントの大きさについて

positionプロパティにabsoluteを指定したボックスは、親要素の大きさに影響を与えなくなり、さらに親要素の影響を受けなくなります。そのため、親要素よりも大きいコンポーネントの場合は、コンポーネントの一部が表示されません。また、親要素(余白)の影響で大きくなっていた場合は、元の大きさに戻ります。

ここで、「REFERENCE BOX」と表示されている水平ボックスの設定を以下のように変更した例を紹介します。

プロパティ
position absolute

1つ目のバブルは設定変更前、2つ目のバブルは設定変更後です。

offsetプロパティの例1 offsetプロパティの例4

「REFERENCE BOX」の大きさは、親要素(垂直ボックス)の大きさに影響を与えなくなり、さらに親要素の影響を受けなくなります。そのため、親要素よりも大きい部分(「2」と「3」の行)は表示されていません。また、親要素(余白)の影響で大きくなっていた左右の余白部分は、元の大きさ(テキスト「REFERENCE BOX」の幅)に戻ります。

描画順序について

JSONデータの順に、コンポーネントが描画されます。つまり、JSONデータの最初に書いたコンポーネントが最背面に描画され、最後に書いたコンポーネントがバブルの最前面に描画されます。

描画順序を変更するには、JSONデータに書く順序を変更してください。

関連ページ

{{ $t("form.question.helpful") }}

{{ $t("form.question.detail") }}

{{ $t("form.question.improve") }}

{{ $t("form.info.start") }}{{ $t("form.info.link") }}{{ $t("form.info.end") }}


{{ $t("form.result.success") }}
{{ $t("form.result.error") }}
{{ $t("form.result.errorLink") }}