问题
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