bootstrap-vue change the position of <b-modal>

19,841

Solution 1

If you want to put the modal into the specific position, below is my solutuon:

  1. add specific class to <b-modal> by its props=modal-class

  2. then add your styles into myclass > div

You can look into the github (line#:176), Bootstrap-vue will place one div.modal-content(including header/body/foot) into one div with class="modal-dialog" which is the direct child of root.

That is why above solution use the css selector = .myclass > div.

If you look into the dom tree: the structure of one bootstrap-vue modal will be:

one root div (myclass will be added into here) -> one div with modal-dialog -> one div with modal-content -> header/body/footer

Below is one sample: (I put different background-color for modal-dialog, modal-content.)

app = new Vue({ //not vue, it is Vue
  el: "#app",
  data: {
    myclass: ['myclass']
  },
  methods: {
    showModal: function(){
      this.$refs.myModalRef.show()
    }
  }
})
.myclass > div {
  position:absolute !important;
  top: -10px !important;
  left: -10px !important;
  background-color:yellow !important;
}

.myclass > .modal-dialog > .modal-content {
  background-color:red !important;
}
<!-- Add this to <head> -->
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css"/>
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css"/>

<!-- Add this after vue.js -->
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<script src="//unpkg.com/babel-polyfill@latest/dist/polyfill.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>
<div id="app">
    <b-button @click="showModal">
      Open Modal
    </b-button>
  <b-modal ref="myModalRef" :modal-class="myclass" size="lg">
      <h2>Test</h2>
  </b-modal>
</div>

Solution 2

I use

<b-modal
    body-class="modalcart"
    ref="addToCart"
    id="addToCarModal"
    hide-footer
    hide-header
>
<b-container class="text-center modal-product-content">
  <img class="modal-image" src="~/assets/images/add-to-cart.png" alt=""/>

and:

<style lang="scss" scoped>
/deep/ .modalcart {
  font-family: 'poppins-bold';
  /deep/ .modal-product-content {
    padding: 3rem;
    margin: 0 auto !important;
    /deep/ .modal-image {
      height: 150px;
      margin-bottom: 2rem;
      }
    }
  ...
  }
  </style>

and work! thanks
Keep in mind that not work without body-class and /deep/ I use node-sass, vue 3, vue-loader 15

Share:
19,841
Minjun Yu
Author by

Minjun Yu

Work solves all problems.

Updated on June 13, 2022

Comments

  • Minjun Yu
    Minjun Yu almost 2 years

    By default <b-modal> shows on top of the page. When attribute centered is added to the tag. It is centered.

    However, I would like to show the modal with a certain amount of gap under the top of the page.
    The Modal is shown when the home page is opened.

    AppModal.vue

    <template>
    <b-modal ref="thisModalRef" :modal-class="my-modal" size="lg" hide-header hide-footer no-close-on-backdrop hide-header-close>
        //...
    </b-modal>
    </template>
    <script>
    export default {
      data () {
        return {
          mymodal: ['mymodal']
        }
      },
      methods: {
        hideModal () {
          this.$refs.thisModalRef.hide()
        },
        showModal () {
          this.$refs.thisModalRef.show()
        }
      }
    }
    </script>
    
    <style scoped>
      .mymodal > div {
        position: absolute;
        top: 300px;
        right: 100px;
        background-color: yellow;
      }
    </style>
    

    AppHome.vue

    <template>
      <div>
        // omitted
        <AppModal ref="modalRef"></AppModal>
      </div>
    </template>
    
    <script>
    import AppModal from './AppModal'
    
    export default {
      components: {
        AppModal
      },
      data () {
        return {
          msg: 'Welcome to Your Vue.js App'
        }
      },
      methods: {
        showModal: function () {
          this.$refs.modalRef.showModal()
        }
      },
      mounted () {
        this.showModal()
      }
    }
    </script>
    
    <style scoped>
    // ommitted
    </style>
    

    html source related to modal

    <div id="__BVID__16___BV_modal_outer_">
       <div id="__BVID__16" role="dialog" class="modal fade show d-block mymodal" style="padding-right: 15px;">
          <div class="modal-dialog modal-lg">
             <div tabindex="-1" role="document" aria-describedby="__BVID__16___BV_modal_body_" class="modal-content">
                <!---->
                <div id="__BVID__16___BV_modal_body_" class="modal-body">
                   // ommitted
                </div>
                <!---->
             </div>
          </div>
       </div>
       <div id="__BVID__16___BV_modal_backdrop_" class="modal-backdrop fade show"></div>
    </div>
    

    As you can see, mymodal class is correctly applied. But the div .modal-dialog does not have the css properties I give it.

    the real css properties found in dev tools

    .modal-dialog {
        position: relative;
        width: auto;
        margin: 0.5rem;
        pointer-events: none;
    }
    

    I tried adding a custom class to <b-modal> and style it. Nothing worked. Please help.

  • Minjun Yu
    Minjun Yu about 6 years
    thank you, +1. I can see yours works. it is still not working on my end. I have slightly different setup. My <b-modal> is wrapped in a <AppModal> component, which is used in another component. myclass correctly attached to the root tag of <b-modal> but its direct child doesn't have the style. In other word, myclass > div is not working for some reason.
  • Sphinx
    Sphinx about 6 years
    @MinjunYu, it doesn't matter what is the parent for <b-modal>, it probably caused by different version. You can open your web developer, then check the dom tree for <b-modal>, finally apply appropriate css selector. or you can add the html into the question, we can help you from there.
  • Sphinx
    Sphinx about 6 years
    @MinjunYu .myclass > .modal-dialog > .modal-content this one also doesn't work?
  • Minjun Yu
    Minjun Yu about 6 years
    No this one also doesn't work. I have put the related html source and vue components. Thank you!
  • Sphinx
    Sphinx about 6 years
    @MinjunYu, I saw your html source, it is almost same as mine. May I know where you define the css? in one global css file or in current view with <style>?
  • Sphinx
    Sphinx about 6 years
    @MinjunYu, it should be caused by css specificity. add !important should be able to fix the current issue you met. check the updated.