bootstrapのモーダルを複数開いたときの問題と対処法
bootstrapのモーダルは複数重ねて開いたときにいくつか細かい問題が発生する。 versionは3系。
2つめのモーダルの背景(.modal-backdrop
)より1つめのモーダルが上に表示されてしまう
標準の挙動
背景(.modal-backdrop
)はmodalごとに、bodyにappendされる(z-indexは.modalのz-index設定値 - 10)
z-indexのスタック文脈について詳しい記事
z-index再入門 - z-indexの仕組み | CodeGrid
問題点
モーダルの数、重なりに関係なく
.modal
は.modal-backgroup
より上に表示される。
対処法
.modal
と.modal-backdrop
のz-indexをstackされている要素を考慮するようにhackする
$(document).on('show.bs.modal', '.modal', function () { var zIndex = 1040 + (10 * $('.modal:visible').length); $(this).css('z-index', zIndex); setTimeout(function() { $('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack'); }, 0); });
bodyスクロールの調整
標準の挙動
body.modal-open
に overflow:hidden
を指定することで、モーダルが開いているときの、body要素のscrollを無効化している
問題点
.modal-open
はbodyに対して設定しているので、モーダルが複数ある場合は考慮されていない。
なので、2つめのモーダルを閉じたときに body.modal-open
が外れてしまい、まだ開いているモーダルがあるのにbodyのスクロールが有効になってしまう。
対処法
モーダルを閉じた後のeventで、まだ開かれているモーダルがあるときは、再度 body.modal-open
をつける
$(document).on('hidden.bs.modal', '.modal', function () { $('.modal:visible').length && $(document.body).addClass('modal-open'); });
right paddingの調整
標準の挙動
モーダルを開く際に、bodyに縦スクロールが発生している場合、.modal
(.modal-dialog
ではない)に対してスクロールバーの幅分paddingRightを指定する。
結果モーダルはスクロールバーの幅分を除いた表示領域内でセンタリングされる。
問題点
2つめのモーダルを開く際はbodyに overflow: hidden
が指定されているため(body.moda-open
によって)スクロールバーが発生していない判定になり、paddingRightが設定されない。
結果、2つめのモーダルが若干右にずれる形になる。
また、1つめのモーダルで縦スクロールが発生している場合、1つめのモーダルはスクロールバー幅分を除いた領域でセンタリングされるが、2つめのモーダルはスクロール幅分を考慮しない領域でセンタリングされるので、2つめが若干右にずれる。
対処法
うーむ。。