Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested CSS grid layout different behavior in Chrome and Firefox

I'm trying to use CSS grid layout to simulate some responsive behavior, specifically with:

grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));

My example https://codepen.io/elgs/pen/goNxeL works well in Chrome, however, it doesn't seem to work in Firefox. You will find it when you resize the browser horizontally.

Another example https://codepen.io/elgs/pen/YYoxOq works well in both Chrome and Firefox.

html,body {
  height: 100%;
  width: 100%;
  margin: 0 auto;
  padding: 0;
}
body {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 100px 1fr 50px;
}
.header {
  grid-column: 1/2;
  grid-row: 1/2;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr;
  background-color: #57324f;
}
.header .title {
  grid-column: 1/2;
  grid-row: 1/2;
  align-self: center;
  justify-self: center;
  width: 100%;
  max-width: 1000px;
  color: aliceblue;
}
.footer {
  grid-column: 1/2;
  grid-row: 3/4;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr;
  background-color: #57324f;
}
.footer .copyright {
  grid-column: 1/2;
  grid-row: 1/2;
  align-self: center;
  font-size: 12px;
  justify-self: center;
  width: 100%;
  max-width: 1000px;
  color: aliceblue;
}
.content {
  grid-column: 1/2;
  grid-row: 2/3;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 0;
  background-color: aliceblue;
}
.content .main {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  grid-gap: 10px;
  grid-auto-flow: dense;
  justify-self: center;
  width: 100%;
  margin-top: 10px;
  max-width: 1000px;
}
.placeholder {
    height: 100px;
  position: relative;
  border: 1px solid red;
}
<div class="header">
    <div class="title">
        <h2>Header</h2>
    </div>
</div>
<div class="content">
    <div class="main">
        <div class="placeholder"></div>
        <div class="placeholder"></div>
        <div class="placeholder"></div>
        <div class="placeholder"></div>
        <div class="placeholder"></div>
        <div class="placeholder"></div>
    </div>
</div>
<div class="footer">
    <div class="copyright">
        <span>Footer</span>
    </div>
</div>

I'm wondering whether I have done anything wrong or it's the browser's bug.

  • Firefox version: 58.0 (64-bit)
  • Chrome version: Version 64.0.3282.119 (Official Build) (64-bit)
like image 691
Qian Chen Avatar asked Jan 25 '18 12:01

Qian Chen


People also ask

Is grid layout supported by all browsers?

The supporting browsers Other than in Internet Explorer, CSS Grid Layout is unprefixed in Safari, Chrome, Opera, Firefox and Edge. Support for all the properties and values detailed in these guides is interoperable across browsers.

Can CSS grids be nested?

You can "nest" grids by making a grid item a grid container. These grids however are independent of the parent grid and of each other, meaning that they do not take their track sizing from the parent grid. This makes it difficult to line nested grid items up with the main grid.

What is the difference between grid and inline grid?

The difference between the values inline-grid and grid is that the inline-grid will make the element inline while grid will make it a block-level element.

Does Subgrid work on Chrome?

CSS Subgrid on Chrome is fully supported on None of the versions, partially supported on None of the versions, and not supported on 4-106 Chrome versions.


1 Answers

This appears to be a bug in Firefox. But I'm not sure.

Here's what is clear:

  1. The fact that you have nested grid containers matters.

    Your second demo, which works in both Chrome and Firefox, has only one grid container.

    The first demo, which only works in Chrome, has nested grid containers. If you eliminate that nesting, and use only one grid container, the layout works in both browsers.

    So, as a possible cross-browser solution, minimize the nesting of grid containers.

    In this revised demo, I've commented out display: grid on the body and .content elements. The only grid container left is on .main, the parent of the red boxes:

    revised demo

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

body {
  /* display: grid; */
  grid-template-columns: 1fr;
  grid-template-rows: 100px 1fr 50px;
}

.header {
  grid-column: 1/2;
  grid-row: 1/2;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr;
  background-color: #57324f;
}

.header .title {
  grid-column: 1/2;
  grid-row: 1/2;
  align-self: center;
  justify-self: center;
  width: 100%;
  max-width: 1000px;
  color: aliceblue;
}

.footer {
  grid-column: 1/2;
  grid-row: 3/4;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr;
  background-color: #57324f;
}

.footer .copyright {
  grid-column: 1/2;
  grid-row: 1/2;
  align-self: center;
  font-size: 12px;
  justify-self: center;
  width: 100%;
  max-width: 1000px;
  color: aliceblue;
}

.content {
  grid-column: 1/2;
  grid-row: 2/3;
  /* display: grid; */
  grid-template-columns: 1fr;
  grid-template-rows: 0;
  background-color: aliceblue;
}

.content .main {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  grid-gap: 10px;
  grid-auto-flow: dense;
  justify-self: center;
  width: 100%;
  margin-top: 10px;
  max-width: 1000px;
}

.placeholder {
    height: 100px;
  position: relative;
  border: 1px solid red;
}
<div class="header">
  <div class="title">
    <h2>Header</h2>
  </div>
</div>
<div class="content">
  <div class="main">
    <div class="placeholder"></div>
    <div class="placeholder"></div>
    <div class="placeholder"></div>
    <div class="placeholder"></div>
    <div class="placeholder"></div>
    <div class="placeholder"></div>
  </div>
</div>
<div class="footer">
  <div class="copyright">
    <span>Footer</span>
  </div>
</div>

  1. In Firefox, a fixed value on max-width prevents the box from shrinking to accommodate smaller screen sizes.

    Firefox has a problem shrinking the .main container with a pixel value on the max-width. Chrome does not.

    A typical solution that comes to mind is to override the min-width: auto default setting on grid items. This prevents items from shrinking past the size of their content or their defined width.

    However, that solution, described here: Prevent content from expanding grid items ... doesn't work in this case.

    (Probably because there is no content in and no defined widths on the grid items. The only widths defined are on the grid columns, set on the grid container. So the solution, which applies only to grid items, probably doesn't even apply.)

    As a possible workaround, if you must keep the nested containers, then instead of using a fixed value with max-width, use a percentage value. That may work for you.

    revised codepen

body {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 100px 1fr 50px;
  height: 100vh;
  margin: 0;
}

.header {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr;
  background-color: #57324f;
}

.content {
  display: grid;
  grid-template-columns: 1fr;
  /* grid-template-rows: 0; */
  align-content: start;  /* new */
  background-color: aliceblue;
}

.content .main {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  grid-auto-rows: 100px;  /* new */
  grid-gap: 10px;
  grid-auto-flow: dense;
  justify-self: center;
  width: 100%;
  margin-top: 10px;
  /* max-width: 1000px; */
  max-width: 75%;  /* new */
}

.placeholder {
  border: 1px solid red;
}

.footer {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr;
  background-color: #57324f;
}

.header .title,
.footer .copyright {
  align-self: center;
  justify-self: center;
  width: 100%;
  max-width: 1000px;
  color: aliceblue;
}

.footer .copyright {
  font-size: 12px;
}
<div class="header">
  <div class="title">
    <h2>Header</h2>
  </div>
</div>
<div class="content">
  <div class="main">
    <div class="placeholder"></div>
    <div class="placeholder"></div>
    <div class="placeholder"></div>
    <div class="placeholder"></div>
    <div class="placeholder"></div>
    <div class="placeholder"></div>
  </div>
</div>
<div class="footer">
  <div class="copyright">
    <span>Footer</span>
  </div>
</div>
like image 72
Michael Benjamin Avatar answered Sep 28 '22 11:09

Michael Benjamin