Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why auto-fit or auto-fill not working properly with minmax?

Tags:

css

css-grid

It doesn't work properly when I add auto-fit or auto-fill instead of a number.

 grid-template-columns: repeat(auto-fit, minmax(max-content, max-content));

enter image description here

But it works properly when I add number instead of max-content.

grid-template-columns: repeat(auto-fit, minmax(50px, max-content));

enter image description here

But I want the size of the grid to be the same(be fit) as the size of the content. Like this:

grid-template-columns: repeat(30, minmax(max-content, max-content));

enter image description here

(using auto-fit or auto-fill). How can I do that?

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

ul {
 display: grid;
 grid-template-columns: repeat(auto-fit, minmax(max-content, max-content));
 grid-gap: 10px;
}

li {
  list-style: none;
}
<body>
    <nav>
      <ul>
        <li>lorem ipsum</li>
        <li>dolor sit</li>
        <li>amet</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
        <li>word</li>
      </ul>
    </nav>
  </body>
like image 483
black Avatar asked Jul 30 '18 13:07

black


People also ask

What is the difference between auto-fit and auto-fill?

With auto-fill , everything is the same as auto-fit , except empty tracks are not collapsed. They are preserved. Basically, the grid layout remains fixed, with or without items. That's the only difference between auto-fill and auto-fit .

What is the difference between auto-fill column width and auto-fill content?

The difference between using auto-fill and auto-fit for sizing columns is only noticeable when the row is wide enough to fit columns in it. If you're using auto-fit, the content will stretch to fill the entire row width whereas with auto-fill, the browser will allow empty columns to occupy space in the rows.

What does grid template auto do?

The grid-auto-columns CSS property specifies the size of an implicitly-created grid column track or pattern of tracks.


2 Answers

I recently came across this problem as well. From the specs

The generic form of the repeat() syntax is, approximately,

repeat( [ <positive-integer> | auto-fill | auto-fit ] , <track-list>) The first argument specifies the number of repetitions. The second argument is a track list, which is repeated that number of times. However, there are some restrictions:

The repeat() notation can’t be nested.

Automatic repetitions (auto-fill or auto-fit) cannot be combined with intrinsic or flexible sizes.

After a few days of trying, it seems that any use of min-content, max-content, or auto in the repeat <track-list> will flat-out be ignored, even inside of minmax. Replacing one of them with a fixed-number works because it simply defaults to that. I did manage to create a programmatic workaround using ResizeSensor and jQuery, though.

var GRID_GAP = 3; // GRID-GAP of the grid
var iGridW = 0; // LAST comparative value of grid item width
var sizingWIP = false;
var GRID_LAYOUT = {
  'maxwidth': { /* CSS settings to compare item widths */
    display: "grid",
    gap: GRID_GAP + "px",
    "grid-template-columns": "none",
    "grid-auto-columns": "max-content"
  },
  'normal': { /* Normal CSS style to display the grid */
    display: "grid",
    gap: GRID_GAP + "px",
    "grid-template-columns": "repeat(auto-fit, minmax(" + iGridW + "px, 1fr)",
    "grid-auto-columns": "none"
  }
};

$(function() { // Shorthand for document.ready event
  evalGridItemMaxSize();
};

new ResizeSensor(document.getElementById("grdContainer"), function() {
  if(sizingWIP) return;
  sizingWIP = true;
  evalGridItemMaxSize();
  sizingWIP = false;
});


// EVALUATE GRID ITEM WIDTH TO MAX-CONTENT FOR *ALL* COLUMNS (equivalent to "grid-template-columns: repeat(auto-fit, max-content)" which *cannot* be set in CSS
//    (repeat(auto-fill... & repeat(auto-fit... *cannot* be used with intrinsic {min-content, max-content, auto})
function evalGridItemMaxSize() {
  $("#grdSelector").css(GRID_LAYOUT['maxwidth']);
  if ($("#someGridItemID").outerWidth() === iGridW) {
    $("#grdSelector").css(GRID_LAYOUT['normal']);
    return; //Exit if grid item max-width is same as last time
  }

  // Re-evaluate grid item width as a function of max-content of *all* items
  iGridW = $("#someGridItemID").outerWidth();
  GRID_LAYOUT['normal']['grid-template-columns'] = "repeat(auto-fit, minmax(" + iGridW + "px, 1fr)"
  $("#grdSelector").css(GRID_LAYOUT['normal']);
}
<script src="https://raw.githubusercontent.com/procurios/ResizeSensor/master/dist/resizeSensor.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container-fluid" id="grdContainer">
  <div class="grid-container" id="grdSelector">
    <!-- GRID ITEMS GO HERE -->
  </div>
</div>

evalGridItemMaxSize() sets the whole grid to a single column with size of max-content so all items will be as wide as the widest item. It then captures that width from one of the elements in the grid and recreates the columns by inserting that width (as a fixed number) into the minmax function in grid-template-columns: repeat(auto-fit....
Not sure if it's exactly what you're looking for, but I was sure happy when I figured this out :) Hope it helps.
NOTE: As I stated, this will size all columns to be the same (minimum) width as the widest element

like image 179
lnelsestuen Avatar answered Nov 03 '22 01:11

lnelsestuen


At least one of the two arguments in a minmax() function must be a fixed length (e.g., px, em, %).

This rule is detailed in the Grid spec. See section "The syntax of a track list".

That's why your code (copied below) is not working.

grid-template-columns: repeat(auto-fit, minmax(max-content, max-content));

In solving the problem I thought this other Grid rule would come in handy:

minmax(min, max)

Defines a size range greater than or equal to min and less than or equal to max.

If max < min, then max is ignored and minmax(min,max) is treated as min.

Looking at that last line, if max is less than min, then min prevails.

Looking at the first rule, at least one argument must be a fixed length.

So then this should work:

grid-template-columns: repeat(auto-fit, minmax(min-content, 1px));

It actually does fix the problem... but it also breaks the auto-fit wrapping feature (demo).

Nothing else I tried seemed to work. Maybe somebody else can find a solution. Or maybe this is a limitation in the current iteration of Grid.

like image 25
Michael Benjamin Avatar answered Nov 03 '22 00:11

Michael Benjamin