Center spinner in viewport on bootstrap overlay

Viewed 2082

I'm using the bootstrap-vue overlay on a page that has long content scrolled via the browser window.

<b-overlay :show="loading">

The overlay correctly covers all of the content, even the part below the viewport, but the overlay's built-in spinner is centered on the content rather than the viewport, so the spinner ends up near or below the bottom of the viewport when the content is long enough.

I've tried custom content via a slot, like this...

<b-overlay :show="loading">
  <template v-slot:overlay>
    <div style="???" class="text-center">
      <p style="???">Make me a spinner and center me on the viewport</p>
      <b-button
    </div>
  </template>

...with dozens of ideas for style="???", including position:absolute with different tops, including top=50vh, including !important strewn around, etc., but the content doesn't budge.

// Note that this snippet doesn't run, because I don't see a way to get
// bootstrap-vue via CDN
var app = new Vue({
  el: '#app',
  data: function() {
    return {
      message: 'Hello Vue!',
      messages: []
    }
  },
  mounted() {
    for (let i=0; i<50; i++)
      this.messages.push(i)
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <b-overlay :show="true">
  {{ message }}
  <!-- long content below extends the overlay size -->
  <!-- this moves the spinner down and off the viewport -->
  <ul>
    <li v-for="m in messages" :key="m">{{m}}</li>
  </ul>
  </b-overlay>
</div>

I think key to solving this is finding the CSS selector that allows me to change the spinner's position to "fixed" as opposed to "absolute" which seems to be what bootstrap generates.

enter image description here

2 Answers

To get spinner on center of screen you need to make it as direct child of body. If it is nested it will have restrict area inside immediate parents area. Try to add that separately or once your DOM ready detach overlay and append to body tag.

I ran into the same issue. Adding this line of CSS on the component resolved it for me:

<style>
.position-absolute {
  position: fixed !important;
}
</style>

Note: make sure to not include the scoped keyword in your <style> tag, as this will not work for Bootstrap classes.

Related