Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS Grid Layout with Max-Width, Centered Content

I'm in the midst of learning CSS Grid (long overdue, I know). I've challenged myself to convert a relatively standard float-based layout to a grid, but can't figure out this last part.

My goal is to have a layout where the content (logo + nav, and sidebar + content) is centered, with a max-width. For example, the logo + nav should have a max-width of 600px. I also have a requirement of having a solid fill background covering the full-width of the viewport (matching the height of the variable height logo/nav row).

The first column (logo and sidebar) should shrink to fit their content - so the first column is only as wide as the wider between logo/sidebar. The nav/content should then fill the remaining space allowed by the max-width.

The following is my best attempt. The width of the main content does not fill a max-width. Instead, the width of the main content is the width of the Logo + 250px (the width defined by the grid columns).

What I'm hoping to achieve is - define the max-width of Logo + Nav to a specific width (say 600px), and have the Logo column shrink to fit its content.

body {
  margin: 40px;
}

.fill {
  grid-column-start: 1;
  grid-column-end: 6;
  grid-row-start: 1;
  grid-row-end: 1;
  background-color: gray;
}

.logo {
  grid-area: logo;
  font-size: calc(1rem + 4vw);
}

.sidebar {
  grid-area: sidebar;
}

.content {
  grid-area: content;
}

.nav {
  grid-area: nav;
  text-align: right;
}

.footer {
  grid-area: footer;
}

.wrapper {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: auto min-content 120px 120px auto;
  grid-template-areas: "... logo nav nav ..." "... sidebar content content ..." "... footer  footer  footer ...";
  background-color: #fff;
  color: #444;
}

.box {
  background-color: #444;
  color: #fff;
  border-radius: 5px;
  padding: 10px;
}

.header,
.footer {
  background-color: #999;
}
<div class="wrapper">
  <div class="fill"></div>
  <div class="box logo">Logo</div>
  <div class="box nav">Nav</div>
  <div class="box sidebar">Sidebar</div>
  <div class="box content">Content
    <br /> More content than we had before so this column is now quite tall.</div>
  <div class="box footer">Footer</div>
</div>

Is this possible with CSS Grid, and if so, how?

like image 200
Brett DeWoody Avatar asked Feb 26 '19 01:02

Brett DeWoody


People also ask

How do I center content in a grid CSS?

One of the easiest ways of centering the content of grid items is using Flexbox. Set the display to "grid" for the grid container, and "flex" for grid items. Then, add the align-items and justify-content properties, both with the "center" value, to grid items.

How do I center a div with a max width?

Technique 1 The max-width does exactly what it says, it sets a maximum width for the center content. The margin declaration is what centers the content in the browser window. The "0" sets the top and bottom margin to "0" and the "auto" sets the right and left margin to "auto" which is what actually centers the content.

How do you center items in a grid item?

Use margin: auto to vertically and horizontally center grid items. To center the content of grid items you need to make the item into a grid (or flex) container, wrap anonymous items in their own elements (since they cannot be directly targeted by CSS), and apply the margins to the new elements.

How do you center an element on the last row in CSS Grid?

To center the last one, you can double the number of columns to 4 and set each item to span 2 . If the last item is odd, start on the second column so it spans columns 2 and 3. With a bit of math and SCSS, this can be generalized to work with any number of columns.


1 Answers

You can have a 2-column grid with grid-template-columns: auto 1fr so that the first column takes the width of its content (as wide as the wider between logo/sidebar) and the second column takes up the remaining space (Note that I have set max-width: 600px to the grid container).

I also have a requirement of having a solid fill background covering the full-width of the viewport (matching the height of the variable height logo/nav row)

For this you can do the following:

  1. First fix logo and nav in the first row by setting the grid-row and grid-column properties

  2. Now use a pseudo element for wrapper overlapping the first row (but stacked below using z-index property).

  3. Set margin-left property as calc(-50vw + 50%) and width as 100vw to stretch the solid fill background across the viewport.

See demo below:

body {
  margin: 40px;
}

.wrapper {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: auto 1fr; /* 2-column grid */
  /* background-color: #fff;*/
  color: #444;
  max-width: 600px; /* max-width of the layout */
  margin: 0 auto; /* center in the viewport */
}
.logo {
  font-size: calc(1rem + 4vw);
  grid-row: 1; /* fix the logo in the first row */
  grid-column: 1; /* fix the logo in the first column */
}
.nav {
  text-align: right;
  grid-row: 1;  /* fix the nav in the first row */
  grid-column: 2;  /* fix the nav in the second column */
}

.footer {
  grid-column: span 2; /* footer spans the two columns */
}

.box {
  background-color: #444;
  color: #fff;
  border-radius: 5px;
  padding: 10px;
}

.header,
.footer {
  background-color: #999;
}

.wrapper:after { /* position this in the first row */
  content: '';
  display: block;
  grid-row: 1;
  grid-column: 1/ 3;
  width: 100vw;
  margin-left: calc(-50vw + 50%);
  background: gray;
  z-index: -1; /* push it behind the first row */
}
<div class="wrapper">
  <div class="box logo">Logo</div>
  <div class="box nav">Nav</div>
  <div class="box sidebar">Sidebar</div>
  <div class="box content">Content
    <br /> More content than we had before so this column is now quite tall.</div>
  <div class="box footer">Footer</div>
</div>
like image 68
kukkuz Avatar answered Nov 24 '22 18:11

kukkuz