CSS网格的最大列数(无媒体查询) [英] CSS grid maximum number of columns without media queries
问题描述
是否可以定义一个最大列数的网格,但是当屏幕宽度改变时允许元素包装到新行上?
Is it possible to define a grid with a maximum number of columns but allow elements to wrap onto new rows when the screen width changes?
我有隐式类,它们允许行包装到新行上,但是没有最大列数.
I have implimented classes that allow rows to wrap onto new rows, but there is no maximum number of columns.
这是使用柔韧性盒
CSS:
.flex-container {
display: flex;
flex-wrap: wrap;
}
另一种方法是使用网格
.grid {
display: grid;
counter-reset: grid-items;
position: relative;
}
.grid--auto-fit {
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
我想要一个相当通用的解决方案,我想在没有Java脚本或媒体查询的情况下实现什么?
I want a fairly generic solution to this, is what I want to achieve possible without Javascript or media queries?
推荐答案
使用CSS网格,您可以考虑使用max(width,100%/N)
,其中N
是最大列数.如果容器的宽度增加,则100%/N
肯定会大于width
,因此每行元素数不会超过N
.
With CSS grid you can consider the use of max(width,100%/N)
where N
is the maximum number of columns. If the width of container increase, 100%/N
will for sure be bigger than width
thus we won't have more than N
elements per row.
.grid-container {
--n:4; /* the max number of columns */
display: grid;
grid-template-columns:repeat(auto-fill,minmax(max(200px,100%/var(--n)),1fr));
}
.grid-item {
background: tomato;
padding: 5px;
height: 50px;
margin: 10px;
line-height: 50px;
color: white;
font-weight: bold;
font-size: 2em;
text-align: center;
box-sizing:border-box;
}
<div class="grid-container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
<div class="grid-item">7</div>
<div class="grid-item">8</div>
</div>
<div class="grid-container" style="--n:3">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
<div class="grid-item">7</div>
<div class="grid-item">8</div>
</div>
有差距:
.grid-container {
--n:4; /* the max number of columns */
display: grid;
grid-template-columns:repeat(auto-fill,
minmax(max(200px,(100% - (var(--n) - 1)*10px)/var(--n)),1fr));
gap:10px;
margin:5px;
}
.grid-item {
background: tomato;
padding: 5px;
height: 50px;
line-height: 50px;
color: white;
font-weight: bold;
font-size: 2em;
text-align: center;
box-sizing:border-box;
}
<div class="grid-container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
<div class="grid-item">7</div>
<div class="grid-item">8</div>
</div>
<div class="grid-container" style="--n:3">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
<div class="grid-item">7</div>
<div class="grid-item">8</div>
</div>
使用flexbox,您可以简单地为容器设置max-width
,因为您的元素具有固定的宽度:
With flexbox, you can simply set a max-width
to the container since your elements have a fixed width:
.flex-container {
display: flex;
flex-wrap: wrap;
max-width:calc(5*(200px + 20px));
}
.flex-item {
background: tomato;
padding: 5px;
width: 200px;
height: 100px;
margin: 10px;
line-height: 100px;
color: white;
font-weight: bold;
font-size: 2em;
text-align: center;
box-sizing:border-box;
}
<div class="flex-container wrap">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
</div>
唯一的缺点是您需要知道元素的宽度及其边距,才能正确设置max-width
.
The only drawback is that you need to know the width of your elements and their margin to correctly set the max-width
.
如果您希望元素扩展并覆盖所有宽度,可以对min-width
使用技巧,如下所示:
If you want your elements to expand and cover all the width, you can use a trick with min-width
like below:
.flex-container {
display: flex;
flex-wrap: wrap;
}
.flex-item {
background: tomato;
padding: 5px;
min-width: 200px;
width:calc(100%/5 - 20px); /*5 columns*/
height: 100px;
margin: 10px;
line-height: 100px;
color: white;
font-weight: bold;
font-size: 2em;
text-align: center;
box-sizing:border-box;
}
<div class="flex-container wrap">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
</div>
这里您还需要考虑边距,您可以使用CSS变量轻松地使它更加灵活:
Here also you need to consider the margin, You can easily make this more flexible using CSS variable:
.flex-container {
display: flex;
flex-wrap: wrap;
}
.flex-item {
--m:10px;
background: tomato;
padding: 5px;
min-width: 200px;
width:calc(100%/5 - 2*var(--m)); /*5 columns*/
height: 100px;
margin: var(--m);
line-height: 100px;
color: white;
font-weight: bold;
font-size: 2em;
text-align: center;
box-sizing:border-box;
}
<div class="flex-container wrap">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
</div>
如果您希望元素始终扩展(即使有换行),也可以考虑使用flex-grow
,但是您可能会遇到需要修复一些问题的最后一行的问题:
You can also consider flex-grow
if you want your element to always expand (even when there is a wrap) but you may face the issue of the last row that you need to fix with some hacks:
.flex-container {
display: flex;
flex-wrap: wrap;
--m:10px;
}
.flex-item {
background: tomato;
padding: 5px;
min-width: 200px;
flex-grow:1;
width:calc(100%/5 - 2*var(--m)); /*5 columns*/
height: 100px;
margin: var(--m);
line-height: 100px;
color: white;
font-weight: bold;
font-size: 2em;
text-align: center;
box-sizing:border-box;
}
.flex-container span {
min-width: 200px;
flex-grow:1;
width:calc(100%/5 - 2*var(--m)); /*5 columns*/
margin:0 var(--m);
}
<div class="flex-container wrap">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
<!-- 4 empty elements to fix the issue (we can also use pseudo element) -->
<span></span>
<span></span>
<span></span>
<span></span>
</div>
在下面的示例中,我们将列数设置为5,因此,如果在最后一行中有1-4个元素,则至少需要4个空元素才能解决此问题.当然,这是一个缺点,但是由于您知道列数,因此可以轻松设置这些空元素,并且不需要任何JS.
In the example below we made the number of columns to be 5 so we will need at least 4 empty element to fix the issue in case we will have one to 4 elements in the last row. Of course, this is a drawback but since you know the number of columns you can easily set those empty elements and you won't need any JS.
为了使其更加灵活,下面是一个关于CSS变量的想法:
To make it more flexible, here is an idea with CSS variables:
.flex-container {
display: flex;
flex-wrap: wrap;
border:1px solid;
--m:10px;
--n:5;
--width:150px;
}
.flex-item {
background: tomato;
min-width: var(--width);
flex-grow:1;
width:calc(100%/var(--n) - 2*var(--m));
height: 50px;
margin: var(--m);
box-sizing:border-box;
}
.flex-container span {
display:contents; /* each span will give us 2 elements*/
}
.flex-container span:before,
.flex-container span:after,
.flex-container:before,
.flex-container:after{
content:"";
min-width: var(--width);
flex-grow:1;
width:calc(100%/var(--n) - 2*var(--m));
margin:0 var(--m);
order:1; /*we make sure they are at the end*/
}
<div class="flex-container wrap">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
<!-- a lot of elements !! -->
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<div class="flex-container wrap" style="--n:10">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
<!-- a lot of elements !! -->
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<div class="flex-container wrap" style="--n:3">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
<!-- a lot of elements !! -->
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
我使用display:contents
能够设置N个空元素,以后将其视为2 * N,这可以减少代码.
I used display:contents
to be able to set N empty elements that will later be considered as 2*N which can reduce the code.
如果您将有7列,我们将仅需要6个额外的元素.我们可以使用两个伪元素,然后仅使用2个空元素来覆盖其余的4个.
If you will have 7 columns, we will only need 6 extra elements. We can use the two pseudo elements then only 2 empty element to cover the remaining 4.
这篇关于CSS网格的最大列数(无媒体查询)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!