35
32

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Bootstrap 3からBootstrap 5に移行してみた

Last updated at Posted at 2021-01-24

これまでずっと、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が不要になったことです。

変更前

index.html
    <!-- 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>

変更後

index.html
    <!-- 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で以下を追加で取り込みます。

index.html
    <link rel="stylesheet" href="dist/css/open-iconic-bootstrap.min.css">

使うときには以下のように変わります。glyphiconではなくoiになります。

変更前

index.html
<button class="btn btn-default glyphicon glyphicon-paperclip" v-on:click="clip_copy(uuid_uuid)"></button>

変更後

index.html
<button class="btn btn-secondary oi oi-paperclip" v-on:click="clip_copy(uuid_uuid)"></button>

当然ながら、絵も名前も違うので、目で見て似たような絵を探す必要があります。

class=nav-linkの追加

Navbarを使っている場合、タブの記述において、aに「class="nav-link"」を付ける必要があります。
また、タブにドロップダウンを付ける場合、キャラット()の指定は不要になりました。

変更前

index.html
        <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>

変更後

index.html
        <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は不要になりました。
例えば以下のような場合です。

index.html
            <div id="blecent" class="tab-pane fade in">
                <h2 class="page-header">BLE Central</h2>

page-headerの代わりにmodal-header

page-headerは無くなったので、どれでも良いのですが、とりあえず、modal-headerで代用しました。

変更前

index.html
            <div id="blecent" class="tab-pane fade in">
                <h2 class="page-header">BLE Central</h2>

変更後

index.html
            <div id="blecent" class="tab-pane fade">
                <h2 class="modal-header">BLE Central</h2>

panalをcardに置き換え

パネルがなくなり、Cardに代わりました。
Collapseを使っていた場合は、CollapseやAccordionに代替するのもありです。

変更前

index.html
                <div class="panel ">
                    <div class="panel-heading">
                        ヘッダー
                    </div>
                    <div class="panel-body">
                      ボディ
                    </div>
                    <div class="panel-footer">
                       フッター
                    </div>
                </div>

変更後

index.html
                <div class="card">
                    <div class="card-header">
                        ヘッダー
                    </div>
                    <div class="card-body">
                      ボディ
                    </div>
                    <div class="card-footer">
                      フッター
                    </div>
                </div>

labelの太字が無効

これまでは、目立たせる意味でで囲って太字にしていましたが、それが無効になりました。
手動で太字にする必要があります。
そこで、cssに記載しておきます。

css/start.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を付けていましたが、不要になりました。

変更前

index.html
                <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>

変更後

index.html
                <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”対象に変更

変更前

image.png

変更後

image.png

・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を付ける。

変更前

index.html
<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>

変更後

index.html
<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の場合には、右端にキャラットが付くのでお好みで。

変更前
image.png

変更後
image.png

使う場合は書き方が特殊で、すぐ忘れるので、以下のようにVueのコンポーネントにしています。

変更前

js/components_bootstrap.js
  '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>`,
  }

変更後

js/components_bootstrap.js
  '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指定にしました。

変更前

index.html
<td v-bind:bgcolor="color_value">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>

変更後

index.html
<td v-bind:style="{ 'background-color': color_value }">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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に数字を入れます。

変更前

index.html
      <div class="panel">

変更後

index.html
      <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で以下をロードします。

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>

呼び出しはこんな感じ

js/methods_bootstrap.js
    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を実装します。

js/methods_bootstrap.js
    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が定義されている前提です。以下は例。

index.html
        <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で実装します。

js/methods_bootstrap.js
    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も同様です。

js/methods_bootstrap.js
    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やボタンと横並びに表示すると、縦方向に中央配置されていません。直すのが面倒なので直していません。

以上

35
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
32

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?