reactjs - Δεν ήταν δυνατή η εφαρμογή CSS στο περιεχόμενο του React portal
Προσπαθώ να χρησιμοποιήσω το React portal για να εμφανίσω ένα portal, οπότε δημιούργησα δύο div. Ένα για το υπόβαθρο και ένα για το πραγματικό portal μέσα στο αρχείο index.html.
<div id="backdrop-root"></div>
<div id="overlay-root"></div>
<div id="root"></div>
Ο κωδικός μου για το Πορτάλ:
const Backdrop = () => {
return <div className="backdrop" />;
};
const ModalOverlay = () => {
return (
<div css={NewTransactionPortalStyles} className="modal">
<Card>
<div className="modal-header">
<div>Create Transaction</div>
<div>
<XLg size={23} />
</div>
</div>
<div className="grid-styles">
<div> This is my Portal </div>
</div>
</Card>
</div>
);
};
export const NewTransactionPortal = () => {
return (
<div css={NewTransactionPortalStyles}>
{ReactDOM.createPortal(
<Backdrop />,
document.getElementById("backdrop-root")!
)}
{ReactDOM.createPortal(
<ModalOverlay transaction={[]} />,
document.getElementById("overlay-root")!
)}
</div>
);
Περιεχόμενο CSS:
export const NewTransactionPortalStyles = css`
.backdrop {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
z-index: 10;
background: rgba(0, 0, 0, 0.75);
}
.modal {
position: fixed;
top: 30vh;
left: 10%;
width: 60%;
height: 50%
z-index: 100;
overflow: hidden;
}
Δεν ξέρω τι λείπει αλλά η κλάση CSS μου δεν εφαρμόζεται στο portal μου, μπορώ να δω ότι μπορώ να στοχεύσω το div αλλά δεν μπορώ να εφαρμόσω CSS σε αυτό, οπότε ως αποτέλεσμα δεν μπορώ να πετύχω το απαιτούμενο αποτέλεσμα. Χρησιμοποιώ τη βιβλιοθήκη emotion για το CSS μου εδώ.
Απάντηση #1
Συνάντησα ένα παρόμοιο πρόβλημα με το έργο μου. Δυστυχώς, το μεγαλύτερο μέρος του CSS μου ήταν παγκόσμιο και περιλαμβανόταν στο αρχείο JS αντί να ανατίθεται σε επίπεδο component. Αυτό που κατέληξα να κάνω ήταν απλώς να ορίσω το innerHTML της ετικέτας head στο παράθυρο στο αυτό που χρησιμοποιούσα για το κύριο παράθυρο:
const NewWindow = ({ children }) => {
const newWindow = React.useMemo(() => window.open('', 'New Window'), [children]);
newWindow.document.head.innerHTML = window.document.head.innerHTML;
return ReactDOM.createPortal(children, newWindow.document.body);
};
Μπορεί ή μπορεί και να μην ισχύει για τη δική σας περίπτωση χρήσης.
Απάντηση #2
Όταν χρησιμοποιείτε το React Portal, το περιεχόμενο του portal βρίσκεται στην πραγματικότητα σε διαφορετική θέση DOM από ό,τι μπορεί να συμπεράνει κανείς από το δέντρο των React components: το περιεχόμενο του portal τοποθετείται ως απόγονος του καθορισμένου στοιχείου.
Αυτό μπορεί να φανεί στο στιγμιότυπό σας:
- το div
backdropείναι παιδί τουbackdrop-root - το
modalείναι παιδί τουoverlay-root - και οι δύο δεν είναι απόγονοι του
root
(Αυτό είναι το αναμενόμενο αποτέλεσμα της χρήσης του React Portal)
Ως εκ τούτου, αν εφαρμόσετε τους κανόνες CSS σας σε ένα στοιχείο μέσα στο root, δεν θα έχει κανένα στυλιστικό αποτέλεσμα στα περιεχόμενα του portal σας, αφού δεν είναι πραγματικοί απόγονοι DOM αυτού του στοιχείου (παρόλο που τα δημιουργήσατε σε React από ένα παιδικό component).
Στην περίπτωσή σας, θα μπορούσατε απλώς να εφαρμόσετε το στυλ σας απευθείας στο φόντο και στο παράθυρο διαλόγου.
Φαίνεται ότι προσπάθησες για το modal, αλλά επειδή το στυλ εφαρμόζεται στο ίδιο στοιχείο που έχει το .modal className, δεν ταιριάζει με το CSS σου που στοχεύει ένα .modal μέσα στο στοιχείο που λαμβάνει το στυλ.
Μπορείς απλώς να κάνεις, για παράδειγμα:
export const ModalStyles = css`
position: fixed;
top: 30vh;
left: 10%;
width: 60%;
height: 50%
z-index: 100;
overflow: hidden;
`;
const ModalOverlay = () => {
return (
<div css={ModalStyles}>
{/* etc. */}
</div>
);
};
