Zoltan King
Zoltan King

Reputation: 2292

CSS Grid layout with gutters

I need a layout like so:

enter image description here

Here is my try:

:root {
  box-sizing: border-box;
}

*,
*::before,
*::after {
  box-sizing: inherit;
}

.grid-container {
  display: grid;
  grid-template-columns:
    [full-start] minmax(0, 1fr)
    [main-start] minmax(0, 55.625em) [main-end]
    minmax(0, 1fr) [full-end];
}

.grid-container > * {
  grid-column: full-start / full-end;
}

.header {
  background: #0e9daf;
}

.main {
  background: #9E9E9E;
  grid-column: main-start;
}

.sidebar {
  background: #dd9f32;
}

.footer {
  background: #9b51e0;
}
<!DOCTYPE html>
<html lang="en-US">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <link rel="stylesheet" href="gridlayout.css">
  <title>Document</title>
</head>
<body>
  <div class="grid-container">
    <header class="header">
      Header
    </header>

    <main class="main">
      Main
    </main>

    <aside class="sidebar">
      Sidebar
    </aside>

    <footer class="footer">
      Footer
    </footer>
  </div>
</body>
</html>

If the screen is wider, let's say a 1080p screen, the main content has gutters on the left and right side, but the header and footer extends the full page.

Think about something like this, but I'm achieving it with grid:

  .main {
     max-width: 800px;
     margin: 0 auto;
  }

On larger displays, I would like to split the main area in two portions, I need a content area (a list of all blog posts) and a sidebar on the right with widgets such as "recent posts", "search bar", etc). I need some gap (not much) between the content and sidebar.

On small screens, I would like the header first, the blog posts below the header, the widgets below the blog posts, and the footer last.

I'm not even sure if I approached this the right way. I would love to hear your opinions. Thank you.

Upvotes: 6

Views: 4942

Answers (3)

Tibbelit
Tibbelit

Reputation: 1335

You can use template-areas (https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-areas) to achieve this quite easy. If you want the layout to change with different resolutions, just add @media queries and define a new grid-template-area.

(I changed minmax(0, 55.625em) to minmax(0, 400px) for visual effect below)

.grid-container {
  display: grid;
  grid-template-rows: auto;
  grid-template-columns:  1fr minmax(0, 300px) minmax(0, 100px) 1fr;
  grid-column-gap:10px;
  grid-template-areas: 
     "header header header header"
     ". main sidebar ."
     "footer footer footer footer"
  ;
}

.header {
  grid-area: header;
  background: #0e9daf;
}

.main {
  grid-area: main;
  background: #9E9E9E;
  grid-column: main-start;
}

.sidebar {
  grid-area: sidebar;
  background: #dd9f32;
}

.footer {
  grid-area: footer;
  background: #9b51e0;
}
<!DOCTYPE html>
<html lang="en-US">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div class="grid-container">
    <header class="header">
      Header
    </header>

    <main class="main">
      Main
    </main>

    <aside class="sidebar">
      Sidebar
    </aside>

    <footer class="footer">
      Footer
    </footer>
  </div>
</body>
</html>

Upvotes: 3

Temani Afif
Temani Afif

Reputation: 273990

You can split the middle column and have 4 columns instead of 3 and you consider media query to switch back to 3 columns:

:root {
  box-sizing: border-box;
}

*,
*::before,
*::after {
  box-sizing: inherit;
}

.grid-container {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 40.625em) minmax(0, 15em) minmax(0, 1fr);
}

.grid-container>* {
  grid-column: 1/-1;
}

.header {
  background: #0e9daf;
}

.main {
  background: #9E9E9E;
  grid-column: 2;
  margin-right: 5px;
}

.sidebar {
  background: #dd9f32;
  grid-column: 3;
  margin-left: 5px;
}

.footer {
  background: #9b51e0;
}

@media all and (max-width:800px) {
  .grid-container {
    grid-template-columns: minmax(0, 1fr) minmax(0, 55.625em) minmax(0, 1fr);
  }
  .main,
  .sidebar {
    grid-column: 2;
    margin: 0;
  }
}
<div class="grid-container">
  <header class="header">
    Header
  </header>

  <main class="main">
    Main
  </main>

  <aside class="sidebar">
    Sidebar
  </aside>

  <footer class="footer">
    Footer
  </footer>
</div>

Upvotes: 0

Yousaf
Yousaf

Reputation: 29344

using grid-template-areas, you can easily achieve the desired layout

html,
body {
  height: 100%;
  margin: 0;
}

.grid-container {
  height: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 15%;
  grid-template-rows: 1fr 10fr 1fr;
  justify-content: center;
  grid-column-gap: 2%;
  grid-template-areas: "h h h h" "m m m s" "f f f f";
}

.header {
  background: #0e9daf;
  grid-area: h;
}

.main {
  background: #9E9E9E;
  grid-area: m;
}

.sidebar {
  background: #dd9f32;
  grid-area: s;
}

.footer {
  background: #9b51e0;
  grid-area: f;
}

@media (max-width: 480px) {
  .grid-container {
    grid-template-areas: "h h h h" "m m m m" "s s s s" "f f f f";
  }
}

@media (min-width: 1080px) {
  .grid-container {
    grid-template-columns: 10% 62% 12% 10%;
    grid-template-areas: "h h h h" ". m s ." "f f f f";
  }
}
<div class="grid-container">
  <header class="header">
    Header
  </header>

  <main class="main">
    Main
  </main>

  <aside class="sidebar">
    Sidebar
  </aside>

  <footer class="footer">
    Footer
  </footer>
</div>

Upvotes: 1

Related Questions