【问题标题】:How to make the items in the last row consume remaining space in CSS Grid?如何使最后一行中的项目占用 CSS Grid 中的剩余空间?
【发布时间】:2019-06-19 14:46:40
【问题描述】:

有没有办法强制网格最后一行中的所有项目填充该行,无论它们有多少?

我不知道网格中的项目数量,因此我无法直接定位它们。我尝试使用grid-auto-flow: dense,但它并没有真正的帮助。

这是我的问题形象化:

div {
  margin:20px auto;
  width: 400px;
  background: #d8d8d8;
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(3, 1fr);
}
span {
  height: 50px;
  background: blue;
}
<div>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>  
</div>
 

【问题讨论】:

  • @IvanS95 哦,对不起!我的错 :) 那他就得用桌子了????
  • @Ahtisham 也不推荐用户表,这种特殊的布局可能会更好地使用 Flexbox,因为 OP 可以使最后一项使用剩余空间
  • @IvanS95 创建两个 div 怎么样。并保持第一个 div 的宽度固定,然后保持动态。 ☺️
  • @Ahtisham 这可能比仅仅使用 flexbox 更有效
  • 我会推荐你​​使用 flexbox。

标签: css grid-layout css-grid


【解决方案1】:

我找到了你的问题的答案,我在这里复制了它: https://jsfiddle.net/nmcobalt/dg3mutwv/13/

为了减少css的复杂性并解决这个复杂的问题,建议使用SCSS*而不是普通的css。

在 SCSS 文件中,您必须使用 css 选择器 nth:last-child 并根据模函数和 3 列的常数因子进行迭代计算子代。

@mixin setLastChildFluid{
  @for $i from 1 through 10 {    
    $span: 3;
    @if $i % 3 == 0{
      $span: 1;
    } @else if $i % 3 == 1{
      $span: 3;
    } @else if $i % 3 == 2{
      $span: 2;
    } 
    @if $span == 2 {
      span:nth-child(#{$i - 1}){
        &:nth-last-child(2){
          grid-column-end:span 1;
          position:relative;
          bottom:0;
          width:calc(150% + 5px);
          left:0;    
        }
      }
      span:nth-child(#{$i}){
        &:nth-last-child(1){
          grid-column-start:2;
          position:relative;
          bottom:0;
          width:calc(150% + 5px);
          left:calc(50% + 5px);
        }
      }
      
    } @else {
      span:nth-child(#{$i}){
        &:last-child{
            grid-column-end:span #{$span};          
        }
      }
    }
    
  }
}
div {
  position:relative;
  margin:20px auto;
  width: 400px;
  background: #d8d8d8;
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(3, 1fr);
  
  @include setLastChildFluid;
}
span {
  height: 50px;
  background: blue;
  color:yellow;
}

和下面的 html 标记;我已经做了两个不同的示例(由 div 包装)来重现您的查询:

<div>
  <span>1</span>
  <span>2</span>
  <span>3</span>
  <span>4</span>
  <span>5</span>
  <span>6</span>
  <span>7</span>
  <span>8</span>
</div>
<div>
  <span>1</span>
  <span>2</span>
  <span>3</span>
  <span>4</span>
  <span>5</span>
  <span>6</span>
  <span>7</span>
</div>

更改 div 的数量以查看流畅的结果。

*SASS 是一种预处理器脚本语言,它被解释或编译成级联样式表 (CSS)。在此处了解更多信息:https://sass-lang.com/guide

【讨论】:

  • 是的,我知道,但是使用 scss 在非常复杂的事情中变得简单得多。您可以随时使用在线工具将 scss 转换为 css。
  • 我不得不承认它以复杂的方式更简单。但只是说他并没有真正询问scss,他可能不知道scss是什么。您至少应该解释一下 scss 以使其更方便,然后再搜索答案。
【解决方案2】:

通过结合 CSS 规则 nth-child 和 nth-last-of-type,这完全可以通过 CSS 网格实现。唯一需要注意的是,需要提前知道列数。

.grid {
    display: grid;
    grid-template-columns: auto auto auto;
    justify-items: start;
    grid-gap: 10px;
}

.grid div {
  border: 1px solid #ccc;
  width: 100%;
}

.grid > *:nth-child(3n-1) {
  justify-self: center;
  text-align: center;
}

.grid > *:nth-child(3n) {
  justify-self: end;
  text-align: right;
}

.grid > *:nth-child(3n-1):nth-last-of-type(1) {
  border-color: red;
  grid-column: span 2;
}

.grid > *:nth-child(3n-2):nth-last-of-type(1) {
  border-color: red;
  grid-column: span 3;
}
<div class="grid">
  <div>text</div>
  <div>TEXT</div>
  <div>text</div>
  <div>text</div>
  <div>TEXT</div>
  <div>text</div>
  <div>text</div>
  <div>TEXT</div>
</div>

【讨论】:

  • 感谢您的回答。仅当我们知道每行有 3 列时,您的解决方案才有效,并且假设我们有 6 列,那么我们必须通过定位 nth-child(6n-5) 来定义跨度 5 次,所以第四次。
  • 是的,如前所述,但是当您知道列数时它完全有效,所以我相信这是您问题的答案。您也可以使用 scss 来计算这些条目,如果列会有所不同,例如当您使用媒体查询时。
  • 抱歉造成误会,再次感谢您花时间回答问题,但这不是答案 :) 如果您请阅读原帖,我没有提到我们知道列数,如果这是您假设的,那么我可以声明它不是预定义的值,我们不知道列数。更清楚地说,这是我们在电子商务平台上制作的模板,我们使用了 Flex(同时),但整个想法是 CSS 不依赖于列数,至少不依赖于列数您的回答所陈述的范围。
  • 您的 css 显示“grid-template-columns: repeat(3, 1fr)”,您的要求是如何让项目填满剩余空间,无论有多少项目。我这样回答。如果您需要进一步询问有关如何在不知道有多少列的情况下执行此操作的问题,请这样做。
  • 我真的不是在争论,我真的很感谢你的回答,但这不是我问题的正确答案,很抱歉!
【解决方案3】:

这在current version (Level 1) of CSS Grid 中是不可能的。但是,使用 flexbox 并不太复杂。

你在评论中写道:

我正在使用 Flexbox 作为后备。我研究网格的一个(不是唯一的)原因是使用“间隙”和它附带的其他功能。例如,尽管间隙可以通过边距模拟,但由于我们不知道最后一行中的项目数,因此消除侧间隙(在容器的一侧)将需要额外的代码。

你说得对:CSS Grid 中的grip-gap 功能非常方便。但是,您也可以在 flexbox 中使用边距来模拟这种行为,而无需太多复杂性。

div {
  display: flex;
  flex-wrap: wrap;
  padding: 0px 0px 5px 5px;
  margin: 20px auto;
  width: 400px;
  background: #d8d8d8;

  }
span {
  flex: 1 0 30%;
  height: 50px;
  margin-top: 5px;
  margin-right: 5px;
  background: blue;
}
<div>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

<div>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

<div>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

<div>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

<div>
  <span></span>
  <span></span>
  <span></span>
</div>

<div>
  <span></span>
  <span></span>
</div>

<div>
  <span></span>
</div>

【讨论】:

    【解决方案4】:

    我不认为 CSS Grid 是您尝试构建的布局的最佳选择,至少如果它是动态的并且您真的不知道容器上将有多少项目时间。 Flexbox 实际上更适合一维布局;将所有内容保持完全相同的大小并完全根据需要使用所有可用空间可能会有点困难,但最终这种类型的情况就是为 Flexbox 构建的。

    当然,您也可以通过对 CSS 进行少量计算来利用 100% 宽度。

    CSS Grid 可能更好地保持行和列对齐,但情况不同。

    .container {
      display: flex;
      flex-wrap: wrap;
      box-sizing: border-box;
    }
    
    .flex-item {
      width: 30%;
      border: 1px solid #000;
      flex-grow: 1;
      min-height: 120px;
      box-sizing: border-box;
      margin: 0 5px 10px;
      justify-content: space-between;
      text-align: center;
    }
    <div class="container">
      <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>

    【讨论】:

    • 感谢您的回答。我正在使用 Flexbox 作为后备。我研究网格的一个(不是唯一)原因是使用“间隙”和它附带的其他功能。例如,尽管间隙可以通过边距模拟,但由于我们不知道最后一行中的项目数,因此消除侧间隙(在容器的一侧)将需要额外的代码。
    • @Ogdila 没问题!不幸的是,目前看来这是不可能的;我实际上刚刚发现这个问题与同样的问题,看起来 CSS Grid 无法实现这个stackoverflow.com/q/53394402/8437694
    • 根据规格,您可以说例如gap: 0.25rem 也适用于 Flexbox。不幸的是,只有 Firefox 和最近的 Chrome 对此有适当的支持。 Safari 仍然(2021 年第一季度)不支持此功能:caniuse.com/flexbox-gap
    • @MikkoRantalainen 这很酷,希望它得到更广泛的采用,对这样的设计有很大帮助
    • 好消息,Safari 14.1 在 flexbox 上支持 gap。现在只需要等待旧版本消失!
    猜你喜欢
    • 2019-04-22
    • 2018-01-29
    • 1970-01-01
    • 2020-06-14
    • 1970-01-01
    • 2021-11-04
    • 2013-02-22
    • 1970-01-01
    相关资源
    最近更新 更多