React Modal Window
In the App.jsx
file:
const [modalVisible, setModalVisible] = useState(false);
const toggleModal = () => {
modalVisible ? setModalVisible(false) : setModalVisible(true);
document.querySelector('body').classList.toggle('modal-open');
}
const toggleModalViaBgClick = (event) => {
// This could be DRYed:
// In order to still be able to use the controls in the modal window
// we cannot just call toggleModal
// b/c we need to be specific about what the event.target is
// NOTE THAT clicking on the left or right edge of the modal
// doesn't trigger this b/c the event.target is the modal content
// and not `div.modal` if the width of modal content is set as follows (via hard-coding `80%`)
// HOWEVER, if the modal content is centered via flexbox,
// clicking on the left or right will register a click event on the `.modal` element
// and will close the modal window
if (event.target.className === 'modal visible') {
modalVisible ? setModalVisible(false) : setModalVisible(true);
document.querySelector('body').classList.toggle('modal-open');
}
}
My Modal
Spam and eggs...
In a CSS file:
/* prevent body from scrolling when modal window is open */
body.modal-open {
height: 100vh;
overflow: hidden;
}
.modal {
display: none;
&.visible {
background: rgba(0, 0, 0, 0.4);
display: block;
height: 100%;
left: 0;
overflow: auto;
position: fixed;
top: 0;
width: 100%;
z-index: 100; /* or some value higher than any other z-index applied */
.modal-header {
align-items: center;
display: flex;
justify-content: space-between;
margin-bottom: 1rem;
button {
background: transparent;
border: 0 none transparent;
color: black;
font-size: 2rem;
line-height: 2rem;
outline: none;
padding: 0;
}
h2 {
margin-bottom: 0;
}
}
.modal-content {
background: white;
margin: 15% auto; /* set to `0 auto` to position to the top edge of the page */
padding: 2rem;
width: 80%; /* set to `100%` to go edge-to-edge left-to-right */
}
}
}
Centering the Modal Window Vertically
Flexbox
On .modal
, change display: block
to display: flex
and set it to align-items: center
to center vertically on the page and justify-content: center
to center horizontally on the page. Remove the width of 80%
from .modal-content
and set the top and bottom margin to 0
instead of 15%
.
This works, unless the modal content is bigger than the container in which case it overflows from the center of the window and gets clipped. This happens both vertically and horizontally.
If max-width: 100%;
and max-height: 100%;
are added to .modal-dialog
, the centering is applied but if the window gets to be smaller than the content, it clips from the top left corner rather than the center which is a bit more expected.
Feedback?
Email us at enquiries@kinsa.cc.