12个花⾥胡哨的CSS炫酷案例!(附源码)
前⾔
⼜到了⾦三银四⾯试季,这⾥我整理了... 欸!?不好意思,跑题了... 感觉近来掘⾦⾸页全是⾯试相关的内容,我是打开掘⾦也不知道该看啥,实在⽆奈。
上个礼拜看了许多关于平⾯构成的资料,我就边⽤ CSS 画了⼀些类似背景图案的玩意⼉。这⾥给⼤家选了12种,从观察者的⾓度由易到难的给⼤家解⼀下思路。本⽂包含⼤量图⽚及代码所以较长,建议先点赞收藏。
⚠预警,本⽂没有对基础知识的详解,不过推荐⼀边看⽂章实践⼀边学习,效率更⾼。
效果图展⽰
分析顺序介绍
粗略看过效果之后,我们按照图案种元素的多少及元素变异程度、动画难易程度、有⽆头绪等因素给⽂章⼩节排⼀个序,顺序见下图。每⼩节都有源码,你可以通过标题直接跳转到你想看的图案。
1. 圆环变形
<div class="card">
<div class="node" v-for="item in 100"></div>
</div>
<style>
// 其余所有图案的 card 类标签都套⽤了这段样式,为了减少⽂章长度,下略。
.card {
width: 200px;
height: 200px;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
</style>
通过图⽚动画效果,我们⼤致得出动画变化的模式。
有部分圆环变形成两个圆环的长度,并改变了底⾊。
观察变长圆环的顺序,能发现“每逢三就变长”这种规律,推测使⽤了 :nth-child(3) 选择器。下⾯是 CSS 源码。
.card {
justify-content: flex-start;
overflow: hidden;
cursor: pointer;
// 每逢三个元素,则执⾏动画,源代码和我们分析的动画的顺序相反,圆环是从长变短,不过不影响    .node {
border: solid 5px #F29338;
border-radius: 50%;
&:nth-child(3n) {
width: 40px;
flex-basis: 40px;
background: #F8C798;
animation: change-circle-width 2s ease alternate infinite;
}
}
}
@keyframes change-circle-width {
from {
width: 40px;
flex-basis: 40px;
background: #F8C798;
}
60% {
width: 20px;
flex-basis: 20px;
background: transparent;
}
// 动画 60% - 100% 这段时间,属性没有变动,所以图案看起来像是静⽌的。
to {
rotate属性width: 20px;
flex-basis: 20px;
background: transparent;
}
}
2. 厕所⾥的瓷砖
<div class="card">
<div class="node" v-for="item in 100"></div>
</div>
和上⼀张图思路类似,只是多出了⼀些圆形⼩球。
⼩球的动画应该包含位置的偏移和颜⾊、透明度的改变。
当⿏标悬浮时(注意图⽚右下⾓的⿏标⼿势),图中多了⼀排⼩圆球,样式和⾏为和前⼀排原球⼏乎⼀样。
推测第⼆排圆球使⽤了 animation-delay 效果。
观察⼩球的个数,欸?貌似有些问题,圆形⼩球数量和瓷砖数量对不上。应该是对⼩球的显隐的顺序做了特殊处理。下⾯是 CSS 源码。
.card {
cursor: pointer;
// ⿏标悬浮时显⽰第⼆排的⼩圆球
&:hover {
.node {
&:nth-child(2n)::after {
visibility: unset;
}
}
}
.node {
background: #71A2DB;
outline: solid 1px white;
/
/ 3n-1,3n+1 ⼀起使⽤时等价于 3n
&:nth-child(3n-1),
&:nth-last-child(3n+1) {
background: #C2D7F0;
}
// 去除末⾏及每⾏末尾的伪元素
&:nth-child(10n)::after,
&:nth-last-child(-n+10)::after {
display: none;
}
&::after {
left: 75%;
top: 75%;
width: 50%;
height: 50%;
border-radius: 50%;
background: white;
animation: card-4-circle-move 1s linear alternate infinite;
}
&:nth-child(2n)::after {
animation: card-4-circle-move-delay 1s linear alternate infinite;
animation-delay: .3s;
visibility: hidden;
}
}
}
@keyframes card-4-circle-move {
from {
left: 45%;
top: 45%;
opacity: 1;
background: white;
}
to {
left: 130%;
top: 130%;
opacity: 0;
opacity: 0;
background: #F2C07D;
}
}
@keyframes card-4-circle-move-delay {
from {
left: 45%;
top: 45%;
opacity: 1;
background: #F2C07D;
z-index: 2;
}
to {
left: 130%;
top: 130%;
opacity: 0;
background: white;
}
}
3. 三⾓与圆球印花
<div class="card">
<div class="node" v-for="item in 100"></div>
</div>
乍⼀眼看,⽤每个节点的伪元素画⼀个圆形和⼀个三⾓形就完成了这张图。
其实并不对,先别往下翻答案,想想为什么。
答案分割线,⼩⼼越界:
观察图案和HTML代码:
从每⾏来看,每⾏有10个三⾓形,但是每⾏有9个圆+2个半圆。
猜测圆形是由半圆组装的,再结合纵向观测,可以推测圆形是由4个 1/4 圆组成的。
但是⽤伪元素没有办法画 1/4 圆。思路不对,再换个思路。
猜测伪元素是⼀个整圆,利⽤ Box-Shadow 复制了4份,分别放在了正⽅形四个⾓落。.card 或是 .node 使⽤ overflow 裁剪掉多余元素。
再看三⾓形。
三⾓形的画法⽐较常见,可以⽤透明 Border + 带颜⾊的 Border 绘制。
三⾓形的⾓度变化很有规律,可以⼤致推测,旋转⾓度和列数有关。
.card {
overflow: hidden;
cursor: pointer;
// 根据三⾓形的序号与10的模来确定旋转⾓度
@for $i from 0 through 9 {
.node:nth-child(10n - #{$i})::before {
transform: rotate((-19 + $i) + unquote('deg'));
}
}
// 上⾯那串函数编译出来就成了下⾯这⼀长串模样