これまでずっと、Bootstrap3で使っていたのですが、そろそろ新しいバージョンに切り替えようと思います。
ちょうど、Bootstrap 5でJQueryに依存しなくなったので、よい機会かなあと。
ですが、うわさに聞いていた通り、Bootstrap 3から4への移行で細かな差異があり、移行は結構手間がかかりました。また、Bootstrap 5になってから、JQueryがなくなったので、それの影響もありました。
今回は既存のBootstrap 3ベースで動いているものをBootstrap 5に移行するにあたり、変更した部分を整理しておきます。
ちなみに、マニュアルはそこまで詳しくは読んでおらず、実動作で試行錯誤しながら直したので、もっと良い直し方があるかもしれません。
参考URL
Bootstrap 5.1.x
https://getbootstrap.com/docs/5.1/getting-started/introduction/
Bootstrap 3.4.x
https://getbootstrap.com/docs/3.4/getting-started/
以下のコンテンツを移行しました。
Bootstrap3.4.1版とBootstrap5版の両方を置きましたので、比較してみてください。
また、実際にWebページとして見れますので、見た目も比較してみてください。
Bootstrap 3.4.1で動かしていたもの
GitHub:https://github.com/poruruba/utilities5/tree/main/utilities
Webページ:https://poruruba.github.io/utilities5/utilities
Bootstrap 5に移行後
GitHub:https://github.com/poruruba/utilities5/tree/main/utilities5
Webページ:https://poruruba.github.io/utilities5/utilities5
※もし上記のページの内容についてご興味がありましたら、以下をご参照ください。
便利ページ:Javascriptでちょっとした便利な機能を作ってみた
変更箇所のサマリ
■Bootstrap変更に伴う変更
- CDN取得先の変更
- Glyphiconの代替
- class=nav-linkの追加
- data-toggleからdata-bs-toggleに変更
- class=”fade in”のinの削除
- page-headerの代わりにmodal-header
- panalをcardに置き換え
- labelの太字が無効
- btn-defaultの代わりにbtn-secondary
- class="input-group-btn" が不要
- class=”form-control”の範囲拡大
- class="form-inline"の廃止
- col-xs-*が col-*に変更
- collapseはaccordionで代用
- text-left/rightの変更
- pull-left/rightの変更
- img-responsiveをimg-fluidに変更
- 属性bgcolorをstyleで代用
- マージンは手動指定
■JQuery廃止に伴う変更
- セレクタ$の置き換え
- Toastの代替
- modalの実装追加
- Collapseの実装追加
- Tab選択の実装追加
Bootstrap変更に伴う変更
CDN取得先の変更
v3.4系からv5系に変えたための当然の変更です。
注目は、JQueryが不要になったことです。
変更前
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" crossorigin="anonymous"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap-theme.min.css" integrity="sha384-6pzBo3FDv/PJ8r2KRkGHifhEocL+1X2rVCTTkUfGk7/0pbek5mMa1upzvWbrUbOZ" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
変更後
<!-- Latest compiled and minified CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
Glyphiconの代替
残念ながら、Glyphiconが同梱されなくなりました。手軽に使えてよかったのですが。。。
そこで、代替として「Open Iconic」を使うようにしました。
OPEN ICONIC
https://useiconic.com/open
本日時点では、v1.1.0のようです。
ダウンロードしてとりあえず以下に配置します。
open-iconic-master.zip\open-iconic-master\font\fonts*
→
dist/fonts/*
open-iconic-master.zip\open-iconic-master\font\css\open-iconic-bootstrap.min.css
→
dist/css/open-iconic-bootstrap.min.css
そして、index.htmlで以下を追加で取り込みます。
<link rel="stylesheet" href="dist/css/open-iconic-bootstrap.min.css">
使うときには以下のように変わります。glyphiconではなくoiになります。
変更前
<button class="btn btn-default glyphicon glyphicon-paperclip" v-on:click="clip_copy(uuid_uuid)"></button>
変更後
<button class="btn btn-secondary oi oi-paperclip" v-on:click="clip_copy(uuid_uuid)"></button>
当然ながら、絵も名前も違うので、目で見て似たような絵を探す必要があります。
class=nav-linkの追加
Navbarを使っている場合、タブの記述において、aに「class="nav-link"」を付ける必要があります。
また、タブにドロップダウンを付ける場合、キャラット()の指定は不要になりました。
変更前
<ul class="nav nav-tabs">
<li v-for="(link, index) in favorite_link"><a v-bind:href="'#' + link" data-toggle="tab">{{get_tab_name(link)}}</a></li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown">ユーティリティ <span class="caret"></span></a>
<ul class="dropdown-menu">
<li v-for="(link, index) in tab_list"><a v-bind:href="'#' + link.id" data-toggle="tab" v-on:click="favorite_add(link.id)">{{link.name}}</a></li>
</ul>
</li>
</ul>
変更後
<ul class="nav nav-tabs">
<li v-for="(link, index) in favorite_link"><a class="nav-link" v-bind:href="'#' + link" data-bs-toggle="tab">{{get_tab_name(link)}}</a></li>
<li class="dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown">ユーティリティ</a>
<ul class="dropdown-menu">
<li v-for="(link, index) in tab_list"><a class="dropdown-item" v-bind:href="'#' + link.id" data-bs-toggle="tab" v-on:click="favorite_add(link.id)">{{link.name}}</a></li>
</ul>
</li>
</ul>
data-toggleからdata-bs-toggleに変更
上記のNavbarもそうですが、いろんなところでdata-toggleを使っていると思いますが、data-bs-toggleに変更します。
class="fade in"のinの削除
fade inと記載していた個所のinは不要になりました。
例えば以下のような場合です。
<div id="blecent" class="tab-pane fade in">
<h2 class="page-header">BLE Central</h2>
page-headerの代わりにmodal-header
page-headerは無くなったので、どれでも良いのですが、とりあえず、modal-headerで代用しました。
変更前
<div id="blecent" class="tab-pane fade in">
<h2 class="page-header">BLE Central</h2>
変更後
<div id="blecent" class="tab-pane fade">
<h2 class="modal-header">BLE Central</h2>
panalをcardに置き換え
パネルがなくなり、Cardに代わりました。
Collapseを使っていた場合は、CollapseやAccordionに代替するのもありです。
変更前
<div class="panel ">
<div class="panel-heading">
ヘッダー
</div>
<div class="panel-body">
ボディ
</div>
<div class="panel-footer">
フッター
</div>
</div>
変更後
<div class="card">
<div class="card-header">
ヘッダー
</div>
<div class="card-body">
ボディ
</div>
<div class="card-footer">
フッター
</div>
</div>
labelの太字が無効
これまでは、目立たせる意味でで囲って太字にしていましたが、それが無効になりました。
手動で太字にする必要があります。
そこで、cssに記載しておきます。
label.title {
font-weight: bold;
}
使い方(変更前)
<label>タイトル</label>
使い方(変更後)
<label class=”title”>タイトル</label>
btn-defaultの代わりにbtn-secondary
btn-defaultなど、****-defaultがなくなりました。とりあえず、btn-secondaryで代用しました。
変更前
<button class="btn btn-default">All Read</button>
変更後
<button class="btn btn-secondary">All Read</button>
class="input-group-btn" が不要
Inputにボタンをくっつけるときに、input-group-btnを付けていましたが、不要になりました。
変更前
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-default glyphicon glyphicon-paperclip" v-on:click="clip_copy(uuid_uuid)"></button>
</span>
<input type="text" class="form-control" v-model="uuid_uuid" readonly>
</div>
変更後
<div class="input-group">
<button class="btn btn-secondary oi oi-paperclip" v-on:click="clip_copy(uuid_uuid)"></button>
<input type="text" class="form-control" v-model="uuid_uuid" readonly>
</div>
class=”form-control”の範囲拡大
form-controlを適用できるものが増えたり、見た目がまともになりました。
・type=”file”がclass=”form-control”対象に変更
変更前
変更後
・type=selectはform-selectに変更
form-controlでも良かったのですが、form-selectにしないと、キャラットが表示されません。
・type=rangeやcolorも見栄え向上
付けないと、横幅を自動的に伸縮してくれないです。
以下を付けるようにします。
class="form-control-color"
class="form-range"
class="form-inline"の廃止
結構form-inlineを多用していたので、これが一番痛かったです。修正も面倒です。
- 明示的にclass="row"で囲う。
- 各要素に、class=”col-auto”を付ける。ただし、インプットやセレクトは、一つ上にdivやspanで囲い、そこにcol-autoを付ける。
変更前
<div class="form-inline">
<label>タイトル</label>
<button class="btn btn-default btn-sm" v-on:click="date_duration_reset">リセット</button>
<select class="form-control" v-on:change="date_process()" v-model="date_duration_unit">
<option value="year">年</option>
<option value="month">月</option>
<option value="day">日</option>
<option value="hour">時</option>
<option value="minute">分</option>
<option value="second">秒</option>
</select>
<input type="number" class="form-control" v-on:change="date_process()" v-model.number="date_duration">
<button class="btn btn-primary btn-sm" v-on:click="date_process()">経過期間→経過後日時</button>
</div>
変更後
<div class="row">
<label class="col-auto title">タイトル</label>
<button class="col-auto btn btn-secondary btn-sm" v-on:click="date_duration_reset">リセット</button>
<span class="col-auto">
<select class="form-select" v-on:change="date_process()" v-model="date_duration_unit">
<option value="year">年</option>
<option value="month">月</option>
<option value="day">日</option>
<option value="hour">時</option>
<option value="minute">分</option>
<option value="second">秒</option>
</select>
</span>
<span class="col-auto">
<input type="number" class="form-control" v-on:change="date_process()" v-model.number="date_duration">
</span>
<button class="col-auto btn btn-primary btn-sm" v-on:click="date_process()">経過期間→経過後日時</button>
</div>
class="col-xs-*"が"col-*"に変更
グリッド指定でxsを使っていた場合はxsを省きます。
collapseはaccordionで代用
これは必須ではないですが、collapseも引き続きBootstrap5で使えますが、accordionの場合には、右端にキャラットが付くのでお好みで。
使う場合は書き方が特殊で、すぐ忘れるので、以下のようにVueのコンポーネントにしています。
変更前
'collapse-panel': {
props: ['id', 'collapse', 'title'],
template: `
<div class="panel">
<div class="panel-heading">
<div class="panel-title"><a data-toggle="collapse" v-bind:href="'#' + id">{{title}}</a></div>
</div>
<div class="panel-collapse" v-bind:class="collapse=='true' ? 'collapse' : 'collapse in'" v-bind:id="id">
<slot name="content"></slot>
</div>
</div>`,
}
変更後
'collapse-panel': {
props: ['id', 'collapse', 'title'],
template: `
<div class="accordion mt-3">
<div class="accordion-item">
<div class="accordion-header">
<button class="accordion-button" v-bind:class="collapse=='true' ? 'collapsed' : ''" type="button" data-bs-toggle="collapse" v-bind:href="'#' + id"><label class='title'>{{title}}</label></button>
</div>
<div class="accordion-collapse" v-bind:class="collapse=='true' ? 'collapse' : 'collapse show'" v-bind:id="id">
<slot name="content"></slot>
</div>
</div>
</div>`,
}
こんな感じで定義します。
<collapse-panel id="html5_audio" title="Audio" collapse="true">
<span slot="content">
<div class="card-body">
・・・
</div>
<div class="card-footer">
・・・
</div>
</span>
</collapse-panel>
属性bgcolorをstyleで代用
なぜか、HTMLでの属性bgcolorの指定が横取りされてしまうようで、style指定にしました。
変更前
<td v-bind:bgcolor="color_value"> </td>
変更後
<td v-bind:style="{ 'background-color': color_value }"> </td>
text-left/rightの変更
text-left・text-rightは、それぞれ、text-start・text-endに名前が変更となりました。
pull-left/rightの変更
pull-left・pull-rightは、それぞれ、float-start・float-endに名前が変更となりました。
img-responsiveをimg-fluidに変更
img-responsiveがimg-fluidに名前が変更となっています。
マージンは手動指定
これまでPanelなどを並べて表示しても、マージンが付与されていたので、くっついて表示されることはなかったのですが、Bootstrap5では自分でマージンを指定します。
class=m-X で、Xに数字を入れます。
変更前
<div class="panel">
変更後
<div class="accordion m-3">
JQuery廃止に伴う変更
JQueryに依存しなくなったのは良いのですが、いくつか使えない機能が出てきましたので、代替を用意します。
セレクタ$の置き換え
JQueryで慣れ親しんできた$(***) によるセレクタは使えなくなるので、ブラウザ標準の書式に変えます。
変更前
$('#id名')
変更後
document.querySelector('#id名')
Toastの代替
これまでは、有志のToastのライブラリを使ってきましたが、ほとんどがJQueryを前提としたものでした。もちろん、Bootstrap5にもToastはあるのですが、使いにくいし、Toast表示をスタックできないようです。
そこで、JQueryに依存しないライブラリに切り替えます。
ooyun0/siiimple-toast
https://github.com/ooyun0/siiimple-toast
https://www.cssscript.com/demo/animated-queued-toast-messages-pure-javascript-siiimple-toast/
index.htmlで以下をロードします。
<link href="https://cdn.jsdelivr.net/npm/siiimple-toast/dist/style.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/siiimple-toast/dist/siiimple-toast.min.js"></script>
呼び出しはこんな感じ
toast_show: function(message, level = "success"){
if( level == 'message' )
siiimpleToast.message(message, { position: 'top|right' });
else if( level == 'alert' )
siiimpleToast.alert(message, { position: 'top|right' });
else
siiimpleToast.success(message, { position: 'top|right' });
},
modalの表示/非表示切り替えの実装追加
Javascriptから、Modalを表示したり非表示するためのJavascriptを実装します。
dialog_open: function(target, backdrop = 'static'){
const element = document.querySelector(target);
let modal = bootstrap.Modal.getInstance(element);
if( !modal )
modal = new bootstrap.Modal(element, { backdrop: backdrop, keyboard: false });
modal.show();
},
dialog_close: function(target){
const element = document.querySelector(target);
let modal = bootstrap.Modal.getInstance(element);
if( modal )
modal.hide();
},
上記の関数はあらかじめ、index.htmlにModalが定義されている前提です。以下は例。
<div class="modal" id="binary_image_dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">内容表示
<span class="pull-right">
<button class="btn btn-secondary" v-on:click="dialog_close('#binary_image_dialog')">閉じる</button>
</span>
</h4>
</div>
<div class="modal-body">
<img v-if="binary_type.startsWith('image/')" v-bind:src="binary_dataurl" class="img-responsive" />
<pre v-if="binary_type.startsWith('text/')">{{binary_text}}</pre>
</div>
</div>
</div>
</div>
ここで、1点注意があります。
Modalでよく使うfadeを使う場合です。
fadeを使うことで、Modal表示・非表示の際にアニメーションを付けることができます。
しかしながら、modal.show()で表示したとき、このアニメーションが終わる前に関数から返ってくるため、すぐにmodal.hide()を呼び出してもModalが表示されたままとなる場合があります。
this.dialog_open('#binary_image_dialog');
this.dialog_close('#binary_image_dialog');
表示のアニメーション中に受け取った非表示要求が無視されるためです。
なので、デフォルトでfadeはつけていません。付ける場合は注意して使ってください。
Collapseの実装追加
Modal同様に、Collapseを開いたり閉じたりする関数をJavascriptで実装します。
panel_open: function(target){
var element = document.querySelector(target);
var collapse = bootstrap.Collapse.getInstance(element);
if( !collapse )
collapse = new bootstrap.Collapse(element, { toggle: false });
collapse.show();
},
panel_close: function(target){
var element = document.querySelector(target);
var collapse = bootstrap.Collapse.getInstance(element);
if( !collapse )
collapse = new bootstrap.Collapse(element, { toggle: false });
collapse.hide();
},
Tab選択の実装追加
Tabも同様です。
tab_select: function(target){
var element = document.querySelector("a[href='" + target + "']");
var tab = bootstrap.Tab.getInstance(element);
if( !tab )
tab = new bootstrap.Tab(element);
tab.show();
},
未解決事項
今回は、既存の実装をBootstrap5に移行しましたので、既存で使っていた部分だけの差分をまとめました。
Bootstrapはいろんな機能がありますので、そのほんの一助になればと思います。
- Navbarのドロップダウンを選択すると、選択状態のままとなってしまいます。表示だけなので問題ないですが。(Bootstrapのバグ?) → 最新のBootstrap5では治っているようです。
- チェックボックスを他のInputやボタンと横並びに表示すると、縦方向に中央配置されていません。直すのが面倒なので直していません。
以上