bootstrap-vue / bootstrap-vue

BootstrapVue provides one of the most comprehensive implementations of Bootstrap v4 for Vue.js. With extensive and automated WAI-ARIA accessibility markup.
https://bootstrap-vue.org
MIT License
14.51k stars 1.88k forks source link

Modal backdrop is not getting the .show and .fade classes applied #3438

Closed garhbod closed 5 years ago

garhbod commented 5 years ago

Describe the bug

Modal backdrop is opaque because it is not getting the .show and .fade classed applied

Steps to reproduce the bug

  1. Create a modal assigned to a button using its id
  2. Click on the button
  3. See Error

Expected behavior

Backdrop to be transparent

Versions

Libraries:

garhbod commented 5 years ago

Issue isn't present with BootstrapVue: 2.0.0-rc.20

tmorehouse commented 5 years ago

In docs, the backdrop is transparent:

image

See answer at https://github.com/bootstrap-vue/bootstrap-vue/issues/3400#issuecomment-498278454

Since we are using new re-usable transitions (to reduce codebase size), and Bootstrap V4.x transition styles are not truly compatible with how Vue handles transitions, not without a lot of extra JS hooks on the transition (see issue https://github.com/vuejs/vue/issues/9986) just to keep the show class on the element when the initial transition happens.

The fade and show classes are only applied during the transition (fade is applied on transition v-enter-active and v-leave-active, and show on v-enter-to and v-leave... see https://vuejs.org/v2/guide/transitions.html#Transition-Classes

Also, please upgrade Bootstrap to V4.3.1 for the latest CSS. and make sure you are loading BootstrapVue CSS after Bootstrap V4.3.1 CSS

tmorehouse commented 5 years ago

Also see PR https://github.com/bootstrap-vue/bootstrap-vue/pull/3281

Modal backdrop, tabs, alert, and toast all now use the re-usable transition helper component.

Modal backdrop needed one extra line of custom CSS to make it work (as added via the mentioned PR)

garhbod commented 5 years ago

I'm not sure the bandaid fix of the following is the answer

.modal-backdrop:not(.show):not(.fade) {
  opacity: $modal-backdrop-opacity;
}

Why can't the .modal-backdrop have the same transition applied to it as the .modal itself? The .modal div ends up with modal fade show d-block Is this the work of above mentioned "lot of extra JS hooks"?

tmorehouse commented 5 years ago

We'e simplified the SCSS from above to:

.modal-backdrop {
  opacity: $modal-backdrop-opacity;
}

The .modal has issues due to two transitions happening as the same time with two different durations: the fade transition, and the transform transition that slides the modal down... which has a longer duration. Using a single transition component would cause the slide down transition to abruptly stop once the fade transition ends. We hae tried to merge the transitions into a single transition but it just doesn't work with Bootstrap's SCSS/CSS.

The code needed to keep the show class active after the initial transition involves keeping data state of the transition stages, adding in requestAnimationFrame timeouts to add/remove the show class, and exit handlers to detect when the show class needs to be removed (as long as the transition isn't cancelled). It is a lot more than just one or two lines of code (I know, I wrote a good chunk of the original code). Now double that due to the .modal having one (well two transitions), and the .modal-backdrop having a transition (which could be a different duration that modal's fade, as they are separately configurable with SCSS variables).

modal fade show d-block was more of a hack / bandaid fix to get modal working, than using the above one line of SCSS to simplify the modal backdrop transition.

Also note, the backdrop and modal are not nested inside a same transitional component. they are two distinct entities, with possibly two distinct transition durations. Vue's transition handler can only pick out the transition duration on the root element in the transition, not nested elements (which the modal slide transition is).

tmorehouse commented 5 years ago

Is there any reason why you need the show class to remain on the .modal-backdrop?

gevinduM commented 4 years ago

so what is the answer for this question? my b-modal back ground working fine in development, but once I deployed it I am getting this issue.

Peppe87 commented 4 years ago

I'm experiencing this problem too. I'm currently importing just modalPlugin and bootstrap-vue.css, as the Vue.js app is placed on a page where "normal" bootstrap 4 is already added via other means.

So my import is like:

import "bootstrap-vue/dist/bootstrap-vue.css";
import { ModalPlugin } from "bootstrap-vue";
Vue.use(ModalPlugin);

And in production mode the backdrop don't get the correct opacity. For now I've just overridden the opacity manually via css, but I'd like to know if it is still a bug or if maybe I'm doing something wrong.

mohaimenkhalid commented 4 years ago

$('.modal-backdrop').remove();