【问题标题】:How do I make a responsive grid with a checkered pattern?如何制作带有方格图案的响应式网格?
【发布时间】:2019-08-19 06:14:25
【问题描述】:

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

我正在尝试使网格具有方格图案,因此我使用 oddeven 选择器为网格单元格着色。

但它只在列数为奇数时有效。当列数为偶数时,变为条纹图案。

是否有 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>

【问题讨论】:

  • 如果没有 JavaScript,这将是不可能的。你每秒都在着色 span 并且想知道你这样做了。
  • 那么“偶数”变体应该是什么样的?如果它应该是方格的,那么必须有 2 个相互连接的浅灰色单元格,所以每一行都必须以不同的模式开始?
  • 这是一个简单的数学,我猜用 evens 是不可能的
  • @empiric 似乎是这样,偶数变体应该像0101, 1010, 0101, 1010,每4个和第5个项目具有相同的颜色。这就是为什么它很复杂,不能简单地用oddeven 解决。希望有一个选择器来做这样的工作。
  • @AbhishekPandey 如果您有兴趣,我添加了一个 idea 解决方案

标签: html css css-grid


【解决方案1】:

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

.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>

<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>

如果您希望间隙具有透明度,可以考虑使用渐变定义的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 我们不需要额外的层

.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:destination-in;
    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>

<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>

【讨论】:

  • 该死的,这比我想象的要复杂得多,但它确实有效!虽然我也想为不同的检查器更改其他属性(colorborder 等),但现在看来仅通过 css 还不能轻松完成。非常感谢您提供此解决方案!你有我的尊重。
  • @HaoWu 如果您还想为文本和边框等着色,我们可以使代码更复杂,但它会变得比实际的更复杂 :) 我可以稍后尝试添加它,如果你想要
  • 也许我应该使用 [col="4"]:nth-child(4n), [col="4"]:nth-child(4n+1) 之类的东西。但是需要为每个偶数分配:/ 最好使用 scss 循环
  • @HaoWu 是的,你可以这样做,你会有很多选择器,但如果最大列数不大,我想应该没问题
  • @AbhishekPandey 是的,想确保没有人会错过颜色;)
猜你喜欢
  • 1970-01-01
  • 2020-07-25
  • 2016-12-23
  • 1970-01-01
  • 2014-08-17
  • 1970-01-01
  • 2020-11-14
  • 2019-11-11
  • 2022-01-22
相关资源
最近更新 更多