Dohab
Dohab

Reputation: 447

Mystery gaps in CSS Grid

In the snippet below, there are gaps above and beneath 'main' area which suppose to be an empty cells with the same height as the grid cells. Also there is an empty space at the very bottom.

I've tried setting grid-auto-flow to different values, but there is no effect except for the very bottom gap when it set to column.

What causes that? and how to fix it?

.header {
    grid-area: hd;
}
.footer {
    grid-area: ft;
}
.content {
    grid-area: main;
}
.sidebar {
    grid-area: sd;
}
* {box-sizing: border-box;}

.wrapper {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
    max-width: 940px;
    margin: 0 auto;
}

.wrapper > div {
    border: 2px solid #ffa94d;
    border-radius: 5px;
    background-color: #ffd8a8;
    padding: 1em;
    color: #d9480f;
}
.wrapper {
    display: grid;
    
    grid-auto-rows: minmax(auto, auto);
    grid-template-areas: 
      "hd hd ft"
      "sd . ft"
      "sd main ft"
      "sd . ft";
}
<div class="wrapper">
    <div class="header">Header</div>
    <div class="sidebar">Sidebar</div>
    <div class="content">Content</div>
    <div class="footer">Footer</div>
</div>

Upvotes: 3

Views: 195

Answers (3)

Michael Benjamin
Michael Benjamin

Reputation: 371113

Here's what's happening:

First, let's see the gaps (they don't appear in many cases):

enter image description here

.wrapper {
  display: grid;
  grid-auto-rows: minmax(auto, auto);
  grid-template-areas: "hd hd ft" "sd . ft" "sd main ft" "sd . ft";
}

.header {
  grid-area: hd;
}

.footer {
  grid-area: ft;
}

.content {
  grid-area: main;
}

.sidebar {
  grid-area: sd;
}

* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
  max-width: 940px;
  margin: 0 auto;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
<div class="wrapper">
    <div class="header">Header</div>
    <div class="sidebar">Sidebar</div>
    <div class="content">Content</div>
    <div class="footer">Footer</div>
</div>

What you're seeing is the rendering of &nbsp; (non-breaking space) characters in the HTML code.

enter image description here

As white space characters, they're invisible, which makes them hard to detect. But once you remove them, the layout works as expected.

enter image description here

.wrapper {
  display: grid;
  grid-auto-rows: minmax(auto, auto);
  grid-template-areas: "hd hd ft" "sd . ft" "sd main ft" "sd . ft";
}

.header {
  grid-area: hd;
}

.footer {
  grid-area: ft;
}

.content {
  grid-area: main;
}

.sidebar {
  grid-area: sd;
}

* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
  max-width: 940px;
  margin: 0 auto;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
<div class="wrapper">
    <div class="header">Header</div>
    <div class="sidebar">Sidebar</div>
    <div class="content">Content</div>
    <div class="footer">Footer</div>
</div>

Lastly, why doesn't the faulty layout display in many cases?

When you copy HTML code as rendered on a web page (e.g., copy the code directly from the question), the &nbsp; characters, being HTML code, have already been rendered. So only plain (collapsible) white space gets copied and the layout will appear to be working fine.

Also, if you copy the HTML code from some code editors in some browsers (e.g., the Stack Snippet editor on Edge), the &nbsp; characters don't get copied, either. I needed to copy the code from the jsFiddle editor in Chrome to finally see the problem.

Also, if you hit the "Tidy" button in the editor using the original code, spaces will be added between the lines.

Upvotes: 1

Wassim Al Ahmad
Wassim Al Ahmad

Reputation: 1094

**I tested the code on Chrome and Firefox and the result was **

enter image description here

enter image description here

Always add the <!DOCTYPE> declaration to your HTML documents, so that the browser knows what type of document to expect.

.header {
    grid-area: hd;
}
.footer {
    grid-area: ft;
}
.content {
    grid-area: main;
}
.sidebar {
    grid-area: sd;
}
* {box-sizing: border-box;}

.wrapper {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
    max-width: 940px;
    margin: 0 auto;
}

.wrapper > div {
    border: 2px solid #ffa94d;
    border-radius: 5px;
    background-color: #ffd8a8;
    padding: 1em;
    color: #d9480f;
}
.wrapper {
    display: grid;
    
    grid-auto-rows: minmax(auto, auto);
    grid-template-areas: 
      "hd hd ft"
      "sd . ft"
      "sd main ft"
      "sd . ft";
}
<!DOCTYPE html>
<html>

  <head>
	
  </head>

<body>




<div class="wrapper">
    <div class="header">Header</div>
    <div class="sidebar">Sidebar</div>
    <div class="content">Content</div>
    <div class="footer">Footer</div>
</div>
</body>
</html>

Upvotes: 2

Prawin soni
Prawin soni

Reputation: 452

The empty cells have to be inserted, you'll not get it by default, just adding the HTML and body tag fixed the bottom gap issue:

.header {
    grid-area: hd;
}
.footer {
    grid-area: ft;
}
.content {
    grid-area: main;
}
.sidebar {
    grid-area: sd;
}
.empty-cell1 {
    grid-area: ec1;
}
.empty-cell2 {
    grid-area: ec2;
}
* {box-sizing: border-box;}

.wrapper {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
    max-width: 940px;
    margin: 0 auto;
}

.wrapper > div {
    border: 2px solid #ffa94d;
    border-radius: 5px;
    background-color: #ffd8a8;
    padding: 1em;
    color: #d9480f;
}
.wrapper {
    display: grid;
    grid-template-areas: 
      "hd hd ft"
      "sd ec1 ft"
      "sd main ft"
      "sd ec2 ft";
}
<!DOCTYPE html>
<html>

  <head>
	
  </head>

<body>




<div class="wrapper">
    <div class="header">Header</div>
    <div class="sidebar">Sidebar</div>
    <div class="content">Content</div>
    <div class="footer">Footer</div>
    <div class="empty-cell1"></div>
    <div class="empty-cell2"></div>
</div>
</body>
</html>

Upvotes: -1

Related Questions