有条件地设置网格容器中选定元素的样式 PlatoBlockchain 数据智能。垂直搜索。人工智能。

有条件地为网格容器中的选定元素设置样式

日历、购物车、画廊、文件浏览器和在线图书馆是可选项目以网格(即方格子)显示的一些情况。你知道,即使是那些安全检查也会要求你选择所有带有人行横道或其他东西的图​​像。

有条件地设置网格容器中选定元素的样式 PlatoBlockchain 数据智能。垂直搜索。人工智能。
????

我找到了一种在网格中显示可选选项的巧妙方法。不,不是重新创建 reCAPTCHA,而是简单地能够选择多个项目。当选择两个或多个相邻项目时,我们可以使用巧妙的方法 :nth-of-type 组合器、伪元素和 :checked 伪类,以让它们看起来组合在一起的方式设置它们的样式。

CodePen 嵌入后备

组合器和伪类获得圆形复选框的整个想法来自 我写的上一篇文章。这是一个简单的单列设计:

CodePen 嵌入后备

然而,这一次,舍入效果应用于网格上垂直轴和水平轴上的元素。您不必为此阅读我上一篇关于复选框样式的文章,因为我将在这里介绍您需要了解的所有内容。但如果您对我们在本文中所做的事情感兴趣,那么这篇文章值得一看。

在我们开始之前……

记下一些事情会对您很有用。例如,为了简单起见,我在演示中使用静态 HTML 和 CSS。根据您的应用程序,您可能必须动态生成网格及其中的项目。为了专注于效果,我省略了对可访问性的实际检查,但您肯定希望在生产环境中考虑此类事情。

另外,我使用 CSS 网格进行布局。我也推荐同样的方法,但当然,这只是个人喜好,您的里程可能会有所不同。对我来说,使用网格可以让我轻松地使用同级选择器来定位项目的 ::before::after 伪。

因此,无论您想在应用程序中使用什么布局标准,请确保伪元素仍然可以在 CSS 中定位,并确保布局在不同的浏览器和屏幕上保持不变。

立马开始吧!!

正如您在前面的演示中可能已经注意到的,选中和取消选中复选框元素会修改框的设计,具体取决于其周围其他复选框的选择状态。这是可能的,因为我使用其相邻元素的伪元素而不是其自己的元素来设置每个框的样式。

下图显示了如何 ::before 每个盒子的伪元素 (第一列除外)将左侧的框重叠,以及如何 ::after 每个盒子的伪元素 (第一行除外)与上面的框重叠。

两个复选框网格显示了伪对象之前和之后的位置。
有条件地为网格容器中的选定元素设置样式

这是基本代码

标记非常简单:

<main> <input type=checkbox> <input type=checkbox> <input type=checkbox> <!-- more boxes -->
</main>

最初的 CSS 中还有更多内容。但是,首先是网格本身:

/* The grid */
main { display: grid; grid: repeat(5, 60px) / repeat(4, 85px); align-items: center; justify-items: center; margin: 0;
}

这是一个包含复选框的五行四列的网格。我决定消除复选框的默认外观,然后给它们我自己的浅灰色背景和超圆形边框:

/* all checkboxes */
input { -webkit-appearance: none; appearance: none; background: #ddd; border-radius: 20px; cursor: pointer; display: grid; height: 40px; width: 60px; margin: 0;
}

另请注意,复选框本身是网格。这是放置他们的关键 ::before::after 伪元素。说到这里,我们现在就这样做:

/* pseudo-elements except for the first column and first row */
input:not(:nth-of-type(4n+1))::before,
input:nth-of-type(n+5)::after { content: ''; border-radius: 20px; grid-area: 1 / 1; pointer-events: none;
}

我们只选择不在网格的第一列或第一行中的复选框的伪元素。 input:not(:nth-of-type(4n+1)) 从第一个复选框开始,然后选择 ::before 从那里开始每第四个项目。但请注意我们说的是 :not(),所以我们实际上正在做的是 跳过::before 从第一个复选框开始,每四个复选框的伪元素。然后我们将样式应用到 ::after 从第五个开始的每个复选框的伪。

现在我们可以设计两者的样式 ::before::after 对不在网格的第一列或第一行中的每个复选框使用伪值,以便它们分别向左或向上移动,默认情况下隐藏它们。

/* pseudo-elements other than the first column */
input:not(:nth-of-type(4n+1))::before { transform: translatex(-85px);
} /* pseudo-elements other than the first row */
input:nth-of-type(n+5)::after { transform: translatey(-60px); }

造型 :checked

现在,当复选框位于 :checked 状态。首先,让我们给它们一个颜色,比如说 limegreen 背景:

input:checked { background: limegreen; }

复选框应该能够重新设置其所有相邻复选框的样式。换句话说,如果我们选择网格中的第十一个复选框,我们还应该能够对它周围的顶部、底部、左侧和右侧的框进行样式设置。

编号为 20 到 11 的四乘五方格网格。选择 7,并突出显示 10、12、15 和 XNUMX。
有条件地为网格容器中的选定元素设置样式

这是通过定位正确的伪元素来完成的。我们该怎么做呢?嗯,这取决于网格中的实际列数。如果在 5⨉4 网格中选中两个相邻的框,则 CSS 如下:

/* a checked box's right borders (if the element to its right is checked) */
input:not(:nth-of-type(4n)):checked + input:checked::before { border-top-right-radius: 0; border-bottom-right-radius: 0; background: limegreen;
}
/* a checked box's bottom borders (if the element below is checked) */
input:nth-last-of-type(n+5):checked + * + * + * + input:checked::after { border-bottom-right-radius: 0; border-bottom-left-radius: 0; background: limegreen;
}
/* a checked box's adjacent (right side) checked box's left borders */
input:not(:nth-of-type(4n)):checked + input:checked + input::before { border-top-left-radius: 0; border-bottom-left-radius: 0; background: limegreen;
}
/* a checked box's adjacent (below) checked box's top borders */
input:not(:nth-of-type(4n)):checked + * + * + * + input:checked + input::before { border-top-left-radius: 0; border-top-right-radius: 0; background: limegreen;
}

如果您愿意,可以动态生成上述代码。然而,在典型的网格(例如图像库)中,列数会很小,并且项目数可能是固定的,而行数可能会不断增加。特别是如果是为移动屏幕设计的。这就是为什么这种方法仍然是一种有效的方法。如果由于某种原因,您的应用程序恰好具有有限的行和扩展的列,那么请考虑横向旋转网格,因为对于项目流,CSS 网格会从左到右和从上到下(即逐行)排列它们。

我们还需要为网格中的最后一个复选框添加样式 - 它们并不全部被伪元素覆盖,因为它们是每个轴中的最后一个项目。

/* a checked box's (in last column) left borders */
input:nth-of-type(4n-1):checked + input:checked { border-top-left-radius: 0; border-bottom-left-radius: 0;
}
/* a checked box's (in last column) adjacent (below) checked box's top borders */
input:nth-of-type(4n):checked + * + * + * + input:checked { border-top-left-radius: 0; border-top-right-radius: 0;
}

这些是一些棘手的选择器!第一个…

input:nth-of-type(4n-1):checked + input:checked

……基本上是这样说的:

已检查 <input> 选中的元素旁边的元素 <input> 在倒数第二列中。

nth-of-type 计算如下:

4(0) - 1 = no match
4(1) - 1 = 3rd item
4(2) - 1 = 7th item
4(3) - 1 = 11th item
etc.

因此,我们从第三个复选框开始,然后从那里选择第四个复选框。如果该序列中的复选框被选中,那么我们也会对相邻的复选框进行样式设置(如果它们也被选中)。

而这一行:

input:nth-of-type(4n):checked + * + * + * + input:checked

是这样说的:

An <input> 前提是被检查的元素与一个元素直接相邻,该元素与另一个元素直接相邻,该元素也与另一个元素直接相邻,而另一个元素又与一个元素直接相邻。 <input> 处于选中状态的元素。

这意味着我们将选中每四个选中的复选框。如果该序列中的一个复选框被选中,那么我们将设置该复选框中的下一个第四个复选框(如果它也被选中)。

CodePen 嵌入后备

投入使用

我们刚才看到的是设计背后的总体原理和逻辑。同样,它在您的应用程序中的有用程度取决于网格设计。

我使用了圆形边框,但您可以尝试其他形状,甚至尝试背景效果(Temani 为您提供创意)。现在你已经知道了这个公式是如何运作的,剩下的就完全取决于你的想象力了。

下面是一个简单日历的示例:

CodePen 嵌入后备

同样,这只是使用静态标记的粗略原型。而且,在日历功能中需要考虑很多很多的可访问性注意事项。


这是一个包装!很整洁,对吧?我的意思是,正在发生的事情并没有什么“新”的。但这是一个很好的例子 选择事物 在CSS中。如果我们掌握了使用组合器和伪类的更高级的选择技术,那么我们的样式设计能力可以远远超出对一个项目进行样式设计的范围 - 正如我们所看到的,我们可以根据另一个元素的状态有条件地对项目进行样式设计。


有条件地为网格容器中的选定元素设置样式 最初发表于 CSS技巧。 你应该 获取时事通讯.

时间戳记:

更多来自 CSS技巧