Search code examples
htmlcssflexboxcenteringtext-align

How to center text within a parent div that has children divs of different sizes (flexbox)


I'm creating a site with Flexbox (which I'm fairly new at using). I want to put the name of the site and the menu dropdown button on the same line. I was able to do this successfully with Flexbox, however the Title isn't centered on the page itself. I'm aware that this is because the menu button has a flex-grow of 1 while the title has a flex-grow of 8. I did this on purpose for spacing, however now the Title isn't centered on the entire page.

I've tried leaving the title div blank and just writing a title outside of the div, but this places the text before the parent container.

<body>
    <div class="parent container">
        <!--Navigational Bar-->
        <div class="Nav">
            <div id="Nav_Button">
                <p>Button</p>
            </div>
            <div id="Nav_Title">
                <h3>Super Snack Stadium</h3>
            </div>
        </div>
    </div>
</body>

.parent_container {
    display: flex;
    flex-direction: column;
    flex-wrap: wrap;
    justify-content: flex-start;
}

/*Containers within ".parent container"*/

.Nav {
    border: 1px solid black;
    text-align: center;
    /*Flex Child Code*/
    order:1;
    /*Flex Parent Code*/
    display: flex;
    flex-direction: row;

}

/*--------Children of .Nav ---------*/

#Nav_Button {
    border: 1px solid black;
    /*Flex Child Code*/
    order: 1;
    flex-grow: 1;
}

#Nav_Title {
    border: 1px solid black;
    text-align: center;
    /*Flex Child Code*/
    order: 2;
    flex-grow: 8;
}

I want to be able to center the title for the entire page (not just within the container its in) using Flexbox if possible.


Solution

  • Step 1: Set the Nav position:relative;

     .Nav {
       border: 1px solid black;
       text-align: center;
       /*Flex Child Code*/
       order:1;
      /*Flex Parent Code*/
      display: flex;
      flex-direction: row;
      position:relative;
    }
    

    Step 2: make h3 absolute.

    h3 {
      position:absolute;
    }
    

    Now, h3is taken out of the document flow, but it can be positioned based on the closest relative element.

    In this case, we have made .Nav as relative. So, h3 will use .Nav for reference. Since .Nav occupies full width of the screen, all we need is to position h3 to the center of .Nav using left and transform

    Step 3:

    h3 {
      position:absolute;
      left:50%;
      transform:translateX(-50%);
    }
    

    Final:

    .parent_container {
        display: flex;
        flex-direction: column;
        flex-wrap: wrap;
        justify-content: flex-start;
    }
    
    /*Containers within ".parent container"*/
    
    .Nav {
       border: 1px solid black;
       text-align: center;
       /*Flex Child Code*/
       order:1;
      /*Flex Parent Code*/
      display: flex;
      flex-direction: row;
      position:relative;
    }
    /*--------Children of .Nav ---------*/
    
    #Nav_Button {
        border: 1px solid black;
        /*Flex Child Code*/
        order: 1;
        flex-grow: 1;
    }
    
    #Nav_Title {
        border: 1px solid black;
        text-align: center;
        /*Flex Child Code*/
        order: 2;
        flex-grow: 8;
    }
    h3 {
      position:absolute;
      left:50%;
      transform:translateX(-50%);
    }
    <div class="Nav">
                <div id="Nav_Button"><p>Button</p></div>
                <div id="Nav_Title"><h3>Super Snack Stadium</h3></div>
            </div>