Nick
Nick

Reputation: 165

Avoiding double grid gap when a grid item is collapsed in mobile view

I am creating a site layout using CSS grid and I have almost got it exactly as I'd like, but I am having one problem:

My desktop view is as I want it, but when it collapses down to a mobile sized view (all elements in separate rows), my leftPad and rightPad divs cause a double grid-gap as seen below:

double grid gap

The code can be seen here: https://codepen.io/nickmask/pen/BbxNoE

.container {
  display: grid;

  grid-template-areas:
    "nav nav nav nav nav"
    "header header header header header"
    "leftPad leftSidebar content rightSidebar rightPad"
    "footer footer footer footer footer";

  grid-template-columns: auto 200px minmax(auto, 600px) 200px auto;
  grid-template-rows: auto auto 1fr auto;
  grid-gap: 10px;

  height: 100vh;
}

body {
  margin: 0;
}

@media (max-width: 768px) {
  .container {
    grid-template-areas:
      "nav"
      "header"
      "leftPad"
      "leftSidebar"
      "content"
      "rightSidebar"
      "rightPad"
      "footer";

    grid-template-columns: 1fr;
    grid-template-rows:
      auto /* Nav */
      auto /* Header */
      auto /* Left Pad */
      minmax(75px, auto) /* Left Sidebar */
      1fr /* Content */
      minmax(75px, auto) /* Right Sidebar */
      auto /* Right Pad */
      auto; /* Footer */
  }

  nav,
  aside {
    margin: 0;
  }
}

header {
  grid-area: header;
  background-color: aqua;
}

nav {
  grid-area: nav;
  background-color: lightblue;
}

main {
  grid-area: content;
}

.leftSidebar {
  background-color: aliceblue;
  grid-area: leftSidebar;
}

.rightSidebar {
  background-color: aliceblue;
  grid-area: rightSidebar;
}

footer {
  grid-area: footer;
  height: 100px;
  background-color: lightcoral;
}
    <div class="container">
      <nav>
        <!-- Navigation -->
        Nav
      </nav>
      <header>
        Header
      </header>
      <div class="leftPad"></div>
      <aside class="leftSidebar">
        <!-- Sidebar / Ads -->
        Side bar
      </aside>
      <main>
        <!-- Main content -->
        Main content
      </main>
      <aside class="rightSidebar">
        <!-- Sidebar / Ads -->
        Side bar
      </aside>
      <div class="rightPad"></div>
      <footer>
        Footer
        <!-- Footer content -->
      </footer>
    </div>
>

Any work around to this, or suggestions on how I could be building this layout differently? Cheers!

Upvotes: 3

Views: 1690

Answers (2)

Temani Afif
Temani Afif

Reputation: 272947

I would optimize you grid definition like below by removing the non needed elements and reducing the number of properties.

I would also consider flexbox on small screen since you won't really have a grid and your elements will simply stack above each other

.container {
  display: grid;
  grid-template-columns: auto 200px minmax(auto, 600px) 200px auto;
  grid-template-rows: auto auto 1fr auto;
  grid-gap: 10px;
  min-height: 100vh; /*better use min-height to avoid overflow on small screen */
}

@media (max-width: 768px) {
  .container {
    display: flex;
    flex-direction: column;
  }
  /*this will replace the gap*/
  .container>*:not(:last-child) {
    margin-bottom: 10px;
  }
}

header,
nav,
footer {
  grid-column: 1/-1;
  /*take whole line*/
}

main {
  grid-column: 3;
  flex-grow: 1; /*will replace 1fr on small screen*/
}

.leftSidebar,
.rightSidebar {
  min-height: 75px;
  background-color: aliceblue;
}

.leftSidebar {
  grid-column: 2;
}

.rightSidebar {
  grid-column: 4;
}

footer {
  height: 100px;
  background-color: lightcoral;
}

header {
  background-color: aqua;
}

nav {
  background-color: lightblue;
}

body {
  margin: 0;
}
<div class="container">
  <nav>
    <!-- Navigation -->
    Nav
  </nav>
  <header>
    Header
  </header>
  <aside class="leftSidebar">
    <!-- Sidebar / Ads -->
    Side bar
  </aside>
  <main>
    <!-- Main content -->
    Main content
  </main>
  <aside class="rightSidebar">
    <!-- Sidebar / Ads -->
    Side bar
  </aside>
  <footer>
    Footer
    <!-- Footer content -->
  </footer>
</div>

Upvotes: 0

kukkuz
kukkuz

Reputation: 42352

The problem is your leftPad and rightPad - you can remove them and then change your grid-template-areas:

grid-template-areas:
    "nav nav nav nav nav"
    "header header header header header"
    ". leftSidebar content rightSidebar ."
    "footer footer footer footer footer";

Note the dots in the definition above. In mobile view, just omit them.

However you can leave grid cells empty with this method of layout. To leave a cell empty use the full stop character, '.'.

MDN

See demo below:

.container {
  display: grid;

  grid-template-areas:
    "nav nav nav nav nav"
    "header header header header header"
    ". leftSidebar content rightSidebar ."
    "footer footer footer footer footer"; /* CHANGED */

  grid-template-columns: auto 200px minmax(auto, 600px) 200px auto;
  grid-template-rows: auto auto 1fr auto;
  grid-gap: 10px;

  height: 100vh;
}

body {
  margin: 0;
}

@media (max-width: 768px) {
  .container {
    grid-template-areas:
      "nav"
      "header"
      "leftSidebar"
      "content"
      "rightSidebar"
      "footer"; /* CHANGED */

    grid-template-columns: 1fr;
    grid-template-rows:
      auto /* Nav */
      auto /* Header */
      minmax(75px, auto) /* Left Sidebar */
      1fr /* Content */
      minmax(75px, auto) /* Right Sidebar */
      auto; /* Footer */
  } /* CHANGED */

  nav,
  aside {
    margin: 0;
  }
}

header {
  grid-area: header;
  background-color: aqua;
}

nav {
  grid-area: nav;
  background-color: lightblue;
}

main {
  grid-area: content;
}

.leftSidebar {
  background-color: aliceblue;
  grid-area: leftSidebar;
}

.rightSidebar {
  background-color: aliceblue;
  grid-area: rightSidebar;
}

footer {
  grid-area: footer;
  height: 100px;
  background-color: lightcoral;
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" type="text/css" media="screen" href="main.css" />
    <script src="main.js"></script>
  </head>
  <body>
    <div class="container">
      <nav>
        <!-- Navigation -->
        Nav
      </nav>
      <header>
        Header
      </header>
      
      <aside class="leftSidebar">
        <!-- Sidebar / Ads -->
        Side bar
      </aside>
      <main>
        <!-- Main content -->
        Main content
      </main>
      <aside class="rightSidebar">
        <!-- Sidebar / Ads -->
        Side bar
      </aside>
      
      <footer>
        Footer
        <!-- Footer content -->
      </footer>
    </div>
  </body>
</html>

Upvotes: 2

Related Questions