1

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?

focus.style
  • 6,612
  • 4
  • 26
  • 38
cjbj
  • 163
  • 4
  • 11
  • justify-content is a property related to CSS Flex, it basically affectst all Items that are inside of the item you apply "justify-content" to. So if you have 4 items inside a row (for example a div) justify-content: center stuffs all 4 Items next to each other in the center of the row. It is meant to be used with "display: flex". – Warden330 Jul 28 '20 at 12:14
  • https://stackoverflow.com/questions/45536537/centering-in-css-grid this could help you out if you want to position items in a grid setup – Warden330 Jul 28 '20 at 12:15
  • in short: in grid its called justify-items not justify-content – Warden330 Jul 28 '20 at 12:18

1 Answers1

1

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>
focus.style
  • 6,612
  • 4
  • 26
  • 38
  • Thanks for looking into it. This is one of the things I tried. It works, as long as there is no content wider than 1200px in header or footer. As soon as I insert a 1800 px header image, the fourth column reverts to zero and main+sidebar are aligned right. – cjbj Jul 29 '20 at 07:40
  • Add `max-width: 100%` to your image. – focus.style Jul 29 '20 at 07:43
  • Trust me, it's there... There is a wrapper inside #header that also has 100% width on it. – cjbj Jul 29 '20 at 07:47
  • Updated the post. Added the image and removed `grid-auto-rows`. – focus.style Jul 29 '20 at 07:49
  • Thanks again. Obviously your example works. Trouble at my end persists. Probably has to do with the fact that #header contains some wrappers around image, header and menu. – cjbj Jul 29 '20 at 08:15
  • I suggest you to make footer and header separate from main and sidebar, using `max-width:1200px; margin:0` like in good old days. Grid is good, but not in this case. It's like hitting a screw with a hummer, we can reach the result but what cost? – focus.style Jul 29 '20 at 08:23
  • I certainly would if it were for only one site. I'm building a WP-template where I can simply click some elements (want a header image? how many columns? etc) in the backoffice and it will generate html and css. So the solution must be generic... Anyway, I'll accept your answer and keep on trying – cjbj Jul 29 '20 at 08:33