4

As you can see in this simple example, each grid cell always uses the maximum possible amount of space. Why does this happen, and how can I convince the grid to use less space if possible?

.testgrid {
  display: grid;
  grid-template-columns: 20% minmax(20%, 80%);
  grid-auto-rows: minmax(1.5em, 4.5em);
}

.testgrid .item {
  background-color: #AF6;
  margin: 1px;
  overflow: hidden;
}
<div class="testgrid">
  <div class="item">Cell 1</div>
  <div class="item">Cell 2</div>
  <div class="item">Cell 3 (uses too much space, so really it ought to be clipped)</div>
  <div class="item">Cell 4</div>
  <div class="item">Cell 5</div>
  <div class="item">Cell 6 (more text here, could push the column wider)</div>
</div>
Qwertie
  • 16,354
  • 20
  • 105
  • 148
  • minmax is a function that clamps values between the two arguments. It will not use less space if possible. – Andrew Li Aug 05 '18 at 16:59
  • By setting a minimum, you're specifying the least possible value it can have. Which means if the space available falls below that value, it'll force that minimum. Your maximum is the max value it'll take up if space is available. This being said, if your max is 3em and 3em is available, it'll use 3em. If 4em is available, it'll still be 3em. Sounds like you want to lower your max. – CodeSpent Aug 05 '18 at 17:06
  • 1
    No, I don't want to lower the maximum, I want the grid to **choose** to use less space, not **be forced** to use less space. To put the question another way: at present the first argument to `minmax` has no effect. Under what circumstances would it have an effect? – Qwertie Aug 05 '18 at 20:44

3 Answers3

3

When you are not using minmax, css grid can use content-sensitive sizing, but evidently, as soon as you add minmax, the grid ignores content and divides space equally among different cells. minmax also prefers to waste space if possible; it will only use less than the maximum if the container is constrained (e.g. by a fixed height or width.)

Therefore, avoid minmax if you want content-sensitive sizing. In fact, content-sensitive sizing seems to be supported only for auto (and no, you cannot write something like calc(auto+2fr) to get more intelligent distribution of free space.)

The desired effect of having a minimum and maximum row height can be accomplished by using auto as the row height and setting the minimum and maximum as properties of the items instead:

.testgrid {
  display: grid;
  grid-template-columns: 20% auto 1fr;
  grid-auto-rows: auto;
  max-width: 600px;
}

.testgrid .item {
  background-color: #AF6;
  margin: 1px;
  overflow: hidden;
  min-height: 1.5em;
  max-height: 4.5em;
}
<div class="testgrid">
  <div class="item">Cell 1</div>
  <div class="item">Cell 2</div>
  <div></div>
  <div class="item">Cell 3 (uses too much space, so really it ought to be clipped)</div>
  <div class="item">Cell 4</div>
  <div></div>
  <div class="item">Cell 5</div>
  <div class="item">Cell 6 (more text here, could push the column wider)</div>
  <div></div>
</div>

I couldn't find an easy way to use less than the maximum column width (this is strange because HTML tables behave that way by default, so it is surprising if the css grid system, which would have ideally made table layouts obsolete, doesn't offer a feature for this purpose.) justify-items: start (or justify-self: start in .item) causes individual cells to shrink independently of each other, but that's undesirable if you want all cells in the column to have the same width.

As a workaround I added a dummy third column to occupy the unused space. Unfortunately this is not CSS-only; the HTML must be aware of the dummy column. In order for this to work properly, the dummy column needs to use the fr unit while all other columns must be fixed-width or auto.

Qwertie
  • 16,354
  • 20
  • 105
  • 148
0

I think you need max-content, This should work:

.testgrid {
  display: grid;
  grid-template-columns: 20% minmax(20%, max-content);
  grid-auto-rows: minmax(1.5em, 4.5em);
}
ziz194
  • 312
  • 2
  • 8
  • 22
-2

It is css3 function and depending on your element size and your screen size .