Bootstrap5で画像付きメニューボタンとか作ってみる
社内Webツールでヘッダ部分に画像付きメニューを横並びで出したい要望があったので、そんなのを調べて作ってみます。せっかくBootstrapで手早くやっているので、レイアウトにあんまり時間をかけたくないです。イメージ的には箱的なものをずらっと並べてやって、箱自体をリンクにしてやればそれっぽいかなと思い、そんな感じの部品となるとcardで出来るんじゃない?と思ったのでcardを使ってやってみます。
とりあえず画像とメニュータイトルをcardに並べてみたけど
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap demo</title>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
</head>
<body>
<div class="container" x-data="data()">
<div class="d-flex flex-row">
<template x-for="menu in menus">
<a class="text-decoration-none" href="javascript:void(0)">
<div class="card mx-1" style="width: 64px; height:64px;">
<div class="card-body">
<img class="w-100" :src="'img/' + menu.img + '.png'"><span x-text="menu.title"></span>
</div>
</div>
</a>
</template>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
<script>
let data = function() {
return {
menus: [
{
img: 'food_konbini_onigiri',
title: 'おにぎり'
},{
img: 'food_spaghetti_vongole_bianco',
title: 'スパゲティ'
},{
img: 'niku_manga',
title: '肉'
}
]
};
};
</script>
</body>
</html>
HTMLの繰り返しを書くのが面倒だったのでalpinejsでループさせています。まぁ、最初はこんなもんですね。とりあえず以下に注意して再構築します。
- card内を上下に分離して上に画像、下にタイトルを
- 文字数がちょっと多いのもあるので横幅を少し広めにして1行表示。表示しきれない部分は非表示
- 画像は上エリアの中で中央表示
調整したらこんな感じになりました。表示しきれない部分の確認のために「スパゲティ」を「スパゲティボンゴレビアンコ」に変更しています。

<div class="card mx-1" style="">
<a class="text-decoration-none text-muted" href="javascript:void(0)">
<div class="card-body p-0" style="width: 80px; height:64px; margin:2px">
<div class="d-flex justify-content-center align-items-start">
<img style="height: calc(64px - 1rem);" :src="'img/' + menu.img + '.png'">
</div>
<div class="d-flex justify-content-center overflow-hidden" style="height: 1rem; line-height: 1rem;" x-text="menu.title">
</div>
</div>
</a>
</div>
cardと絵かタイトルが被らないようにcard-bodyの周り2pxでマージンを取りました。リンクをcardにしているとcard左右のマージンもリンクになっていたのでcard-bodyに充てるように変更しました。文字の高さは1remなので絵の高さをcard-bodyの内部の高さから1rem引いたサイズにしました。あとは細かく中央寄せしたりはみ出し非表示したりした感じです。
まとめ
cardとd-flexでそれっぽい画像付きメニューリストを作れたかと思います。
