使用CSS的counter-increment做的游戏
我把CSS的黑魔法和把CSS推动到极限当作我的至爱。许多人没有意识到这是有多么的强大(特别是结合Sass)的预处理技术。这篇文章结合这两种至爱来做一些有意思的东西。当然它可能会或可能不会被你的下一个客户问,这样做有价值吗?但这样尝试才能真正的理解一种语言(当然,很多人说CSS不是一种语言)。但你也能使用纯CSS技术做一些简单的小游戏。
Counter-Increment
counter-increment
是一个相对模糊的CSS属性,其原本是想用于编号的设计。这是一个很实用的CSS属性,而且也得到了很好的支持:
Codrops的CSS Reference详细介绍了这个属性,我建议你可以看看。
Counter-Reset
为了使用counter-increment
做编号设计,就必须要使用counter-reset
设置一个计数器。counter-increment
和counter-reset
的值应该相互匹配,但可以是任意东东,比如:
// 父元素有一个counter-reset应用于实例化(初始化)
section {
counter-reset: unicornCounter;
}
// 被指定的子元素上开始计算
section h1 {
counter-increment: unicornCounter;
}
在上面的代码中,在section
中的每个<h1>
元素将会被计算值为1
(这个数字可以定制,下面的内容会说到这个)。
使用Counter-Increment来计数
CSS中并没有提供很多变量选项,或者说用来变量来存储数字,但有一个小魔法,那就是使用复选框(<input type="checkbox">
)。复选框有一个全局属性(checked
),可以不通过JavaScript来改变(只需要单击)。这样使得复选框非常独特,也适合动态计算:
input:checked {
counter-increment: counterName;
}
这样就可以在每个input
元素上设置counter-increment
属性,当其选中(如上显示)来做计数统计。简单点说,就是通过用户动态的选择或不选择复选框,让counter-increment
做出相应的反应。
显示计数器
我们可以使用伪元素(::before
或::after
)和它的content
来显示计数器。因为我们有一个变量的名称,通过counter-increment
可以让它做一个增量计算,例如:
span::after {
content: counter(counterName);
}
注意:counter
只会对可见元素做统计。只要DOM元素设置了display:none
和visibility: hidden;
都将不会被计算在内。
这里有一个例子,通过counter-increment
来统计被击中目标的分数值的一个小游戏。每个目标是一个复选框,并且animation-duration
使用了一个随机值,让其移动有不同的速度。而且每个击中的目标还使用了animation-delay
属性,延迟了10s
。感兴趣的可以在新的窗口中打开下面的游戏,亲自体验一翻:
这里动画效果都是通过CSS的
transition
和animation
来实现,但是未来可以使用Web Animation API,能更好的控好动画。
自定义计数器
在实际使用中,也可以自定义计数器(也可以使用多个计数器),并且指定增量的数量(默认值为1
)。可以像下面这样做:
// 按2的增量input计数
input:checked {
counter-increment: counterName 2;
}
// 每次input选中减去3
input:checked {
counter-increment: counterName -3;
}
如果我想让上面的游戏变得更复杂一些,可以给每个目标制作成一个环形靶,而且每个环的目标值都不一样:
在上面的示例中,每个靶不只是一个复选框,而是变成三个复选框了:
<!-- HTML for target list -->
<ul class="game-area">
<!-- Individual target -->
<ul class="target">
<li><input type="checkbox" class="inner-check"></li>
<li><input type="checkbox" class="middle-check"></li>
<li><input type="checkbox" class="outer-check"></li>
</ul>
<!-- Next targets here ... -->
</ul>
每个复选框都使用counter(game)
,但每个复选框使用不同的counter-increment
值:
.inner-check {
@extend %target-ring;
// ... style color and position
z-index: 3;
// counting "game" up by 5
&:checked {
counter-increment: game 5;
}
&:checked::after {
content: '+5';
}
}
.middle-check {
@extend %target-ring;
// ... style color and position
z-index: 2;
// counting "game" up by 3
&:checked {
counter-increment: game 3;
}
&:checked::after {
content: '+3';
}
}
.outer-check {
@extend %target-ring;
// ... style color and position
z-index: 1;
// counting "game" up by 1
&:checked {
counter-increment: game 1;
}
&:checked::after {
content: '+1';
}
}
复选框逻辑
现在你可以使用复选框的逻辑写一些更牛逼的游戏。你可以通过使用:chceked
和:not(:checked)
伪选择器来做这些事情。
例如::checked + :checked
属性选择器,直接选中另一个元素,甚至你可以使用:checked + :not(:checked) + :checked
来实现类似on,off,on
的功能。
我使用这种方法(以及上面提到的一些动画技巧,这个时候它有自己的z-index
)重新创建了一个游戏。
这是圈圈叉叉的逻辑示例,这样每个示例的X就可以赢:
// x | x | x
// | |
// | |
//
// note: also works for a horizontal match on the
// 2nd & 3rd rows, but more logic should be applied
// to avoid false positives of 3 consecutive checks
:checked + :checked + :checked ~ span::after { ... }
// x | |
// x | |
// x | |
:checked + :not(:checked) + :not(:checked) + :checked + :not(:checked) + :not(:checked) + :checked ~ span::after { ... }
// | x |
// | x |
// | x |
:not(:checked) + :checked + :not(:checked) + :not(:checked) + :checked + :not(:checked) + :not(:checked) + :checked ~ span::after { ... }
// | | x
// | | x
// | | x
:not(:checked) + :checked + :not(:checked) + :not(:checked) + :checked + :not(:checked) + :not(:checked) + :checked ~ span::after { ... }
// | | x
// | x |
// x | |
:not(:checked) + :not(:checked) + :checked + :not(:checked) + :checked + :not(:checked) + :checked ~ span::after { ... }
// x | |
// | x |
// | | x
:checked + :not(:checked) + :not(:checked) + :not(:checked) + :checked + :not(:checked) + :not(:checked) + :not(:checked)+ :checked ~ span::after { ... }
这可能让你的示例立马变得复杂,但不用担心,Sass可以帮你。Jake Albaugh创建了一个更令人难以置信的二进制计算器的示例,这个示例直接向你展示了这个属性是有多么强大,Sass怎么有用。当逻辑复杂性增加时,你需要一些编程的能力,可以帮助你更好的维护。
如果你使用这种技术做了一些更酷的案例,我真的想看看,请您在下面的评论中分享您的案例链接地址。
总结
这篇文章通过几个游戏案例,向您展示了CSS的counter-increment
是多么的强大,其除了可以让你简单实现一些项目编号的设计之外,还可以做一些更有意思的事情,同时向你展示了CSS更强的魅力与实际价值。
扩展阅读
- CSS Counters
- 如何从css生成内容和计数组件中得到益处
- On CSS counters plus a CSS3 Reversi UI
- How To Benefit From CSS Generated Content And Counters
- Counters
本文根据@una的《Pure CSS Games with Counter-Increment》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处://una.im/css-games/。
如需转载,烦请注明出处:https://www.fedev.cn/css3/pure-css-games-with-counter-increment.htmlAdidas Energy Boost