Search code examples
htmlcssresponsive-designvertical-alignmentcentering

How to vertically & horizontally center children elements in a fluid layout set by media queries?


I'm trying to achieve a certain fluid layout where the content of each DIVs are centered vertically and horizontally. But, my middle row (A, B, C) keeps on having vertical and/or horizontal alignment issues.

The goal is to have it work like this:

enter image description here

Note: If there's a way I can have the option to set the Mobile layout's "C" area fluid as well (without having to change the HTML, just the CSS, so that I can test which option works best), that'd be a bonus!

Here's a snippet of the HTML:

<div class="page">
    <div class="col col-top">top</div>
    <div class="col col-mid">
        <div class="col col-left">
            <div class="centerBox"><div class='debugBox'></div></div>
        </div>
        <div class="col col-center">
            <div class="centerBox"><div class='debugBox'></div></div>
        </div>
        <div class="col col-right">
            <div class="centerBox"><div class='debugBox'></div></div>
        </div>
    </div>
    <div class="col col-bottom">bottom</div>
</div>

I'm not sure if the "wrapper" DIVs with the "centerBox" class is really necessary (they're set as display: table-cell while each col class are set to display: table to behave like tables, but this causes issues to place those areas with position: absolute and % values for their left / right / top / bottom properties.

For instance, if the "C" area is set to display: table, this happens:

enter image description here

And if I change the "C" area to display: block;, then it fills that full center area, but...

enter image description here

... the horizontal and vertical alignment breaks inside of it.

Would using "Ghost" DIV elements (as discussed in this css-tricks article, "Centering in the Unknown" by Chris Coyier ) be any better to get the correct alignment?


Solution

  • Ok, this solution works without a framework, pure CSS using flexbox. As long as the layout is horizontal, C has a fixed width. When it is mobile, C takes up the whole width and has a variable height.

    header,
    footer {
      padding: 10px;
      background-color: lightblue;
    }
    main {
      display: flex;
      flex-direction: row;
    }
    
    main > div {
      padding: 10px;
      background-color: tomato;
      flex-grow: 1;
      min-height: 40px;
      display: flex;
      align-items: center;
    }
    main > div:nth-child(2) {
      background-color: olive;
    }
    
    .fixed {
      width: 400px;
    }
    
    @media (max-width: 768px) {
      main {
        flex-direction: column;
      }
      .fixed {
        width: auto;
      }
    }
    <header>Top</header>
    <main>
      <div>A</div>
      <div class="fixed">C</div>
      <div>B</div>
    </main>
    <footer>Bottom</footer>

    Here is a pen (drag the border to see the mobile layout): Codepen