没有媒体查询的CSS网格最大列

Ben*_*len 9 html css css3 flexbox css-grid

是否可以定义一个最大列数的网格,但是当屏幕宽度改变时允许元素包装到新行上?

我有隐式类,允许行包装到新行上,但是没有最大列数。

这是使用弹性盒的一种方法的代码笔

CSS:

.flex-container {
  display: flex;
  flex-wrap: wrap;
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用网格

.grid {
  display: grid;
  counter-reset: grid-items;
  position: relative;
}


.grid--auto-fit {
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
Run Code Online (Sandbox Code Playgroud)

我想要一个相当通用的解决方案,没有Java脚本或媒体查询,我想实现的目标是否可能?

Tem*_*fif 12

使用 CSS 网格,您可以考虑使用max(width,100%/N)whereN是最大列数。如果容器的宽度增加,100%/N肯定会大于,width因此N每行不会有多个元素。

.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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

有间隙:

.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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


使用 flexbox,您可以简单地将 a 设置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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

唯一的缺点是您需要知道元素的宽度及其边距才能正确设置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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

在这里,您还需要考虑边距,您可以使用 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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

您还可以考虑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);
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

在下面的示例中,我们将列数设为 5,因此我们将需要至少 4 个空元素来解决问题,以防我们在最后一行中有 1 到 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*/
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

我曾经display:contents可以设置 N 个空元素,这些元素以后会被认为是 2*N,这样可以减少代码。

如果你有 7 列,我们只需要 6 个额外的元素。我们可以使用两个伪元素然后只用 2 个空元素来覆盖剩下的 4 个。