Modal

Use Bootstrap's Vue modal components to add dialogs to your site for lightboxes, user notifications, or completely custom content.

On this page

Live demo

Toggle a working modal demo by clicking the button below. It will slide down and fade in from the top of the page.

vue
<template>
  <!-- Button trigger modal -->
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModal"
  >
    Launch demo modal
  </b-button>
  <!-- Modal -->
  <Modal id="exampleModal">
    <ModalDialog>
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Modal title</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>...</ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Save changes
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
</template>

Static backdrop

When backdrop="static"attribute is setted, the modal will not close when clicking outside it. Click the button below to try it.

vue
<template>
  <!-- Button trigger modal -->
  <b-button
    button="primary"
    toggle="modal"
    target="#staticBackdropLive"
  >
    Launch demo modal
  </b-button>
  <!-- Modal -->
  <Modal
    id="staticBackdropLive"
    backdrop="static"
    :keyboard="false"
  >
    <ModalDialog>
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Modal title</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>
          <p>
            I will not close if you click outside me. Don't even try to press
            escape key.
          </p>
        </ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Understood
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
</template>

Scrolling long content

When modals become too long for the user's viewport or device, they scroll independent of the page itself. Try the demo below to see what we mean.

vue
<template>
  <!-- Button trigger modal -->
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModalLong-1"
  >
    Launch demo modal
  </b-button>
  <!-- Modal -->
  <Modal id="exampleModalLong-1">
    <ModalDialog scrollable>
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Modal title</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody style="min-height: 1500px">
          <b-p>
            This is some placeholder content to show the scrolling behavior for
            modals. Instead of repeating the text the modal, we use an inline
            style set a minimum height, thereby extending the length of the
            overall modal and demonstrating the overflow scrolling. When content
            becomes longer than the height of the viewport, scrolling will move
            the modal as needed.
          </b-p>
        </ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Save changes
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
</template>

You can also create a scrollable modal that allows scroll the modal body by adding scrollable attribute to ModalDialog component.

vue
<template>
  <!-- Button trigger modal -->
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModalLong-2"
  >
    Launch demo modal
  </b-button>
  <!-- Modal -->
  <Modal id="exampleModalLong-2">
    <ModalDialog scrollable>
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Modal title</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>
          <p>
            This is some placeholder content to show the scrolling behavior for
            modals. We use repeated line breaks to demonstrate how content can
            exceed minimum inner height, thereby showing inner scrolling. When
            content becomes longer than the predefined max-height of modal,
            content will be cropped and scrollable within the modal.
          </p>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <p>This content should appear at the bottom after you scroll.</p>
        </ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Save changes
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
</template>

Vertically centered

Add centered attribute to ModalDialog component to vertically center the modal.

vue
<template>
  <!-- Button trigger modal -->
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModalCenter"
  >
    Vertically centered modal
  </b-button>
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModalCenteredScrollable"
  >
    Vertically centered scrollable modal
  </b-button>
  <!-- Modal -->
  <Modal id="exampleModalCenter">
    <ModalDialog centered>
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Modal title</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>This is a vertically centered modal.</ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Save changes
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
  <Modal id="exampleModalCenteredScrollable">
    <ModalDialog
      centered
      scrollable
    >
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Modal title</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>
          <p>
            This is some placeholder content to show a vertically centered
            modal. We've added some extra copy here to show how vertically
            centering the modal works when combined with scrollable modals. We
            also use some repeated line breaks to quickly extend the height of
            the content, thereby triggering the scrolling. When content becomes
            longer than the predefined max-height of modal, content will be
            cropped and scrollable within the modal.
          </p>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <br>
          <p>Just like that.</p>
        </ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Save changes
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
</template>

Tooltips and popovers

Tooltips and popovers can be placed within modals as needed. When modals are closed, any tooltips and popovers within are also automatically dismissed.

vue
<template>
  <!-- Button trigger modal -->
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModalPopovers"
  >
    Launch demo modal
  </b-button>
  <!-- Modal -->
  <Modal id="exampleModalPopovers">
    <ModalDialog>
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Modal title</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>
          <h5>Popover in a modal</h5>
          <p>
            This
            <b-button
              button="secondary"
              toggle="popover"
              title="Popover title"
              content="Popover body content is set in this attribute."
            >
              button
            </b-button>
            triggers a popover on click.
          </p>
          <hr>
          <h5>Tooltips in a modal</h5>
          <p>
            <b-a
              toggle="tooltip"
              title="Tooltip"
            >
              This link
            </b-a>
            and
            <b-a
              toggle="tooltip"
              title="Tooltip"
            >
              that link
            </b-a>
            have tooltips on hover.
          </p>
        </ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Save changes
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
</template>

Using the grid

Utilize the Bootstrap grid system within a modal by nesting Container component with fluid attribute within the ModalBody component. Then, use the normal grid system classes as you would anywhere else.

vue
<template>
  <!-- Button trigger modal -->
  <b-button
    button="primary"
    toggle="modal"
    target="#gridSystemModal"
  >
    Launch demo modal
  </b-button>
  <!-- Modal -->
  <Modal id="gridSystemModal">
    <ModalDialog>
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Grids in modals</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>
          <Container fluid>
            <Row>
              <Col col="md-4">
                .col-md-4
              </Col>
              <Col col="md-4 ms-auto">
                .col-md-4 .ms-auto
              </Col>
            </Row>
            <Row>
              <Col col="md-3 ms-auto">
                .col-md-3 .ms-auto
              </Col>
              <Col col="md-2 ms-auto">
                .col-md-2 .ms-auto
              </Col>
            </Row>
            <Row>
              <Col col="md-6 ms-auto">
                .col-md-6 .ms-auto
              </Col>
            </Row>
            <Row>
              <Col col="md-9">
                Level 1: .col-sm-9
              </Col>
              <Row>
                <Col col="col-8 col-sm-6">
                  Level 2: .col-8 .col-sm-6
                </Col>
                <Col col="col-4 col-sm-6">
                  Level 2: .col-4 .col-sm-6
                </Col>
              </Row>
            </Row>
          </Container>
        </ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Save changes
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
</template>

Varying modal content

Have a bunch of buttons that all trigger the same modal with slightly different contents? Use event.relatedTarget and HTML data-bs * attributes to vary the contents of the modal depending on which button was clicked.

vue
<template>
  <!-- Button trigger modal -->
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModalVary"
    whatever="@mdo"
  >
    Open modal for @mdo
  </b-button>
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModalVary"
    whatever="@fat"
  >
    Open modal for @fat
  </b-button>
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModalVary"
    whatever="@getbootstrap"
  >
    Open modal for @getbootstrap
  </b-button>
  <!-- Modal -->
  <Modal id="exampleModalVary">
    <ModalDialog>
      <ModalContent>
        <ModalHeader>
          <ModalTitle>New message</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>
          <BForm>
            <Row class="mb-3">
              <BColFormLabel for="recipient-name">
                Recipient:
              </BColFormLabel>
              <Col>
                <BFormInput
                  id="recipient-name"
                  type="text"
                />
              </Col>
            </Row>
            <b-div class="mb-3">
              <BFormLabel
                for="message-text"
                class="col-form-label"
              >
                Message:
              </BFormLabel>
              <BFormTextarea id="message-text" />
            </b-div>
          </BForm>
        </ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Save changes
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
</template>

Toggle between modals

Toggle between multiple modals with some clever placement of the data-bs-target and data-bs-toggle attributes.

For example, you could toggle a password reset modal from within an already open sign in modal. Please note multiple modals cannot be open at the same time—this method simply toggles between two separate modals.

vue
<template>
  <!-- Button trigger modal -->
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModalToggle"
  >
    Open first modal
  </b-button>
  <!-- Modal -->
  <Modal id="exampleModalToggle">
    <ModalDialog centered>
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Modal 1</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>
          Show a second modal and hide this one with the button below.
        </ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button
            button="primary"
            toggle="modal"
            target="#exampleModalToggle2"
          >
            Open second modal
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
  <!-- Modal -->
  <Modal id="exampleModalToggle2">
    <ModalDialog centered>
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Modal 2</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>
          Hide this modal and show the first with the button below.
        </ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button
            button="primary"
            toggle="modal"
            target="#exampleModalToggle1"
          >
            Back to first
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
</template>

Remove animation

For modals that simply appear rather than fade in to view, remove the .fade class from your modal markup.

Optional sizes

Modals have three optional sizes, available via modifier classes to be placed on a .modal-dialog.

These sizes kick in at certain breakpoints to avoid horizontal scrollbars on narrower viewports.

Our default modal without modifier class constitutes the "medium" size modal.

vue
<template>
  <!-- Button trigger modal -->
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModalXl"
  >
    Extra large modal
  </b-button>
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModalLg"
  >
    large modal
  </b-button>
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModalSm"
  >
    small modal
  </b-button>
  <!-- Modal -->
  <Modal id="exampleModalXl">
    <ModalDialog>
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Extra large modal</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>...</ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Save changes
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
  <Modal id="exampleModalLg">
    <ModalDialog>
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Large modal</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>...</ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Save changes
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
  <Modal id="exampleModalSm">
    <ModalDialog>
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Small modal</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>...</ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Save changes
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
</template>

Fullscreen Modal

Another override is the option to pop up a modal that covers the user viewport, available via modifier classes that are placed on a .modal-dialog.

ClassAvailability
.modal-fullscreenAlways
.modal-fullscreen-sm-down Below 576px
.modal-fullscreen-md-down Below 768px
.modal-fullscreen-lg-down Below 992px
.modal-fullscreen-xl-down Below 1200px
.modal-fullscreen-xxl-down Below 1400px
vue
<template>
  <!-- Button trigger modal -->
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModalFullscreen"
  >
    Full screen
  </b-button>
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModalFullscreenSm"
  >
    Full screen below sm
  </b-button>
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModalFullscreenMd"
  >
    Full screen below md
  </b-button>
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModalFullscreenLg"
  >
    Full screen below lg
  </b-button>
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModalFullscreenXl"
  >
    Full screen below xl
  </b-button>
  <b-button
    button="primary"
    toggle="modal"
    target="#exampleModalFullscreenXxl"
  >
    Full screen below xxl
  </b-button>
  <!-- Modal -->
  <Modal id="exampleModalFullscreen">
    <ModalDialog fullscreen>
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Modal title</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>...</ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Save changes
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
  <Modal id="exampleModalFullscreenSm">
    <ModalDialog fullscreen="sm-down">
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Full screen below down</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>...</ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Save changes
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
  <Modal id="exampleModalFullscreenMd">
    <ModalDialog fullscreen="md-down">
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Full screen below md</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>...</ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Save changes
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
  <Modal id="exampleModalFullscreenLg">
    <ModalDialog fullscreen="lg-down">
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Full screen below lg</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>...</ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Save changes
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
  <Modal id="exampleModalFullscreenXl">
    <ModalDialog fullscreen="xl-down">
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Full screen below xl</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>...</ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Save changes
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
  <Modal id="exampleModalFullscreenXxl">
    <ModalDialog fullscreen="xxl-down">
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Full screen below xl</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>...</ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Save changes
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
</template>

Methods

MethodDescription
toggle Manually switch the modal
show Manually open the modal
hide Manually hide the modal
dismiss Manually hide the modal

Demo

vue
<template>
  <!-- Button trigger modal -->
  <b-button
    button="primary"
    @click="clicked"
  >
    Launch demo modal
  </b-button>
  <!-- Modal -->
  <Modal ref="demoModal">
    <ModalDialog>
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Modal title</ModalTitle>
          <CloseButton dismiss="modal" />
        </ModalHeader>
        <ModalBody>...</ModalBody>
        <ModalFooter>
          <b-button
            button="secondary"
            dismiss="modal"
          >
            Close
          </b-button>
          <b-button button="primary">
            Save changes
          </b-button>
        </ModalFooter>
      </ModalContent>
    </ModalDialog>
  </Modal>
</template>
<script setup lang="ts">
import { delay } from 'lodash-es';

const demoModal = ref(null)

const clicked = () => {
  delay(() => {
    if (demoModal.value) {
      demoModal.value.show()
    }
  }, 3000)

}
</script>