如何让React Modal基于指定div而非窗口实现垂直水平居中?
Hey there! I’ve dealt with this exact issue with react-modal before, so I totally get the frustration when setAppElement('#canvas') doesn’t shift the centering to your workspace. Let’s walk through why that happens and how to fix it easily.
Why setAppElement Isn’t Changing Centering
First, a quick clarification: setAppElement is primarily for accessibility purposes (it tells screen readers which element is "hidden" when the modal opens), not for modifying the modal’s positioning context. React-modal’s default centering is hardcoded to the viewport (window), so we need to override its styles to make it center relative to #canvas.
Step-by-Step Solution
1. Override React-Modal’s Default Styles
We need to disable the viewport-based centering and set up flexbox centering relative to the parent container. Pass a custom style prop to your Modal component:
<Modal isOpen={modalIsOpen} onRequestClose={closeModal} // Keep this for accessibility! appElement="#canvas" style={{ overlay: { // Make overlay relative to #canvas instead of viewport position: 'relative', backgroundColor: 'rgba(0, 0, 0, 0.75)', // Use flexbox to center content inside the overlay display: 'flex', justifyContent: 'center', alignItems: 'center', // Reset default viewport positioning values top: 'unset', left: 'unset', right: 'unset', bottom: 'unset', padding: 0, margin: 0, // Match #canvas's dimensions if needed width: '100%', height: '100%', }, content: { // Disable viewport-based centering position: 'relative', top: 'unset', left: 'unset', right: 'unset', bottom: 'unset', transform: 'none', // Reset default margins margin: 0, // Add your own padding/styling padding: '2rem', borderRadius: '8px', backgroundColor: '#fff', }, }} > {/* Your modal content goes here */} <h2>Centered in #canvas!</h2> <button onClick={closeModal}>Close Modal</button> </Modal>
2. Ensure #canvas Has the Right Positioning
For the overlay to center relative to #canvas, the container needs to be a positioning context. Add this to your CSS:
#canvas { position: relative; /* Adjust these values to account for your top/left menus */ width: calc(100vw - 250px); /* Example: 250px left menu width */ height: calc(100vh - 80px); /* Example: 80px top menu height */ overflow: auto; /* Keep this if your workspace needs scrolling */ }
3. Place the Modal Inside #canvas
This is critical! The Modal component needs to be a direct (or nested) child of #canvas so its overlay inherits the container’s positioning context:
<div id="canvas"> {/* Your workspace/canvas content here */} <button onClick={openModal}>Open Modal</button> {/* Modal lives inside #canvas */} <Modal isOpen={modalIsOpen} onRequestClose={closeModal} appElement="#canvas" style={/* Custom styles from step 1 */} > {/* Modal content */} </Modal> </div>
Quick Notes
- Keep
appElement="#canvas"enabled—it’s essential for screen reader users to understand that the rest of the page is inactive when the modal is open. - If your
#canvashas scrollable content, this setup will keep the modal centered in the visible area of the workspace, even when scrolling.
内容的提问来源于stack exchange,提问作者Brainmaniac

