Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to specify the maximum number of columns repeat() will create using auto-fit/fill? [duplicate]

Tags:

css

css-grid

Is there a way, without using media query, to limit the number of columns that get created, and combine that with auto-fit/fill?

For example:

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

Creates a wonderful, responsive layout. But imagine the design calls for a maximum of 3 columns -- even in wide browsers. It would happily show, 4, 5, more columns as space allows.

Using media query, I could specify big screens get:

grid-template-columns: 1fr 1fr 1fr;

And smaller screens get:

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

But that feels wrong. Is there a way to tell my grid layout to repeat up to a maximum of n times, and still use repeat and auto-fit/fill?

Update: This is not a duplicate of: How to limit the amount of columns in larger viewports with CSS Grid and auto-fill/fit?

I am asking how to make the code for the viewport also work for smaller viewports. The question (and answer) referenced above only gets to the starting point of my question.

like image 241
Ted Avatar asked Feb 27 '19 14:02

Ted


People also ask

How do you specify the number of columns in a CSS grid?

To specify the number of columns of the grid and the widths of each column, the CSS property grid-template-columns is used on the grid container. The number of width values determines the number of columns and each width value can be either in pixels( px ) or percentages(%).

What is the syntax for the repeat () function in CSS?

Syntax. The repeat() function takes two arguments: repeat count: the first argument specifies the number of times that the track list should be repeated. It is specified with an integer value of 1 or more, or with the keyword values auto-fill or auto-fit .

What is autofill and autofit?

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 .

How do I use autofill in CSS?

Auto-fill: The auto-fill property fills the rows with as many columns as it can fit. The newly added column may be empty but it will still occupy a space in the given row. It is an important property in the CSS grid that make a responsive layout without writing a media query for each grid.


1 Answers

CSS custom properties ('CSS variables') to the rescue

.grid {
  --repeat: auto-fit;
}
@media (min-width: calc(250px * 3)) {
  .grid {
    --repeat: 3;
  }
}

.grid {
  display: grid;
  grid-template-columns: repeat(var(--repeat, auto-fit), minmax(calc(250px * 1) , 1fr));
  grid-gap: 8px;
}

.grid .item {
  background-color: silver;
  padding: 8px;
}
<div class="grid">
  <div class="item">Lorem, ipsum.</div>
  <div class="item">Soluta, voluptatibus!</div>
  <div class="item">Reprehenderit, consequuntur.</div>
  <div class="item">Temporibus, veritatis!</div>
  <div class="item">Consequatur, voluptates.</div>
  <div class="item">Distinctio, adipisci.</div>
  <div class="item">Repellat, corrupti.</div>
  <div class="item">Quia, corporis.</div>
  <div class="item">Nobis, aut.</div>
  <div class="item">Dicta, officiis?</div>
  <div class="item">Voluptate, tempora?</div>
  <div class="item">Nihil, earum?</div>
  <div class="item">Placeat, aspernatur!</div>
  <div class="item">Officia, sunt?</div>
  <div class="item">Atque, temporibus!</div>
  <div class="item">Rerum, unde!</div>
  <div class="item">Hic, molestias!</div>
  <div class="item">Et, repellat!</div>
  <div class="item">Earum, itaque.</div>
  <div class="item">Doloribus, facilis.</div>
  <div class="item">Eius, alias!</div>
  <div class="item">Est, officia.</div>
  <div class="item">Ad, porro!</div>
  <div class="item">Ipsum, voluptates.</div>
  <div class="item">Animi, eligendi.</div>
  <div class="item">Tempore, hic!</div>
  <div class="item">Voluptatibus, illum.</div>
  <div class="item">Autem, cumque!</div>
  <div class="item">Cupiditate, minus!</div>
  <div class="item">Tenetur, aliquam.</div>
</div>

Remark

The asker wanted in his OP a solution which would not use media queries. This solution does use media queries, but in a somewhat different way. The only thing that is changed in the media query is the value of a CSS custom property.

We could even use a 'global' custom property with the :root selector

:root {
  --repeat: auto-fit;
}
@media (min-width: calc(250 * 3px)) {
  :root {
    --repeat: 3;
  }
}

One could think further and use custom properties in the media query condition itself, but unfortunately this does not work. (See this answer)

/* not working */
:root {
  --repeat: auto-fit;
  --max-columns: 3;
  --max-column-width: 250px;
}
/* Will not work: var is not allowed in media query condition */
@media (min-width: calc(var(--max-column-width) * var(--max-columns))) {
  :root {
    --repeat: var(--max-columns);
  }
}
like image 58
yunzen Avatar answered Sep 28 '22 11:09

yunzen