Bootstrap Vue Modal Component

Bootstrap Vue Modal component offers a lightweight, multi-purpose popup to add dialogs to yours. Learn how to customize Bootstrap Vue Modals easily. Multiple examples and tutorial.

Examples

Below is a static modal example (meaning its position and display have been overridden). Included are the modal header, modal body (required for padding), and modal footer (optional). We ask that you include modal headers with actions whenever possible, or provide another explicit action.

<CModal class="show d-block position-static" :backdrop="false" :keyboard="false" visible>
  <CModalHeader>
    <CModalTitle>Modal title</CModalTitle>
  </CModalHeader>
  <CModalBody>Modal body text goes here.</CModalBody>
  <CModalFooter>
    <CButton color="secondary">Close</CButton>
    <CButton color="primary">Save changes</CButton>
  </CModalFooter>
</CModal>
1
2
3
4
5
6
7
8
9
10

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.

<template>
  <CButton color="primary" @click="() => { visibleLiveDemo = true }">Launch demo modal</CButton>
  <CModal :visible="visibleLiveDemo" @close="() => { visibleLiveDemo = false }">
    <CModalHeader>
      <CModalTitle>Modal title</CModalTitle>
    </CModalHeader>
    <CModalBody>Woohoo, you're reading this text in a modal!</CModalBody>
    <CModalFooter>
      <CButton color="secondary" @click="() => { visibleLiveDemo = false }">
        Close
      </CButton>
      <CButton color="primary">Save changes</CButton>
    </CModalFooter>
  </CModal>
</template>
<script>
  export default {
    data() {
      return { 
        visibleLiveDemo: false,
      }
    }
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

Static backdrop

If you set backdrop property to static, your modal will behave as though the backdrop is static, meaning it will not close when clicking outside it. Click the button below to try it.

<template>
  <CButton color="primary" @click="() => { visibleStaticBackdropDemo = true }">Launch demo modal</CButton>
  <CModal backdrop="static" :visible="visibleStaticBackdropDemo" @close="() => { visibleStaticBackdropDemo = false }">
    <CModalHeader>
      <CModalTitle>Modal title</CModalTitle>
    </CModalHeader>
    <CModalBody>Woohoo, you're reading this text in a modal!</CModalBody>
    <CModalFooter>
      <CButton color="secondary" @click="() => { visibleStaticBackdropDemo = false }">
        Close
      </CButton>
      <CButton color="primary">Save changes</CButton>
    </CModalFooter>
  </CModal>
</template>
<script>
  export default {
    data() {
      return { 
        visibleStaticBackdropDemo: false,
      }
    }
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

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.

<template>
  <CButton color="primary" @click="() => { visibleScrollingLongContentDemo = true }">Launch demo modal</CButton>
  <CModal :visible="visibleScrollingLongContentDemo" @close="() => { visibleScrollingLongContentDemo = false }">
    <CModalHeader>
      <CModalTitle>Modal title</CModalTitle>
    </CModalHeader>
    <CModalBody>
      <p>
        Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac
        facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum
        at eros.
      </p>
      <p>
        Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis
        lacus vel augue laoreet rutrum faucibus dolor auctor.
      </p>
      <p>
        Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel
        scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus
        auctor fringilla.
      </p>
      <p>
        Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac
        facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum
        at eros.
      </p>
      <p>
        Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis
        lacus vel augue laoreet rutrum faucibus dolor auctor.
      </p>
      <p>
        Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel
        scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus
        auctor fringilla.
      </p>
      <p>
        Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac
        facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum
        at eros.
      </p>
      <p>
        Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis
        lacus vel augue laoreet rutrum faucibus dolor auctor.
      </p>
      <p>
        Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel
        scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus
        auctor fringilla.
      </p>
      <p>
        Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac
        facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum
        at eros.
      </p>
      <p>
        Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis
        lacus vel augue laoreet rutrum faucibus dolor auctor.
      </p>
      <p>
        Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel
        scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus
        auctor fringilla.
      </p>
      <p>
        Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac
        facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum
        at eros.
      </p>
      <p>
        Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis
        lacus vel augue laoreet rutrum faucibus dolor auctor.
      </p>
      <p>
        Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel
        scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus
        auctor fringilla.
      </p>
      <p>
        Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac
        facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum
        at eros.
      </p>
      <p>
        Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis
        lacus vel augue laoreet rutrum faucibus dolor auctor.
      </p>
      <p>
        Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel
        scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus
        auctor fringilla.
      </p>
    </CModalBody>
  </CModal>
</template>
<script>
  export default {
    data() {
      return { 
        visibleScrollingLongContentDemo: false,
      }
    }
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

You can also create a scrollable modal that allows scroll the modal body by adding scrollable prop.

<template>
  <CButton color="primary" @click="() => { visibleScrollableDemo = true }">Launch demo modal</CButton>
  <CModal scrollable :visible="visibleScrollableDemo" @close="() => { visibleScrollableDemo = false }">
    <CModalHeader>
      <CModalTitle>Modal title</CModalTitle>
    </CModalHeader>
    <CModalBody>
      <p>
        Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac
        facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum
        at eros.
      </p>
      <p>
        Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis
        lacus vel augue laoreet rutrum faucibus dolor auctor.
      </p>
      <p>
        Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel
        scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus
        auctor fringilla.
      </p>
      <p>
        Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac
        facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum
        at eros.
      </p>
      <p>
        Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis
        lacus vel augue laoreet rutrum faucibus dolor auctor.
      </p>
      <p>
        Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel
        scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus
        auctor fringilla.
      </p>
      <p>
        Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac
        facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum
        at eros.
      </p>
      <p>
        Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis
        lacus vel augue laoreet rutrum faucibus dolor auctor.
      </p>
      <p>
        Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel
        scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus
        auctor fringilla.
      </p>
      <p>
        Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac
        facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum
        at eros.
      </p>
      <p>
        Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis
        lacus vel augue laoreet rutrum faucibus dolor auctor.
      </p>
      <p>
        Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel
        scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus
        auctor fringilla.
      </p>
      <p>
        Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac
        facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum
        at eros.
      </p>
      <p>
        Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis
        lacus vel augue laoreet rutrum faucibus dolor auctor.
      </p>
      <p>
        Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel
        scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus
        auctor fringilla.
      </p>
      <p>
        Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac
        facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum
        at eros.
      </p>
      <p>
        Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis
        lacus vel augue laoreet rutrum faucibus dolor auctor.
      </p>
      <p>
        Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel
        scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus
        auctor fringilla.
      </p>
    </CModalBody>
  </CModal>
</template>
<script>
  export default {
    data() {
      return { 
        visibleScrollableDemo: false,
      }
    }
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

Vertically centered

Add alignment="center to <CModal> to vertically center the modal.

<template>
  <CButton color="primary" @click="() => { visibleVerticallyCenteredDemo = true }">Launch demo modal</CButton>
  <CModal alignment="center" :visible="visibleVerticallyCenteredDemo" @close="() => { visibleVerticallyCenteredDemo = false }">
    <CModalHeader>
      <CModalTitle>Modal title</CModalTitle>
    </CModalHeader>
    <CModalBody>
      Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
    </CModalBody>
    <CModalFooter>
      <CButton color="secondary" @click="() => { visibleVerticallyCenteredDemo = false }">
        Close
      </CButton>
      <CButton color="primary">Save changes</CButton>
    </CModalFooter>
  </CModal>
</template>
<script>
  export default {
    data() {
      return { 
        visibleVerticallyCenteredDemo: false,
      }
    }
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<template>
  <CButton color="primary" @click="() => { visibleVerticallyCenteredScrollableDemo = true }">Vertically centered scrollable modal</CButton>
  <CModal alignment="center" scrollable :visible="visibleVerticallyCenteredScrollableDemo" @close="() => { visibleVerticallyCenteredScrollableDemo = false }">
    <CModalHeader>
      <CModalTitle>Modal title</CModalTitle>
    </CModalHeader>
    <CModalBody>
      Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
    </CModalBody>
    <CModalFooter>
      <CButton color="secondary" @click="() => { visibleVerticallyCenteredScrollableDemo = false }">
        Close
      </CButton>
      <CButton color="primary">Save changes</CButton>
    </CModalFooter>
  </CModal>
</template>
<script>
  export default {
    data() {
      return { 
        visibleVerticallyCenteredScrollableDemo: false,
      }
    }
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

Tooltips and popovers

<CTooltips> and <CPopovers> can be placed within modals as needed. When modals are closed, any tooltips and popovers within are also automaticallyed.

<template>
  <CButton color="primary" @click="() => { tooltipsAndPopoversDemo = true }">Launch demo modal</CButton>
  <CModal :visible="tooltipsAndPopoversDemo" @close="() => { tooltipsAndPopoversDemo = false }">
    <CModalHeader>
      <CModalTitle>Modal title</CModalTitle>
    </CModalHeader>
    <CModalBody>
      <h5>Popover in a modal</h5>
      <p>This <CButton color="secondary" v-c-popover="{header: 'Popover title', content: 'Popover body content is set in this property.'}">button</CButton></p>
      <hr/>
      <h5>Tooltips in a modal</h5>
      <p>
        <CLink v-c-tooltip="'Tooltip'">This link</CLink> and <CLink v-c-tooltip="'Tooltip'">that link</CLink> have tooltips on hover.
      </p>
    </CModalBody>
    <CModalFooter>
      <CButton color="secondary" @click="() => { tooltipsAndPopoversDemo = false }">
        Close
      </CButton>
      <CButton color="primary">Save changes</CButton>
    </CModalFooter>
  </CModal>
</template>
<script>
  export default {
    data() {
      return { 
        tooltipsAndPopoversDemo: false,
      }
    }
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

Optional sizes

Modals have three optional sizes, available via modifier classes to be placed on a <CModal>. These sizes kick in at certain breakpoints to avoid horizontal scrollbars on narrower viewports.

SizeProperty sizeModal max-width
Small'sm'300px
DefaultNone500px
Large'lg'800px
Extra large'xl'1140px
<template>
  <CButton color="primary" @click="() => { xlDemo = true }">Extra large modal</CButton>
  <CButton color="primary" @click="() => { lgDemo = true }">Large modal</CButton>
  <CButton color="primary" @click="() => { smDemo = true }">Small modal</CButton>
  <CModal size="xl" :visible="xlDemo" @close="() => { xlDemo = false }">
    <CModalHeader>
      <CModalTitle>Extra large modal</CModalTitle>
    </CModalHeader>
    <CModalBody>
      ...
    </CModalBody>
  </CModal>
  <CModal size="lg" :visible="lgDemo" @close="() => { lgDemo = false }">
    <CModalHeader>
      <CModalTitle>Large modal</CModalTitle>
    </CModalHeader>
    <CModalBody>
      ...
    </CModalBody>
  </CModal>
  <CModal size="sm" :visible="smDemo" @close="() => { smDemo = false }">
    <CModalHeader>
      <CModalTitle>Small modal</CModalTitle>
    </CModalHeader>
    <CModalBody>
      ...
    </CModalBody>
  </CModal>
</template>
<script>
  export default {
    data() {
      return { 
        xlDemo: false,
        lgDemo: false,
        smDemo: false,
      }
    }
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

Fullscreen Modal

Another override is the option to pop up a modal that covers the user viewport, available via property fullscrean.

Property fullscreanAvailability
trueAlways
'sm'Below 576px
'md'Below 768px
'lg'Below 992px
'xl'Below 1200px
'xxl'Below 1400px
<template>
  <CButton color="primary" @click="() => { fullscreenDemo = true }">Full screen</CButton>
  <CButton color="primary" @click="() => { fullscreenSmDemo = true }">Full screen below sm</CButton>
  <CButton color="primary" @click="() => { fullscreenMdDemo = true }">Full screen below md</CButton>
  <CButton color="primary" @click="() => { fullscreenLgDemo = true }">Full screen below lg</CButton>
  <CButton color="primary" @click="() => { fullscreenXlDemo = true }">Full screen below xl</CButton>
  <CButton color="primary" @click="() => { fullscreenXxlDemo = true }">Full screen below xxl</CButton>
  <CModal fullscreen :visible="fullscreenDemo" @close="() => { fullscreenDemo = false }">
    <CModalHeader>
      <CModalTitle>Full screen</CModalTitle>
    </CModalHeader>
    <CModalBody>
      ...
    </CModalBody>
  </CModal>
  <CModal fullscreen="sm" :visible="fullscreenSmDemo" @close="() => { fullscreenSmDemo = false }">
    <CModalHeader>
      <CModalTitle>Full screen below sm</CModalTitle>
    </CModalHeader>
    <CModalBody>
      ...
    </CModalBody>
  </CModal>
  <CModal fullscreen="md" :visible="fullscreenMdDemo" @close="() => { fullscreenMdDemo = false }">
    <CModalHeader>
      <CModalTitle>Full screen below md</CModalTitle>
    </CModalHeader>
    <CModalBody>
      ...
    </CModalBody>
  </CModal>
  <CModal fullscreen="lg" :visible="fullscreenLgDemo" @close="() => { fullscreenLgDemo = false }">
    <CModalHeader>
      <CModalTitle>Full screen below lg</CModalTitle>
    </CModalHeader>
    <CModalBody>
      ...
    </CModalBody>
  </CModal>
  <CModal fullscreen="xl" :visible="fullscreenXlDemo" @close="() => { fullscreenXlDemo = false }">
    <CModalHeader>
      <CModalTitle>Full screen below xl</CModalTitle>
    </CModalHeader>
    <CModalBody>
      ...
    </CModalBody>
  </CModal>
  <CModal fullscreen="xxl" :visible="fullscreenXxlDemo" @close="() => { fullscreenXxlDemo = false }">
    <CModalHeader>
      <CModalTitle>Full screen below xxl</CModalTitle>
    </CModalHeader>
    <CModalBody>
      ...
    </CModalBody>
  </CModal>
</template>
<script>
  export default {
    data() {
      return { 
        fullscreenDemo: false,
        fullscreenSmDemo: false,
        fullscreenMdDemo: false,
        fullscreenLgDemo: false,
        fullscreenXlDemo: false,
        fullscreenXxlDemo: false,
      }
    }
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

API

CModal

import { CModal } from '@coreui/bootstrap-vue'
// or
import CModal from '@coreui/bootstrap-vue/src/components/modal/CModal'
1
2
3

Props

Prop nameDescriptionTypeValuesDefault
alignmentAlign the modal in the center or top of the screen.string'top', 'center''top'
backdropApply a backdrop on body while offcanvas is open.boolean|string'static'true
content-class-nameA string of all className you want applied to the modal content component.string--
fullscreenSet modal to covers the entire user viewportboolean|stringboolean, 'sm', 'md', 'lg', 'xl', 'xxl'-
keyboardCloses the modal when escape key is pressed.boolean-true
scrollableCreate a scrollable modal that allows scrolling the modal body.boolean-
sizeSize the component small, large, or extra large.string'sm', 'lg', 'xl'-
transitionRemove animation to create modal that simply appear rather than fade in to view.boolean-true
unmount-on-closeBy default the component is unmounted after close animation, if you want to keep the component mounted set this property to false.boolean-true
visibleToggle the visibility of alert component.boolean-

Events

Event nameDescriptionProperties
closeCallback fired when the component requests to be closed.
close-preventedCallback fired when the component requests to be closed.
showCallback fired when the modal is shown, its backdrop is static and a click outside the modal or an escape key press is performed with the keyboard option set to false.

CModalHeader

import { CModalHeader } from '@coreui/bootstrap-vue'
// or
import CModalHeader from '@coreui/bootstrap-vue/src/components/modal/CModalHeader'
1
2
3

Props

Prop nameDescriptionTypeValuesDefault
close-buttonAdd a close button component to the header.boolean-true

CModalTitle

import { CModalTitle } from '@coreui/bootstrap-vue'
// or
import CModalTitle from '@coreui/bootstrap-vue/src/components/modal/CModalTitle'
1
2
3

Props

Prop nameDescriptionTypeValuesDefault
componentComponent used for the root node. Either a string to use a HTML element or a component.string-'h5'