是否可以定义一个具有最大列数的网格,但是当屏幕宽度改变时允许元素包装到新行上?
我有一些隐含的类,它们允许行包装到新行上,但是没有最大列数。
这是使用flex boxes
的一种方法的代码笔CSS:
.flex-container {
display: flex;
flex-wrap: wrap;
}
另一种方法是使用grid
.grid {
display: grid;
counter-reset: grid-items;
position: relative;
}
.grid--auto-fit {
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
我想要一个相当通用的解决方案,我想在没有Java脚本或媒体查询的情况下实现什么?
答案 0 :(得分:3)
对于 flexbox 或 CSS网格,您不能明确地做到这一点-但您可以使用 hack 使用CSS Variables
(通常这就是您所需要的)。
例如,您可以在:root
中设置全局列号,而在网格包装器上设置特定列号-请参见下面的 CSS网格全局设置了4列:
:root {
--columns: 3;
}
.grid {
display: grid;
grid-gap: 10px;
/* adjusting for the 10px grid-gap as well */
grid-template-columns: repeat(auto-fit, minmax(calc(100% / var(--columns) - 20px), 1fr));
}
.grid > * {
background-color: green;
height: 200px;
}
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
现在,您可以通过重新声明 --columns
来为网格容器上的列数设置规则(也可以让JS添加一个包含class
声明的--columns
)-请参见下面的演示
:root {
--columns: 3;
}
.grid {
display: grid;
grid-gap: 10px;
--columns: 4; /* re-define the number of columns */
grid-template-columns: repeat(auto-fit, minmax(calc(100% / var(--columns) - 20px), 1fr));
}
.grid > * {
background-color: green;
height: 200px;
}
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
Flexbox
类似的参数对 flexboxes 有效-请参见下面的简化演示
:root {
--columns: 3;
}
.flexbox {
display: flex;
flex-wrap: wrap;
--columns: 4; /* re-define the number of columns */
}
.flexbox > * {
background-color: green;
height: 200px;
margin: 10px;
flex-basis: calc(100% / var(--columns) - 20px);
}
<div class="flexbox">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
答案 1 :(得分:3)
使用flexbox,您可以简单地为容器设置max-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
。
如果您希望元素扩展并覆盖所有宽度,可以对min-width
使用以下技巧:
.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变量轻松地使它更加灵活:
.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
,但是您可能会遇到需要修复一些问题的最后一行的问题:
.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。
为了使其更加灵活,以下是有关CSS变量的想法:
.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,这可以减少代码。
如果您将有7列,我们将仅需要6个额外的元素。我们可以使用两个伪元素,然后仅使用2个空元素来覆盖其余4个。
答案 2 :(得分:-1)
通过一些数学运算,您可以在 minmax 内的 max 函数中添加一个百分比。这样它会在 200 像素处中断,但会扩展以填充页面的 1/3(在这种情况下,因为我使用了 33%,不过只需添加您想要的任何百分比)
grid-template-columns: repeat(auto-fit, minmax(max(200px, 33%), 1fr));