React Modal Component

React Modal component offers a lightweight, multi-purpose popup to add dialogs to yours. Learn how to customize React CoreUI 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 dismiss actions whenever possible, or provide another explicit dismiss action.

1<CModal
2 className="show d-block position-static"
3 backdrop={false}
4 keyboard={false}
5 portal={false}
6 visible
7>
8 <CModalHeader>
9 <CModalTitle>Modal title</CModalTitle>
10 </CModalHeader>
11 <CModalBody>Modal body text goes here.</CModalBody>
12 <CModalFooter>
13 <CButton color="secondary">Close</CButton>
14 <CButton color="primary">Save changes</CButton>
15 </CModalFooter>
16</CModal>

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.

1const [visible, setVisible] = useState(false)
2return (
3 <>
4 <CButton onClick={() => setVisible(!visible)}>Launch demo modal</CButton>
5 <CModal visible={visible} onClose={() => setVisible(false)}>
6 <CModalHeader onClose={() => setVisible(false)}>
7 <CModalTitle>Modal title</CModalTitle>
8 </CModalHeader>
9 <CModalBody>Woohoo, you're reading this text in a modal!</CModalBody>
10 <CModalFooter>
11 <CButton color="secondary" onClick={() => setVisible(false)}>
12 Close
13 </CButton>
14 <CButton color="primary">Save changes</CButton>
15 </CModalFooter>
16 </CModal>
17 </>
18)

Static backdrop#

If you set a backdrop 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.

1const [visible, setVisible] = useState(false)
2return (
3 <>
4 <CButton onClick={() => setVisible(!visible)}>Launch static backdrop modal</CButton>
5 <CModal visible={visible} onClose={() => setVisible(false)}>
6 <CModalHeader>
7 <CModalTitle>Modal title</CModalTitle>
8 </CModalHeader>
9 <CModalBody>
10 I will not close if you click outside me. Don't even try to press escape key.
11 </CModalBody>
12 <CModalFooter>
13 <CButton color="secondary" onClick={() => setVisible(false)}>
14 Close
15 </CButton>
16 <CButton color="primary">Save changes</CButton>
17 </CModalFooter>
18 </CModal>
19 </>
20)

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.

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

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

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

Vertically centered#

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

1const [visible, setVisible] = useState(false)
2return (
3 <>
4 <CButton onClick={() => setVisible(!visible)}>Vertically centered modal</CButton>
5 <CModal alignment="center" visible={visible} onClose={() => setVisible(false)}>
6 <CModalHeader>
7 <CModalTitle>Modal title</CModalTitle>
8 </CModalHeader>
9 <CModalBody>
10 Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,
11 egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
12 </CModalBody>
13 <CModalFooter>
14 <CButton color="secondary" onClick={() => setVisible(false)}>
15 Close
16 </CButton>
17 <CButton color="primary">Save changes</CButton>
18 </CModalFooter>
19 </CModal>
20 </>
21)
1const [visible, setVisible] = useState(false)
2return (
3 <>
4 <CButton onClick={() => setVisible(!visible)}>Vertically centered scrollable modal</CButton>
5 <CModal alignment="center" scrollable visible={visible} onClose={() => setVisible(false)}>
6 <CModalHeader>
7 <CModalTitle>Modal title</CModalTitle>
8 </CModalHeader>
9 <CModalBody>
10 <p>
11 Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis
12 in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
13 </p>
14 <p>
15 Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus
16 vel augue laoreet rutrum faucibus dolor auctor.
17 </p>
18 <p>
19 Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel
20 scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus
21 auctor fringilla.
22 </p>
23 <p>
24 Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis
25 in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
26 </p>
27 <p>
28 Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus
29 vel augue laoreet rutrum faucibus dolor auctor.
30 </p>
31 </CModalBody>
32 <CModalFooter>
33 <CButton color="secondary" onClick={() => setVisible(false)}>
34 Close
35 </CButton>
36 <CButton color="primary">Save changes</CButton>
37 </CModalFooter>
38 </CModal>
39 </>
40)

Tooltips and popovers#

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

1const [visible, setVisible] = useState(false)
2return (
3 <>
4 <CButton onClick={() => setVisible(!visible)}>Launch demo modal</CButton>
5 <CModal alignment="center" visible={visible} onClose={() => setVisible(false)}>
6 <CModalHeader>
7 <CModalTitle>Modal title</CModalTitle>
8 </CModalHeader>
9 <CModalBody>
10 <h5>Popover in a modal</h5>
11 <p>
12 This
13 <CPopover title="Popover title" content="Popover body content is set in this property.">
14 <CButton>button</CButton>
15 </CPopover> triggers a popover on click.
16 </p>
17 <hr />
18 <h5>Tooltips in a modal</h5>
19 <p>
20 <CTooltip content="Tooltip">
21 <CLink>This link</CLink>
22 </CTooltip>{' '}
23 and
24 <CTooltip content="Tooltip">
25 <CLink>that link</CLink>
26 </CTooltip> have tooltips on hover.
27 </p>
28 </CModalBody>
29 <CModalFooter>
30 <CButton color="secondary" onClick={() => setVisible(false)}>
31 Close
32 </CButton>
33 <CButton color="primary">Save changes</CButton>
34 </CModalFooter>
35 </CModal>
36 </>
37)

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
1const [visibleXL, setVisibleXL] = useState(false)
2const [visibleLg, setVisibleLg] = useState(false)
3const [visibleSm, setVisibleSm] = useState(false)
4return (
5 <>
6 <CButton onClick={() => setVisibleXL(!visibleXL)}>Extra large modal</CButton>
7 <CButton onClick={() => setVisibleLg(!visibleLg)}>Large modal</CButton>
8 <CButton onClick={() => setVisibleSm(!visibleSm)}>Small modal</CButton>
9 <CModal size="xl" visible={visibleXL} onClose={() => setVisibleXL(false)}>
10 <CModalHeader>
11 <CModalTitle>Extra large modal</CModalTitle>
12 </CModalHeader>
13 <CModalBody>...</CModalBody>
14 </CModal>
15 <CModal size="lg" visible={visibleLg} onClose={() => setVisibleLg(false)}>
16 <CModalHeader>
17 <CModalTitle>Large modal</CModalTitle>
18 </CModalHeader>
19 <CModalBody>...</CModalBody>
20 </CModal>
21 <CModal size="sm" visible={visibleSm} onClose={() => setVisibleSm(false)}>
22 <CModalHeader>
23 <CModalTitle>Small modal</CModalTitle>
24 </CModalHeader>
25 <CModalBody>...</CModalBody>
26 </CModal>
27 </>
28)

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
1const [visible, setVisible] = useState(false)
2const [visibleSm, setVisibleSm] = useState(false)
3const [visibleMd, setVisibMdSm] = useState(false)
4const [visibleLg, setVisibleLg] = useState(false)
5const [visibleXL, setVisibleXL] = useState(false)
6const [visibleXXL, setVisibleXXL] = useState(false)
7return (
8 <>
9 <CButton onClick={() => setVisible(!visible)}>Full screen</CButton>
10 <CButton onClick={() => setVisibleSm(!visibleSm)}>Full screen below sm</CButton>
11 <CButton onClick={() => setVisibleMd(!visibleMd)}>Full screen below md</CButton>
12 <CButton onClick={() => setVisibleLg(!visibleLg)}>Full screen below lg</CButton>
13 <CButton onClick={() => setVisibleXL(!visibleXL)}>Full screen below xl</CButton>
14 <CButton onClick={() => setVisibleXXL(!visibleXXL)}>Full screen below xxl</CButton>
15 <CModal fullscreen visible={visible} onClose={() => setVisible(false)}>
16 <CModalHeader>
17 <CModalTitle>Full screen</CModalTitle>
18 </CModalHeader>
19 <CModalBody>...</CModalBody>
20 </CModal>
21 <CModal fullscreen="sm" visible={visibleSm} onClose={() => setVisibleSm(false)}>
22 <CModalHeader>
23 <CModalTitle>Full screen below sm</CModalTitle>
24 </CModalHeader>
25 <CModalBody>...</CModalBody>
26 </CModal>
27 <CModal fullscreen="md" visible={visibleMd} onClose={() => setVisibleMd(false)}>
28 <CModalHeader>
29 <CModalTitle>Full screen below md</CModalTitle>
30 </CModalHeader>
31 <CModalBody>...</CModalBody>
32 </CModal>
33 <CModal fullscreen="lg" visible={visibleLg} onClose={() => setVisibleLg(false)}>
34 <CModalHeader>
35 <CModalTitle>Full screen below lg</CModalTitle>
36 </CModalHeader>
37 <CModalBody>...</CModalBody>
38 </CModal>
39 <CModal fullscreen="xl" visible={visibleXL} onClose={() => setVisibleXL(false)}>
40 <CModalHeader>
41 <CModalTitle>Full screen below xl</CModalTitle>
42 </CModalHeader>
43 <CModalBody>...</CModalBody>
44 </CModal>
45 <CModal fullscreen="xxl" visible={visibleXXL} onClose={() => setVisibleXXL(false)}>
46 <CModalHeader>
47 <CModalTitle>Full screen below xxl</CModalTitle>
48 </CModalHeader>
49 <CModalBody>...</CModalBody>
50 </CModal>
51 </>
52)

API#

CModal#

1import { CModal } from '@coreui/react'
2// or
3import CModal from '@coreui/react/src/components/modal/CModal'
PropertyDescriptionTypeDefault
alignmentAlign the modal in the center or top of the screen.'top' | 'center'-
backdropApply a backdrop on body while modal is open.boolean | 'static'true
classNameA string of all className you want applied to the base component.string-
fullscreenSet modal to covers the entire user viewport.boolean | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'-
keyboardCloses the modal when escape key is pressed.booleantrue
onCloseCallback fired when the component requests to be closed.() => void-
onClosePreventedCallback fired when the component requests to be closed.() => void-
onShowCallback 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.() => void-
portalGenerates modal using createPortal.booleantrue
scrollableCreate a scrollable modal that allows scrolling the modal body.boolean-
sizeSize the component small, large, or extra large.'sm' | 'lg' | 'xl'-
transitionRemove animation to create modal that simply appear rather than fade in to view.booleantrue
visibleToggle the visibility of modal component.boolean-

CModalBody#

1import { CModalBody } from '@coreui/react'
2// or
3import CModalBody from '@coreui/react/src/components/modal/CModalBody'
PropertyDescriptionTypeDefault
classNameA string of all className you want applied to the base component.string-

CModalFooter#

1import { CModalFooter } from '@coreui/react'
2// or
3import CModalFooter from '@coreui/react/src/components/modal/CModalFooter'
PropertyDescriptionTypeDefault
classNameA string of all className you want applied to the base component.string-

CModalHeader#

1import { CModalHeader } from '@coreui/react'
2// or
3import CModalHeader from '@coreui/react/src/components/modal/CModalHeader'
PropertyDescriptionTypeDefault
classNameA string of all className you want applied to the base component.string-
closeButtonAdd a close button component to the header.booleantrue

CModalTitle#

1import { CModalTitle } from '@coreui/react'
2// or
3import CModalTitle from '@coreui/react/src/components/modal/CModalTitle'
PropertyDescriptionTypeDefault
classNameA string of all className you want applied to the base component.string-
componentComponent used for the root node. Either a string to use a HTML element or a component.string | ComponentClass<any, any> | FunctionComponent<any>-