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

纵然是瞬间 提交于 2019-12-12 08:43:59

问题


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.


回答1:


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

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

.grid {
  display: grid;
  grid-template-columns: repeat(var(--repeat, auto-fit), minmax(calc(250 * 1px) , 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.

/* 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);
  }
}



回答2:


I think you will have better luck considering flexbox in this case:

.container {
  display: flex;
  flex-wrap: wrap;
}

.container span {
  height: 50px;
  flex-basis: 30%; /*will define 3 columns*/
  flex-grow: 1; /*this will behave as 1fr*/
  margin: 5px;
  min-width: 250px; /*set a min-width to simulate auto-fit*/
  background: red;
}

/*to fix the last row and avoid having bigger element than previous rows*/
.container:before,
.container:after {
  content:"";
  order:2;
  height: 1px;
  margin: 5px;
  flex-grow: 1;
  flex-basis: 30%;
  min-width: 250px;
}
<div class="container">
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>



回答3:


Just add a max-width to the container.

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


来源:https://stackoverflow.com/questions/54907270/how-to-specify-the-maximum-number-of-columns-repeat-will-create-using-auto-fit

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!