Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS Grid layout max-content does not work as expected in Firefox

Tags:

html

css

css-grid

I used CSS Grid layout to create a basic layout for a page, and I worked originally in Chrome while doing that. I tested this now also in Firefox and noticed some behaviour that I don't understand and that doesn't seem to follow the specification as I understand it.

I created a simplified example that shows the behaviour. The problem is the height of the search-header div. This is set to max-content and should be just as large as needed to fit the contained element.

This works as expected in Chrome 66, but not in Firefox 52 ESR or Firefox 62 Developer Edition (all on Linux). In Firefox the search-header div is larger and extends beyond the contained span. This does only happen if there are the input elements in the search-sidebar div, and the more of them I add the larger the search-header div gets.

Am I misunderstanding how max-content is supposed to work? Why are Firefox and Chrome behaving differently in this case? And how can I fix this?

.search {
  display: grid;
  grid-template-columns: minmax(200px, 1fr) 4fr;
  grid-template-rows: max-content auto;
  grid-gap: 10px;
  height: 95vh;
  width: 100%;
  align-self: stretch;
  background: #FFF;
  overflow: hidden;
  margin-top: 5px;
}

.search-sidebar {
  grid-column: 1 / 2;
  grid-row: 1 / 3;
  background: #CCFFFF;
  padding: 5px;
}

.search-header {
  grid-column: 2 / 3;
  grid-row: 1 / 2;
  background: #FFCCCC;
  padding: 5px;
}

.search-table {
  grid-column: 2 / 3;
  grid-row: 2 / 3;
  background: #FFFFAA;
}
<div class="search">
  <div class="search-sidebar">
    <div>
      <label>Label:</label>
      <div><input type="text"></div>
    </div>
    <div>
      <label>Label:</label>
      <div><input type="text"></div>
    </div>
    <div>
      <label>Label:</label>
      <div><input type="text"></div>
    </div>
  </div>
  <div class="search-header">
    <span>some text here</span>
  </div>
  <div class="search-table"></div>
</div>

This is how it looks in Firefox:

enter image description here

And this is how it looks in Chrome, and how it is intended to look:

enter image description here

like image 587
Mad Scientist Avatar asked Jul 16 '18 09:07

Mad Scientist


2 Answers

As Ilya Streltsyn comments, replacing auto for 1fr solves the issue. Any browser that supports display: grid will support fr, and there's virtually no difference between auto and one single use of fr: both refer to the entirety of the unclaimed space.

grid-template-rows: max-content 1fr;

.search {
  display: grid;
  grid-template-columns: minmax(200px, 1fr) 4fr;
  grid-template-rows: max-content 1fr;
  grid-gap: 10px;
  height: 95vh;
  width: 100%;
  align-self: stretch;
  background: #FFF;
  overflow: hidden;
  margin-top: 5px;
}

.search-sidebar {
  grid-column: 1 / 2;
  grid-row: 1 / 3;
  background: #CCFFFF;
  padding: 5px;
}

.search-header {
  grid-column: 2 / 3;
  grid-row: 1 / 2;
  background: #FFCCCC;
  padding: 5px;
}

.search-table {
  grid-column: 2 / 3;
  grid-row: 2 / 3;
  background: #FFFFAA;
}
<div class="search">
  <div class="search-sidebar">
    <div>
      <label>Label:</label>
      <div><input type="text"></div>
    </div>
    <div>
      <label>Label:</label>
      <div><input type="text"></div>
    </div>
    <div>
      <label>Label:</label>
      <div><input type="text"></div>
    </div>
  </div>
  <div class="search-header">
    <span>some text here</span>
  </div>
  <div class="search-table"></div>
</div>
like image 25
wordbug Avatar answered Oct 01 '22 08:10

wordbug


I would start with a review of browser support for the max-content sizing value.

Here are a few observations:

  • The min-content, max-content and fit-content() values are all new. They were introduced in CSS Intrinsic & Extrinsic Sizing Module Level 3. So full browser support is already suspect.

  • A review of browser support tables at caniuse.com reveals that max-content has full support in Chrome, but only limited support in Firefox. It also requires the -moz- prefix to work in FF.

  • A review of max-content at MDN also shows that max-content works fine in Chrome, but has limited support and requires the -moz- prefix in Firefox. MDN also says that max-content is experimental and should not be used in production code.

Those items may describe the reason for the Chrome / Firefox discrepancy in your layout.

But putting all that aside, you don't even need max-content to make your layout work. You can use max-content, min-content or auto on the first row.

Then make the second row 1fr, which forces the second row to consume all remaining height in the container, squeezing all free space out of the first row.

The auto value does not do this because it functions under a different algorithm than fr.

  • fr sizing algorithm
  • auto sizing algorithm

So, for the reasons described above, make this simple adjustment to your code:

grid-template-rows: auto 1fr;

.search {
  display: grid;
  grid-template-columns: minmax(200px, 1fr) 4fr;
  grid-template-rows: auto 1fr;
  grid-gap: 10px;
  height: 95vh;
  width: 100%;
  align-self: stretch;
  background: #FFF;
  overflow: hidden;
  margin-top: 5px;
}

.search-sidebar {
  grid-column: 1 / 2;
  grid-row: 1 / 3;
  background: #CCFFFF;
  padding: 5px;
}

.search-header {
  grid-column: 2 / 3;
  grid-row: 1 / 2;
  background: #FFCCCC;
  padding: 5px;
}

.search-table {
  grid-column: 2 / 3;
  grid-row: 2 / 3;
  background: #FFFFAA;
}
<div class="search">
  <div class="search-sidebar">
    <div>
      <label>Label:</label>
      <div><input type="text"></div>
    </div>
    <div>
      <label>Label:</label>
      <div><input type="text"></div>
    </div>
        <div>
      <label>Label:</label>
      <div><input type="text"></div>
    </div>
        <div>
      <label>Label:</label>
      <div><input type="text"></div>
    </div>
        <div>
      <label>Label:</label>
      <div><input type="text"></div>
    </div>
    <div>
      <label>Label:</label>
      <div><input type="text"></div>
    </div>
  </div>
  <div class="search-header">
    <span>some text here</span>
  </div>
  <div class="search-table"></div>
</div>

jsFiddle demo

like image 200
Michael Benjamin Avatar answered Oct 01 '22 07:10

Michael Benjamin