cssreactjsflexboxreact-portal

Centering a react portal on top of the parent element


I have been reading a lot of about Portals and decided to make one.

I have a simple react page that displays a table.

So I made a button, that when clicked, blurs the table and opens the portal.

It "works", but for some reason the table isn't centered like I see in the articles I've been reading.

It just appears at the bottom of the page, under the blurred table.

Here is my Portal:

function MyPortal() {
    return ReactDOM.createPortal(
        <div>
            <div>My first Portal!</div>
            <div>HEY YOU</div>
        </div>,
        document.getElementById('portal-root'),
        document.getElementById('DisplayTable').style.filter = 'blur(5px)'
    )
}

And here is my table function:

function DisplayTable() {
const [isPortalOpen, setIsPortalOpen] = useState(false);

// some data processing code for the table


return (
    <div id="mainContent">
        <div id="DisplayTable">
            <table>
                <tr>
                    <td>My Table</td>
                </tr>
                <tr>
                    <td><button onClick={() => { setIsPortalOpen(!isPortalOpen); }}>Portal Button</button></td>
                </tr>
            </table>
        </div>
         {isPortalOpen && (
            <MyPortal />
        )}
    </div>
)

And here is my main index.js:

ReactDOM.render(
    <React.Fragment>
        <Table />
        <div id="portal-root"></div>
    </React.Fragment>,
    document.getElementById('root')
)   

How can make it so the portal is displayed in the middle of the screen instead of the bottom?

Do I need to use another component or library?

Thanks!


Solution

  • So here is how I did it. I am sure there are many ways to do this.

    I added this to the main parent div of the portal:

    z-index: 100;
    

    Then I added this to the div that the portal creates:

    position: absolute; 
    background-color: #eee;
    border: 1px solid #555;
    left:0;
    right:0;
    margin-left: auto;
    margin-right: auto;
    height: 75%;
    top: 15%; /* push down by 50% of the height of the container */
    width: 80%;
    margin-top: -25px; /* bring it back up by half of it's height */
    

    Like I said, there are many ways to achieve this and this was my way.