画像崩れ・バッジ肥大化・ボタン文字改行のレイアウト問題を解決する極意
MarTech(マーケティングテクノロジー)システムの開発、ECのSNSマーケティング、またはゲームコミュニティでの自動化配信(CS2の抽選・ガチャ機能など)において、
LINE Flex Message
はユーザーのコンバージョン率を爆発的に高める最強の武器です。特にモダンなダークモード(Dark Mode)に対応したフルスクリーンの高質感なカード型 UI は、タップ率を飛躍的に向上させます。
しかし、多くのフロントエンド・バックエンドエンジニア(例えば、Go言語の
line-bot-sdk-go
を使用するアーキテクトなど)が公式の Flex Message Simulator で綺麗に調整した JSON を、本番環境で実機に配信した途端、以下のような絶望的なレイアウト崩れに直面することがあります:背景を透過した 3D アイテム画像がスマホ画面で横に引き伸ばされて潰れてしまう、精緻にデザインした角丸の徽章バッジがワイド画面のスマホで太った「ソーセージ」のように肥大化する、ボタンの文字がスペース不足で無情にも2行に強制改行される...
本記事では、これら実務で遭遇する3大「ビジュアルの死穴(致命的な罠)」をピクセル単位で解剖します。
🛑 罠1:画像の比率崩れ(Object Distortion)
❌ 失敗のケース
4:3 に近い比率の、背景を透過したクールな武器ボックス画像を配置する際、JSON に以下のように記述してしまうケースです:
"aspectRatio": "16:9",
"aspectMode": "cover"
🔍 原因の分析と解決策
底層のロジック: 16:9 は画像コンテナを強制的に上下に押しつぶし、さらに cover 属性がコンテナ内を無理やり埋め尽くそうとトリミングを行います。この2つが LINE のレンダリングエンジン内で衝突した結果、画像が横方向に極端に引き伸ばされてしまいます。正しい解決策: 画像の物理比率を解放し、アスペクト比を画像本来の形に近い 4:3 に調整した上で、aspectMode を fit に変更します。これにより、画像はあらゆる画面サイズで等倍に縮小・拡大され、絶対に歪んだり引き伸ばされたりしなくなります。また、画像の両端にある鮮やかなパーティクルエフェクトもカットされずに完全な状態で表示できます!
🛑 罠2:Flex 属性によるバッジの強制肥大化(ソーセージ化の呪い)
❌ 失敗のケース
"type": "box",
"layout": "horizontal",
"contents": [
{ "type": "box", "layout": "vertical", "backgroundColor": "#F97316", "flex": 2 },
{ "type": "box", "layout": "vertical", "flex": 8 }
]
🔍 原因の分析と解決策
底層のロジック: カード全体のサイズを最大幅の mega に設定した場合、このバッジコンテナはカード全体の横幅が広がるにつれて、その分配比率(flex: 2)のまま横方向に無限に引き伸ばされます。文字に対して余白が広がりすぎ、バッジが太ったブロック(ソーセージ)のように肥大化してしまいます。正しい解決策: 物理的なサイズ制限を持たない flex 属性を完全にカットし、Box に直接固定の物理幅を設定すること(例: "width": "58px")が唯一の正攻法です。外側のレスポンシブな Flex Box から切り離すことで、どんなワイド画面でもバッジの美しさを維持できます。
🛑 罠3:複数ボタン並列時の「文字自動改行」(Text Wrapping)
❌ 失敗のケース
横並びで3つのアクションボタンを配置した際、中国語などの短い文字数環境では完璧に見えても、他言語(日本語など)にローカライズした途端にレイアウトが崩れるケースです:
活動詳情
が
イベント詳細
(5文字)、
立即開箱
が
🎁 今すぐ開封
(7文字) に変わることで、ボタン内のテキストがスペース不足で無情にも2行に強制改行され、大手の公式アカウントが持つような高級感が一瞬で破壊されてしまいます!
🔍 原因の分析と解決策
底層のロジック: 日本語のフォントや絵文字は文字幅を消費しやすく、さらに LINE 純正の button コンポーネントは内部にデフォルトで厚めの内余白(Padding)を持っています。この状態で、両端に flex: 1 などの空の Box を配置して中央寄せ(スプリング効果)を行ってしまうと、ボタンが利用できる横方向の有効空間が極限まで圧迫され、自動改行が発生します。正しい解決策: 「スプリング権重の微調整(4:25:25:25:4)」+「ラベル文字の洗練化」を採用します。左右の空の Box の flex 値を最小限の 4 に下げ、中央の3つのボタンの flex 値を 25 まで引き上げることで、デッドスペースをボタンの幅に還元します。さらに、ボタンテキストを短い表現(例:詳細 や 🎁 開封)に精練することで、文字が1行の中に美しく収まり、洗練された UI 質感を最大化できます!
🎯 最終ピクセル完全調優済みソースコード(至高のサイバーパンク・ガチャカード)
以下は、実務での検証を重ね、LINEのデフォルトの白い背景を完全に覆い隠し、100%フルスクリーンのサイバーパンク風(ダークブルー)の世界観を表現した完成版 JSON コードです。そのまま本番環境にコピー&ペーストしてご利用いただけます:
| ファイル名 | バリデーション状態 |
template.json | 🟢 LINE Flex Schema 合格 |
{
"type": "bubble",
"size": "mega",
"body": {
"type": "box",
"layout": "vertical",
"backgroundColor": "#0F172A",
"paddingAll": "0px",
"contents": [
{
"type": "image",
"url": "https://im.gurl.eu.org/file/AgACAgEAAxkDAAEBjBBqGjwpp3adBiz1fvi032gaf_FJbgACvQtrG82J2UQraRTtROGx1wEAAwIAA3kAAzsE.png",
"size": "full",
"aspectRatio": "4:3",
"aspectMode": "cover"
},
{
"type": "box",
"layout": "vertical",
"paddingStart": "20px",
"paddingEnd": "20px",
"paddingTop": "16px",
"paddingBottom": "20px",
"spacing": "8px",
"contents": [
{
"type": "box",
"layout": "horizontal",
"contents": [
{
"type": "box",
"layout": "vertical",
"backgroundColor": "#F97316",
"cornerRadius": "8px",
"paddingAll": "4px",
"width": "58px",
"contents": [
{
"type": "text",
"text": "LIMITED",
"color": "#FFFFFF",
"size": "xxs",
"align": "center",
"weight": "bold"
}
]
}
]
},
{
"type": "text",
"text": "🎉 おめでとうございます!「エアドロップ武器箱」の抽選権を獲得しました!",
"weight": "bold",
"color": "#FFFFFF",
"size": "md",
"wrap": true,
"margin": "md"
},
{
"type": "text",
"text": "FlexCraft トレンドフェスティバルへの参加資格がアンロックされました。限定スキンや豪華周辺機器が手に入るチャンス!今すぐ下のボタンからシェア、またはガチャを引いて開封しましょう!",
"color": "#CBD5E1",
"size": "sm",
"wrap": true,
"lineHeight": "md",
"margin": "xs"
}
]
},
{
"type": "box",
"layout": "horizontal",
"spacing": "6px",
"paddingStart": "16px",
"paddingEnd": "16px",
"paddingBottom": "20px",
"contents": [
{
"type": "box",
"layout": "vertical",
"flex": 4
},
{
"type": "button",
"style": "primary",
"color": "#22C55E",
"height": "sm",
"action": {
"type": "uri",
"label": "シェア",
"uri": "https://liming.me"
},
"flex": 25
},
{
"type": "button",
"style": "secondary",
"color": "#475569",
"height": "sm",
"action": {
"type": "uri",
"label": "詳細",
"uri": "https://liming.me"
},
"flex": 25
},
{
"type": "button",
"style": "primary",
"color": "#F97316",
"height": "sm",
"action": {
"type": "uri",
"label": "🎁 開封",
"uri": "https://liming.me"
},
"flex": 25
},
{
"type": "box",
"layout": "vertical",
"flex": 4
}
]
}
]
}
}
🛠️ 職人は器を厳選する(工欲善其事,必先利其器)
LINE Flex Message の JSON を直接手書きすることは、コンパイラがない時代にアセンブリ言語を書くようなものです。わずかな
padding
の設定ミスや、プロパティの誤用(例えば、Web 用の
lineHeight: 1.5
のような数値をそのまま LINE に渡すなど)が、即座に送信エラー(
APIError 400
)を引き起こします。
このような開発現場のペインポイントを解消するために、私は LINE Flex Message 専門のビジュアル開発プラットフォーム
[FlexCraft]
を構築しました。3層の沙盒検証(厳格なスキーマ検証)機能を搭載し、ソースコード双方向同期モード(
customViewHtml
)にも対応しています。不正な属性や比率の崩れをフロントエンド側で未然にブロックするため、テンプレートの開発効率を10倍以上に高めることができます!
👉
GitHub にアクセスして多言語対応のテンプレートリポジトリをダウンロード https://github.com/arieslee/line-flex-message-templates
タイトルの上に『LIMITED』という精緻な限定オレンジバッジを配置し、それを左寄せにしたい時、私たちはついつい
flex
権重(比率分配)を使って空間を分けてしまいがちです: