【问题标题】:CSS Grid Layout - grid-row-gap every 2 RowsCSS 网格布局 - 每 2 行网格行间隙
【发布时间】:2019-07-05 07:23:24
【问题描述】:

是否可以有一个带有行间距的网格布局,但间距只有每 2 行? 或者每2行有一个边框?

之后我想跨越网格上的元素。放置一个额外的元素,因为线条会破坏网格,我不能重叠已经填充的区域。

示例代码:

body{
  background-color:gray;
}
.grid {
  display: grid;
  grid-template-columns: 1fr;
  grid-row-gap: 5px;
  grid-template-rows: repeat(12,20px);
  border: 1px solid black;
  background-color:lightgray;
}

.grid > div {
  background: lightblue;
  border: 1px solid cadetblue;
}



#element{
  grid-row: 5 / span 3;
}
The lightgrey element should have lines/borders every second grid row
<div class="grid">
  <div id="element">Element</div>
</div>

示例布局:

跨过它的元素:

也欢迎其他解决方案。

【问题讨论】:

    标签: html css css-grid grid-layout


    【解决方案1】:

    要跨越元素,您可以使用 grid-row-startgrid-row-end 属性,例如 -

        .item1 {
          grid-row-start: 3;
          grid-row-end: 6;
          background-color:red;
        }
        
        .grid-container {
      display: grid;
      grid-template-columns: 1fr;
      grid-row-gap: 5px;
      grid-template-rows: repeat(12,20px);
      border: 1px solid black;
    
    }
    <div class="grid-container">
          <div class="item1">1</div>
          <div class="item2">2</div>
          <div class="item3">3</div>  
          <div class="item4">4</div>
          <div class="item5">5</div>
          <div class="item6">6</div>
          <div class="item7">7</div>
          <div class="item8">8</div>  
        </div>

    对于行间距,不要使用grid-row-gap,只需添加边距,如

    .grid > div:nth-child(4n + 1), .grid > div:nth-child(4n + 2) {
        margin-top: 1em;
    }
    
    .grid > div:nth-child(4n + 3), .grid > div:nth-child(4n + 4) {
        margin-bottom: 1em;
    }
    

    而不是添加负边距。它的工作方式相同。 (我个人不喜欢添加负边距,因为它会使布局复杂化,但这是您的选择)

    【讨论】:

    • 是的......现在将@kukkuz 答案与您的答案结合起来;)
    • 是的,你可以这样做。但我正在尝试寻找一种比添加负边距更好的方法来解决行间距问题。会发布如果会找到一些东西:-)
    【解决方案2】:

    要每两行有一个行间距,您可以尝试为网格容器设置grid-row-gap属性,然后使用负边距和一些 nth-child 逻辑 来调整行间距(假设这是一个 2 列布局)。

    这充其量只是一个 hack,无论如何请看下面的演示:

    .grid {
      display: grid;
      grid-template-columns: 1fr 1fr;
      grid-row-gap: 1em;
      grid-auto-rows: 1fr;
      counter-reset: counter;
    }
    
    .grid > div {
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 10px;
      background: lightblue;
      border: 1px solid cadetblue;
    }
    
    .grid > div:before {
      counter-increment: counter;
      content: counter(counter);
    }
    
    .grid > div:nth-child(4n + 1), .grid > div:nth-child(4n + 2) {
      margin-bottom: -0.5em;
    }
    
    .grid > div:nth-child(4n + 3), .grid > div:nth-child(4n + 4) {
      margin-top: -0.5em;
    }
    <div class="grid">
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
    </div>

    【讨论】:

    • 这是我问题第一部分的解决方案,但没有解决我的第二个问题。 codepen.io/anon/pen/WqKxZR
    • @JanneckLange 此解决方案不解决第二个问题,因为 spanning rows 破坏了 nth-child-negative-margin 逻辑
    【解决方案3】:

    是的,但是通过定义一个grid-auto-rows 结构来匹配所需的额外“间隙”。

    这是没有语义的,因为我们使用元素只是为了样式和间距。

    body {
      background-color: gray;
    }
    
    .grid {
      display: grid;
      grid-template-columns: 1fr 1fr;
      grid-gap: 5px;
      grid-auto-rows: 20px 20px 5px;
      border: 1px solid black;
      background-color: lightgray;
    }
    
    .grid>div {
      border: 1px solid cadetblue;
      background: lightblue;
    }
    
    .item.red {
      background: red;
      grid-column: span 2;
    }
    
    .item.spanner {
      grid-row: span 3;
      background: orange;
    }
    <div class="grid">
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
      <div class="item red"></div>
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
      <div class="item red"></div>
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
      <div class="item spanner"></div>
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
    </div>

    【讨论】:

      【解决方案4】:

      我有一个解决方案。将 hr 元素放置在绝对位置,并使它们变大以流过一切。 z-index 将把这条线放在我的元素下面。

      body{
        background-color:gray;
      }
      
      .grid {
        display: grid;
        grid-template-columns: 0.1fr 1fr 0.1fr;
        grid-gap: 5px;
        grid-template-rows: repeat(18, 15px);
        border: 1px solid black;
        background-color:lightgray;
      }
      
      #element{
        grid-column:2;
        grid-row: 3 / span 6;
        background-color:green;
        z-index:3;
        margin: 5px;
      }
      
      .H1{
        grid-column:1;
        grid-row: 1;
      }
      .H2{
        grid-column:1;
        grid-row: 7;
      }
      
      .H3{
        grid-column:1;
        grid-row: 13;
      }
      
      .Hr{
        position: absolute;
        background-color: black;
        height: 2px;
        width:100%;
      }
      
      .Vr{
          position: absolute;
        background-color: black;
        width: 2px;
        height:100%;
      }
      
      .V1{
          grid-column:1;
        grid-row: 1;
      }
      
      .V1{
          grid-column:3;
        grid-row: 1;
      }
      <div class="grid">
        <div class="H1"><hr class="Hr" /></div>
        <div class="H2"><hr class="Hr"/></div>
        <div class="H3"><hr class="Hr"/></div>
        <div class="V1"><hr class="Vr" /></div>
        <div class="V2"><hr class="Vr" /></div>
        <div id="element">Element</div>
      </div>

      【讨论】:

      • 所以它只是关于视觉效果?如果是这样,我有一个更简单的解决方案,没有额外的元素
      【解决方案5】:

       
      
      <head>
             <meta charset="utf-8">
             <meta name="viewport" content="width=device-width, initial-scale=1">
             <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
             <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
             <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
             <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
      </head>
      <body>
        <div class="row mb-5 table-bordered">
          <div class="col-12">
            <div class="row">
              <div class="col-6">1</div>
              <div class="col-6">2</div>
            </div>
            <div class="row">
              <div class="col-6">3</div>
              <div class="col-6">4</div>
            </div>
          </div>
        </div>
        <div class="row table-bordered">
          <div class="col-12">
            <div class="row">
              <div class="col-6">A</div>
              <div class="col-6">B</div>
            </div>
            <div class="row">
              <div class="col-6">C</div>
              <div class="col-6">D</div>
            </div>
          </div>
        </div>
      </body>

      【讨论】: