代码之家  ›  专栏  ›  技术社区  ›  Hao Wu

如何使响应网格具有方格图案?

  •  0
  • Hao Wu  · 技术社区  · 5 年前

    我有一个响应的网格布局。根据窗口宽度,可以有任意数量的列。

    我试图使网格有一个方格图案,所以我使用 odd even 为网格单元格上色的选择器。

    但它只在列数为奇数时才起作用。当列数为偶数时,它将成为条带模式。

    有没有css属性/选择器来解决这个问题,或者有更好的方法来解决这个问题?

    以下是我的项目的简化代码,显示了问题:

    .grid {
      display: grid;
      counter-reset: spans;
      grid-template-columns: repeat(var(--cols), 1fr);
      grid-gap: 1px;
    }
    
    .grid > * {
      counter-increment: spans;
      text-align: center;
      padding: 10px 0;
      color: #fff;
    }
    
    .grid > *::after {
      content: counter(spans);
    }
    
    /* Coloring */
    .grid > *:nth-child(odd) {
      background-color: #789;
    }
    
    .grid > *:not(:nth-child(odd)) {
      background-color: #567;
    }
    <h2>Works when columns are odd</h2>
    <div class="grid" style="--cols: 5;">
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
    </div>
    
    <h2>Doesn't work while even</h2>
    <div class="grid" style="--cols: 4;">
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
    </div>
    0 回复  |  直到 5 年前
        1
  •  3
  •   Temani Afif    5 年前

    如果知道行数或至少知道它们的最大值,则可以使用渐变和多个背景轻松实现此目的。唯一的缺点是,着色将在容器上,因此您可以让空单元格也着色。

    .grid {
      display: grid;
      margin:10px 0;
      counter-reset: spans;
      grid-template-columns: repeat(var(--cols), 1fr);
      grid-auto-rows: 40px;
      --grad:repeating-linear-gradient(to right,red 0 calc(50% / var(--cols)),blue calc(50% / var(--cols))  calc(100% / var(--cols)));
      background:
        var(--grad),
        var(--grad),
        var(--grad),
        var(--grad),
        var(--grad);
      background-size:200% 40px;
      background-position: 
        0                        calc(0*40px),
        calc(100% / var(--cols)) calc(1*40px),
        0                        calc(2*40px),
        calc(100% / var(--cols)) calc(3*40px),
        0                        calc(4*40px);
      background-repeat:no-repeat;
    }
    
    .grid > * {
      counter-increment: spans;
      text-align: center;
      padding: 10px 0;
      color: #fff;
    }
    
    .grid > *::after {
      content: counter(spans);
    }
    <div class="grid" style="--cols: 5;">
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
    </div>
    
    <div class="grid" style="--cols: 4;">
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
    </div>
    
    <div class="grid" style="--cols: 8;">
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
    </div>

    为了避免空单元格的着色,我们可以考虑使用伪元素但没有透明度的黑客:

    .grid {
      display: grid;
      counter-reset: spans;
      margin:10px 0;
      grid-template-columns: repeat(var(--cols), 1fr);
      grid-auto-rows: 40px;
      --grad:repeating-linear-gradient(to right,red 0 calc(50% / var(--cols)),blue calc(50% / var(--cols))  calc(100% / var(--cols)));
      background:
        var(--grad),
        var(--grad),
        var(--grad),
        var(--grad),
        var(--grad);
      background-size:200% 40px;
      background-position: 
        0                        calc(0*40px),
        calc(100% / var(--cols)) calc(1*40px),
        0                        calc(2*40px),
        calc(100% / var(--cols)) calc(3*40px),
        0                        calc(4*40px);
      background-repeat:no-repeat;
      overflow:hidden;
    }
    
    .grid > * {
      counter-increment: spans;
      text-align: center;
      padding: 10px 0;
      color: #fff;
      position:relative;
    }
    
    .grid > *::after {
      content: counter(spans);
    }
    .grid > *:last-child::before {
      content:"";
      position:absolute;
      top:0;
      bottom:0;
      left:100%;
      width:100vw;
      background:#fff;
    }
    <div class="grid" style="--cols: 5;">
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
    </div>
    
    <div class="grid" style="--cols: 4;">
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
    </div>
    
    <div class="grid" style="--cols: 8;">
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
    </div>

    模拟可以考虑的间隙 outline 在网格项上(仍然没有透明度):

    .grid {
      display: grid;
      counter-reset: spans;
      margin:10px 0;
      grid-template-columns: repeat(var(--cols), 1fr);
      grid-auto-rows: 40px;
      --grad:repeating-linear-gradient(to right,red 0 calc(50% / var(--cols)),blue calc(50% / var(--cols))  calc(100% / var(--cols)));
      background:
        var(--grad),
        var(--grad),
        var(--grad),
        var(--grad),
        var(--grad);
      background-size:200% 40px;
      background-position: 
        0                        calc(0*40px),
        calc(100% / var(--cols)) calc(1*40px),
        0                        calc(2*40px),
        calc(100% / var(--cols)) calc(3*40px),
        0                        calc(4*40px);
      background-repeat:no-repeat;
      overflow:hidden;
    }
    
    .grid > * {
      counter-increment: spans;
      text-align: center;
      padding: 10px 0;
      color: #fff;
      position:relative;
      outline:1px solid #fff;
    }
    
    .grid > *::after {
      content: counter(spans);
    }
    .grid > *:last-child::before {
      content:"";
      position:absolute;
      top:0;
      bottom:0;
      left:100%;
      width:100vw;
      background:#fff;
    }
    <div class=“grid”style=”--cols:5;“>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    </分区>
    
    <div class=“grid”style=”--cols:4;“>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    </分区>
    
    <div class=“grid”style=”--cols:8;“>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    </分区>

    如果你想有透明度的差距,你可以考虑 mask 你用梯度定义的。您需要一个额外的包装:

    .grid {
      display: grid;
      counter-reset: spans;
      grid-template-columns: repeat(var(--cols), 1fr);
      grid-auto-rows: 40px;
      --grad:repeating-linear-gradient(to right,red 0 calc(50% / var(--cols)),blue calc(50% / var(--cols))  calc(100% / var(--cols)));
      background:
        var(--grad),
        var(--grad),
        var(--grad),
        var(--grad),
        var(--grad);
      background-size:200% 40px;
      background-position: 
        0                        calc(0*40px),
        calc(100% / var(--cols)) calc(1*40px),
        0                        calc(2*40px),
        calc(100% / var(--cols)) calc(3*40px),
        0                        calc(4*40px);
      background-repeat:no-repeat;
      -webkit-mask:
        repeating-linear-gradient(to right,
          transparent 0 1px,#fff 1px calc(100% / var(--cols) - 1px),
          transparent calc(100% / var(--cols) - 1px) calc(100% / var(--cols)))
        center/calc(100% + 2px) 100%;  
      mask:
        repeating-linear-gradient(to right,
          transparent 0 1px,#fff 1px calc(100% / var(--cols) - 1px),
          transparent calc(100% / var(--cols) - 1px) calc(100% / var(--cols)))
        center/calc(100% + 2px) 100%;  
    }
    .wrapper {
      margin:30px 0;
      -webkit-mask:repeating-linear-gradient(to bottom,
          transparent 0 1px,#fff 1px calc(40px - 1px),
          transparent calc(40px - 1px) 40px)
        center/100% calc(100% + 2px);
      mask:repeating-linear-gradient(to bottom,
          transparent 0 1px,#fff 1px calc(40px - 1px),
          transparent calc(40px - 1px) 40px)
        center/100% calc(100% + 2px);
    }
    
    .grid > * {
      counter-increment: spans;
      text-align: center;
      padding: 10px 0;
      color: #fff;
      position:relative;
    }
    
    .grid > *::after {
      content: counter(spans);
    }
    
    
    body {
      background:yellow;
    }
    <div class="wrapper">
    <div class="grid" style="--cols: 5;">
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
    </div>
    </div>
    
    <div class="wrapper">
    <div class="grid" style="--cols: 4;">
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
    </div>
    </div>
    
    <div class="wrapper">
    <div class="grid" style="--cols: 8;">
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
    </div>
    
    </div>

    使用 mask-composite 以及 ìntersect 值,我们不需要额外的层,但实际上它只适用于Firefox:

    .grid {
      display: grid;
      counter-reset: spans;
      margin:30px 0;
      grid-template-columns: repeat(var(--cols), 1fr);
      grid-auto-rows: 40px;
      --grad:repeating-linear-gradient(to right,red 0 calc(50% / var(--cols)),blue calc(50% / var(--cols))  calc(100% / var(--cols)));
      background:
        var(--grad),
        var(--grad),
        var(--grad),
        var(--grad),
        var(--grad);
      background-size:200% 40px;
      background-position: 
        0                        calc(0*40px),
        calc(100% / var(--cols)) calc(1*40px),
        0                        calc(2*40px),
        calc(100% / var(--cols)) calc(3*40px),
        0                        calc(4*40px);
      background-repeat:no-repeat;
      -webkit-mask:
        repeating-linear-gradient(to right,
          transparent 0 1px,#fff 1px calc(100% / var(--cols) - 1px),
          transparent calc(100% / var(--cols) - 1px) calc(100% / var(--cols)))
        center/calc(100% + 2px) 100%,
        repeating-linear-gradient(to bottom,
          transparent 0 1px,#fff 1px calc(40px - 1px),
          transparent calc(40px - 1px) 40px)
        center/100% calc(100% + 2px);  
      mask:
        repeating-linear-gradient(to right,
          transparent 0 1px,#fff 1px calc(100% / var(--cols) - 1px),
          transparent calc(100% / var(--cols) - 1px) calc(100% / var(--cols)))
        center/calc(100% + 2px) 100%,
        repeating-linear-gradient(to bottom,
          transparent 0 1px,#fff 1px calc(40px - 1px),
          transparent calc(40px - 1px) 40px)
        center/100% calc(100% + 2px);  
        
        -webkit-mask-composite:intersect;
        mask-composite:intersect;
    }
    
    
    .grid > * {
      counter-increment: spans;
      text-align: center;
      padding: 10px 0;
      color: #fff;
      position:relative;
    }
    
    .grid > *::after {
      content: counter(spans);
    }
    
    
    body {
      background:yellow;
    }
    <div class=“grid”style=”--cols:5;“>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    </分区>
    
    <div class=“grid”style=”--cols:4;“>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    </分区>
    
    <div class=“grid”style=”--cols:8;“>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    <SPAN></SPAN>
    </分区>