当我 10 岁的时候,我记得我表弟来我家玩。 他是(现在仍然是)一个很酷的孩子,他会在软盘上带他自己的编程象棋游戏。 他的象棋版本和他一样酷,因为棋盘的一块会在每次移动后消失。
更酷的是? 游戏棋盘上消失的每一块都会显示出一张漂亮的照片。

我认为同样的想法可以制作出一些很酷的 UI。 除了,也许不是需要用户交互来揭示背景,它可以简单地作为动画播放。 这是我最终得到的结果
这个想法很简单,还有很多其他方法可以实现,但这是我遵循的路线……
首先,我创建了一些标记
图像可以在 CSS 中作为背景处理在 <body>
上,或一些设计为特定大小的 <div>
。 因此,现在还不需要处理它。
但棋盘很有趣。 这是一个在 CSS 网格上写满了的图案,所以我用一个元素来充当网格容器,里面有一堆 <div>
元素。 我不知道一个真正的棋盘有多少块瓦片/方格/无论什么,所以我只是从空中选择了一个数字 7,然后平方它得到 49 个方格。
<div class="grid">
<div></div>
<!-- etc. -->
<div></div>
</div>
是的,写出所有这些 divs 很痛苦,JavaScript 可以肯定地帮助。 但是如果我只是在实验,并且只需要开发人员的便利,那么使用 Haml 可以帮助解决这个问题
.grid
- 49.times do
%div
最终它们都是一样的。 无论哪种方式,它都为我提供了开始样式化所需的所有标记!
设置背景图像
同样,这可以作为 <body>
或其他元素上的 background-image
发生,具体取决于它的使用方法——只要它覆盖整个空间即可。 由于我反正需要一个网格容器,我决定使用它。
.checkerboard {
background-image: url('walrus.jpg');
background-size: cover;
/* Might need other properties to position the image just right */
}
渐变是光栅图像文件的一部分,但我可以用某种类型的覆盖在 <body>
上使用伪元素,如 :after
,变得聪明。 哎呀,这是一种广泛使用的技术,就在 CSS-Tricks 的当前设计上。
设置网格样式
是的,我使用了 CSS 网格。 用这种方式制作一个 7×7 网格非常容易。
.checkerboard {
background-image: url('walrus.jpg');
background-size: cover;
display: grid;
grid-template-columns: repeat(7, 1fr);
grid-template-rows: repeat(7, 1fr);
}
我想象,一旦我们看到 aspect-ratio
广泛支持,它会好得多,至少如果我正确理解的话。 我现在遇到的问题是,网格没有保持任何比例。 这意味着棋盘的瓦片在不同的视窗大小下会变得很软等等。 嘘。 在此期间,我们可以做一些很小的技巧,如果这非常重要,但我决定保持原样。
设置瓦片样式
它们在白色和深灰色之间交替,因此
.checkerboard > div {
background-color: #fff;
}
.checkerboard > div:nth-child(even) {
background-color: #2f2f2f;
}
信不信由你,我们的标记和样式化完成了! 剩下的就是……
为瓦片设置动画
所有动画需要做的就是将每个瓦片的 opacity: 1;
过渡到 opacity: 0;
,CSS 动画非常适合此操作。
@keyframes poof {
to {
opacity: 0;
}
}
太棒了! 我甚至不需要设置一个开始关键帧! 我所要做的就是调用瓦片上的动画。
.checkerboard > div {
animation-name: poof;
animation-duration: 0.25s;
animation-fill-mode: forwards;
background: #fff;
}
是的,我本可以使用 animation
简写属性,但我经常发现将它的组成属性单独拆分出来更容易,因为……好吧,它们太多了,而且在一行上很难阅读和识别。
如果您想知道这里为什么要使用 animation-fill-mode
,那是因为它可以防止动画在设置为 forwards
时循环回到动画的开头。 换句话说,每个瓦片在动画结束时会停留在 opacity: 0;
上,而不是重新出现。
我真的很想做一些聪明而巧妙的事情来交错瓦片的 animation-delay
,但我碰了一堆墙,最后决定放弃 100% 原生 CSS 的努力,转而使用一些轻量级的 SCSS。 这样,我可以循环遍历所有瓦片,并使用一个非常标准的函数为每个瓦片设置动画偏移。 所以,对于突然的转换感到抱歉! 这只是旅程的一部分。
$columns: 7;
$rows: 7;
$cells: $columns * $rows;
@for $i from 1 through $cells {
.checkerboard > div:nth-child(#{$i}) {
animation-delay: (random($cells) / $columns) + s;
}
}
让我们分解一下
- 有网格列数 (
$columns
)、网格行数 ($rows
) 和单元格总数 ($cells
) 的变量。 最后一个是前两个的乘积。 如果我们知道我们总是在使用一个完美的正方形网格,那么我们可以稍微重构一下,使用指数来计算单元格数量。 - 然后,对于
1
和$cells
总数(在本例中为 49)之间的每个单元格实例,每个单独的瓦片都会根据其:nth-child()
值获得animation-delay
。 因此,第一个瓦片是div:nth-child(1)
,然后是div:nth-child(2)
,依此类推。 查看演示中的编译 CSS,您将看到它是如何全部分解的。
.checkerboard > div:nth-child(1) {}
.checkerboard > div:nth-child(2) {}
/* etc. */
- 最后,
animation-delay
是一个计算,它取1
和$cells
总数之间的随机数,除以$columns
的数量,并在值后面附加秒。 这是最好的方法吗? 我不知道。 它归结为多尝试一些东西,找到一些感觉“正确”的东西。 对我来说,这感觉“正确”。
我真的很想发挥创意,使用 CSS 自定义属性,而不是求助于 SCSS。 我喜欢自定义属性和值可以在客户端更新,而 SCSS 中的计算值是在构建时编译的,并且一直保持不变。 同样,这正是我非常想使用 JavaScript 的地方。 但是,我已经铺好床了,只能躺在里面。
如果您之前查看过编译的 CSS,那么您将看到计算出的值
/* Yes, Autoprefixer is in there... */
.checkerboard > div:nth-child(1) {
-webkit-animation-delay: 4.5714285714s;
animation-delay: 4.5714285714s;
}
.checkerboard > div:nth-child(2) {
-webkit-animation-delay: 5.2857142857s;
animation-delay: 5.2857142857s;
}
.checkerboard > div:nth-child(3) {
-webkit-animation-delay: 2.7142857143s;
animation-delay: 2.7142857143s;
}
.checkerboard > div:nth-child(4) {
-webkit-animation-delay: 1.5714285714s;
animation-delay: 1.5714285714s;
}
嗯,也许那个动画应该可选……
有些人对运动和移动很敏感,所以最好改变一下,让瓦片只有在用户喜欢的情况下才设置样式和动画。 我们为此有一个媒体查询!
@media screen and (prefers-reduced-motion: no-preference) {
.checkerboard > div {
animation-name: poof;
animation-duration: 0.25s;
animation-fill-mode: forwards;
background: #fff;
}
.checkerboard > div:nth-child(even) {
background: #2f2f2f;
}
}
就是这样!
这是那个演示,再来一次
:-D 用 8×8 做吧 ;-)
有求必应 请查收.
您没有将您的列和行更新为 repeat(8, 1fr)。