cjbj
cjbj

Reputation: 163

CSS Grid with fullwidth header/footer and narrower main/sidebar

I have a classic site set-up with a header, main content with sidebar, and a footer. On wider screens I want the header and footer to be full width, while the main and sidebar have a fixed width, with whitespace on either site. When you make the screen narrower the whitespace shrinks (much like here at StackExchange). Once you reach the main+sidebar width, these scale down. In the old days, I would put a wrapper around main+sidebar, apply max-width:1200px; margin:0 auto; and it was done. Now I'm trying to solve this with grid, but to no avail. Here's the code:

<div id="totalcontent">
  <div id="header">content</div>
  <div id="main">content</div>
  <div id="sidebar">content</div>
  <div id="footer">content</div>
</div>

<style>
#totalcontent {
  grid-template-areas:
   'header header'
   'main sidebar'
   'footer footer';
  grid-template-columns: 66% auto;
  }
</style>

Now, I can put (say) max-width:900px; float:right on #main and max-width:300px; float:left; on #sidebar to make them narrower, but only when window width is 1800px will this lead to neatly centered content with 300px whitespace on either side. As soon as the screen becomes narrower, main+sidebar veer left, because at 1500px width you would need grid-template-columns: 70% auto; to have 150px whitespace on either side.

What I tried

  1. Make it a four column grid with empty blocks either side of main and sidebar. Tried all kinds of things with grid-template-columns to prioritize the empty blocks shrinking. No luck.
  2. Use media queries to adjust grid-template-columns. That worked, but made the design jumpy when dragging the window to resize it.
  3. Ditch the grid system and revert to css plus added html. This works, but looks hacky.

The latter solution looks like this:

<div id="totalcontent">
  <div id="header">content</div>
  <div id="main"><div class="inner">content</div></div>
  <div id="sidebar"><div class="inner">content</div></div>
  <div id="footer">content</div>
</div>

<style>
#main           {width:calc( 900px + ( (98vw - 1200px) / 2) );}
#main .inner    {max-width:900px; float:right}
#sidebar        {width:calc( 300px + ( (98vw - 1200px) / 2) );}
#sidebar. inner {max-width:300px; float:left;}
</style>

<!-- 98vw instead of 100vw as a safety margin to account for gap -->

Question

The problem seems to be that you can center a single grid item inside a row using justify-content:center; but you cannot center multiple grid items inside a row. Is that correct? If not, how do I do it?

Upvotes: 1

Views: 2415

Answers (1)

focus.style
focus.style

Reputation: 6760

I think your approach is over complicated. Here is the example with @media but without jumping on screen resize.

First we using grid-template-columns: auto 900px 300px auto; and after screen reaches 1200px width - switch to grid-template-columns: auto 3fr 1fr auto;

As soon as 1200px we can imagine as 4fr, so 900px is 3fr and 300px is 1fr. This will minimize any jumping on @media switch.

body {
  margin: 0;
  padding: 0;
}

#totalcontent {
  display: grid;
  grid-template-areas:
    'header header header header'
    '. main sidebar .'
    'footer footer footer footer';
  grid-template-columns: auto 900px 300px auto;
  
}

@media (max-width: 1200px) {
  #totalcontent {
    grid-template-columns: auto 3fr 1fr auto;
  }
}

#header {
  grid-area: header;
  background: #555
  min-height: 100px;
}

#main {
  grid-area: main;
  background: #777;
  min-height: 100px;
}

#sidebar {
  grid-area: sidebar;
  background: #999;
  min-height: 100px;
}

#footer {
  grid-area: footer;
  background: #aaa;
  min-height: 100px;
}

#header img {max-width: 100%;}
<div id="totalcontent">
  <div id="header"><img src="http://via.placeholder.com/1800x190">content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content </div>
  <div id="main">content</div>
  <div id="sidebar">content</div>
  <div id="footer">content</div>
</div>

Upvotes: 1

Related Questions