先找到index.html(通常在public資料夾中),在body中多建立一個DOM元件。
// index.html
<body>
<div id="over-lay"></div>
<div id="root"></div>
</body>
先在Modal組件中,新增兩個組件。Modal會有兩層,一層是遮罩層,透明黑底的效果,另一層是Modal裡面的內容。
// Modal.js
import classes from "./Modal.module.css"
const BackDrop = ()=>{
return <div className={classes.backdrop}></div>
}
const ModalOverLay = props => {
return (
<div className={classes.modal}>
<div className={classes.content}>{props.childern}</div>
</div>
)
}
要把這兩個組件放到我們剛剛建立好的DOM節點上面,因此這邊要使用ReactDOM,ReactDOM提供我們一個可以在項目最頂層使用的方式,詳細可以參考官網解說。
createPortal(child, container)
createPortal會帶兩個參數,child是要放上去dom的組件,container是DOM節點。
import { Fragment } from "react"
import ReactDom from "react-dom"
import classes from "./Modal.module.css"
const BackDrop = ()=>{
return <div className={classes.backdrop}></div>
}
const ModalOverLay = props => {
return (
<div className={classes.modal}>
<div className={classes.content}>{props.children}</div>
</div>
)
}
const portalElement = document.getElementById("over-lay")
const Modal = props=>{
return <Fragment>
{ReactDom.createPortal(<BackDrop/>,portalElement)}
{ReactDom.createPortal(<ModalOverLay>{props.children}</ModalOverLay>,portalElement)}
</Fragment>
}
export default Modal
這樣我們就可以使用Modal組件了!
附上CSS module
.backdrop {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
z-index: 20;
background-color: rgba(0, 0, 0, 0.75);
}
.modal {
position: fixed;
top: 20vh;
left: 5%;
width: 90%;
background-color: white;
padding: 1rem;
border-radius: 14px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
z-index: 30;
animation: slide-down 300ms ease-out forwards;
}
@media (min-width: 768px) {
.modal {
width: 40rem;
left: calc(50% - 20rem);
}
}
@keyframes slide-down {
from {
opacity: 0;
transform: translateY(-3rem);
}
to {
opacity: 1;
transform: translateY(0);
}
}