仅⽤CSS⼏步实现赛博朋克2077风格视觉效果
背景
⽂章开始之前先简单了解下什么是赛博朋克,以及什么是赛博朋克2077。
赛博朋克(Cyberpunk)是“控制论、神经机械学”与“朋克”的结合词,背景⼤都建⽴于“低端⽣活与⾼等科技的结合”,拥有先进的科学技术,再以⼀定程度崩坏的社会结构做对⽐;拥有五花⼋门的视觉冲击效果,如街头的霓虹灯、街排标志性⼴告以及⾼楼建筑等,通常搭配⾊彩是以⿊、紫、绿、蓝、红为主。其中菲利普·狄克所著作的《仿⽣⼈会梦到电⼦⽺吗?》最受注⽬,⼩说亦被改编成电影《银翼杀⼿》。总的来讲,赛博朋克的风格主线,就是反应出科技⾼度发展的⼈类⽂明,与脆弱渺⼩的⼈类个体之间的强烈反差,同时外界与内在,钢铁与⾁体,过去与未来,现实与虚幻等⽭盾在其中交织。
《赛博朋克2077》是⼀款动作⾓⾊类游戏,于2020年12⽉10⽇登陆各⼤游戏平台。故事发⽣在夜之城,权⼒更迭和⾝体改造是这⾥不变的主题。玩家将扮演⼀名野⼼勃勃的:V,追寻⼀种独⼀⽆⼆的植⼊体——获得永⽣的关键。它以⾃由的探索性,较⾼的操控度以及惊艳的视觉特效收获了⼀⼤批玩家。我⾮常喜欢2077官⽹的设计风格,因此本篇⽂章主要以2077官⽹为例,通过⼏个例⼦,依次实现赛博朋克风格元素效果。
实现
裴勇俊丑闻⾼对⽐度
⾸先我们来看⼀下2077中⽂官⽹⾸页,页⾯主要以醒⽬的明黄⾊为主⾊调,并⼩⾯积使⽤它的对⽐⾊淡蓝⾊、玫红⾊的⾊块作为点缀,⽂本和线条边框使⽤纯⿊⾊。这⼀步实现⾮常简单,我们在实现赛博朋克风格的页⾯时,可以使⽤上⾯提到的⿊、紫、绿、蓝、红为主⾊调,再以它们的对⽐⾊作为按钮、⽂本提⽰框,可以实现强烈的视觉冲击。
故障风格按钮
故障效果是⼀种显⽰设备崩坏效果,在2077官⽹中应⽤很多,我们先来实现button在hover时产⽣故障效果。
<button>⽴即加⼊</button>
故障效果主要通过clip-path: inset和动画实现。利⽤button的伪元素::after,给它定义多个分⽚--slice变量,并通过动画切换切⽚的位置,来实现晃动效果。其中clip-path属性使⽤裁剪⽅式创建元素的可显⽰区域。区域内的部分显⽰,区域外的隐藏。inset()⽅法⽤于定义⼀个矩形,可以传⼊5个参数,分别对应top,right,bottom,left的裁剪位置
及round和radius(可选,圆⾓),它的基本语法如下:
inset( <length-percentage>{1,4} [ round <border-radius> ]? )
clip-path: inset(2em 3em 2em 1em round 2em);
完整实现:
button, button::after {
width: 300px;
height: 86px;
font-size: 40px;
background: linear-gradient(45deg, transparent 5%, #FF013C 5%);
border: 0;
color: #fff;
letter-spacing: 3px;
line-height: 88px;
box-shadow: 6px 0px 0px #00E6F6;
outline: transparent;
position: relative;
}
button::after {
--slice-0: inset(50% 50% 50% 50%);
--slice-1: inset(80% -6px 0 0);
--slice-2: inset(50% -6px 30% 0);
--slice-3: inset(10% -6px 85% 0);
--slice-4: inset(40% -6px 43% 0);
-
-slice-5: inset(80% -6px 5% 0);
content: '⽴即加⼊';
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(45deg, transparent 3%, #00E6F6 3%, #00E6F6 5%, #FF013C 5%);
text-shadow: -3px -3px 0px #F8F005, 3px 3px 0px #00E6F6;
clip-path: var(--slice-0);
}
button:hover::after {
animation: 1s glitch;
animation-timing-function: steps(2, end);
}
@keyframes glitch {
0% { clip-path: var(--slice-1); transform: translate(-20px, -10px); }
10% { clip-path: var(--slice-3); transform: translate(10px, 10px); }
20% { clip-path: var(--slice-1); transform: translate(-10px, 10px); }
30% { clip-path: var(--slice-3); transform: translate(0px, 5px); }
40% { clip-path: var(--slice-2); transform: translate(-5px, 0px); }
50% { clip-path: var(--slice-3); transform: translate(5px, 0px); }
60% { clip-path: var(--slice-4); transform: translate(5px, 10px); }
70% { clip-path: var(--slice-2); transform: translate(-10px, 10px); }
80% { clip-path: var(--slice-5); transform: translate(20px, -10px); }
90% { clip-path: var(--slice-1); transform: translate(-10px, 0px); }
100% { clip-path: var(--slice-1); transform: translate(0); }
}
故障风格图⽚
故障效果同样可以应⽤在⽂本、图⽚、视频等媒体展⽰上,营造满满的科技氛围。这部分内容来看看如何实现故障风格的图⽚展⽰效果。
.glitch是为图⽚展⽰容器主体,它的⼦元素glitch__item⽤来表⽰故障条,与上例中::after伪元素作⽤类似。
<div class="glitch">
<div class="glitch__item"></div>
<!-- ... -->
<div class="glitch__item"></div>
</div>
故障风格图⽚和故障风格按钮实现思路基本类似,不过这次⽤到了clip-path: polygon实现,polygon⽤于裁切多边形的⽅法,它的每对值表⽰裁切元素的坐标。background-blend-mode属性定义了背景层的混合模式。由于⽂章篇幅有限,以下代码只展⽰了⼀个故障条的动画,完整例⼦可查看⽂章末尾对应链接 :
:root {
--gap-horizontal: 10px;
--gap-vertical: 5px;
-
-time-anim: 4s;
--delay-anim: 2s;
--blend-mode-1: none;
--blend-color-1: transparent;
}
.glitch {
position: relative;
}
.glitch .glitch__item {
background: url("banner.png") no-repeat 50% 50%/cover;
height: 100%;
width: 100%;
top: 0;
left: 0;
position: absolute;
}
乐嘉个人资料.glitch .glitch__item:nth-child(1) {
background-color: var(--blend-color-1);
background-blend-mode: var(--blend-mode-1);
animation-duration: var(--time-anim);
animation-delay: var(--delay-anim);
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-name: glitch-anim-1;
}
@keyframes glitch-anim-1 {
0% {
transform: translate3d(var(--gap-horizontal), 0, 0);
clip-path: polygon(0 2%, 100% 2%, 100% 5%, 0 5%);
}
2% { clip-path: polygon(0 15%, 100% 15%, 100% 15%, 0 15%); }
4% { clip-path: polygon(0 10%, 100% 10%, 100% 20%, 0 20%); }
6% { clip-path: polygon(0 1%, 100% 1%, 100% 2%, 0 2%); }
8% { clip-path: polygon(0 33%, 100% 33%, 100% 33%, 0 33%); }
10% { clip-path: polygon(0 44%, 100% 44%, 100% 44%, 0 44%); }
12% { clip-path: polygon(0 50%, 100% 50%, 100% 20%, 0 20%); }
14% { clip-path: polygon(0 70%, 100% 70%, 100% 70%, 0 70%); }
16% { clip-path: polygon(0 80%, 100% 80%, 100% 80%, 0 80%); }
18% { clip-path: polygon(0 50%, 100% 50%, 100% 55%, 0 55%); }
20% { clip-path: polygon(0 70%, 100% 70%, 100% 80%, 0 80%); }
21.9% {
opacity: 1;
transform: translate3d(var(--gap-horizontal), 0, 0);
}
22%, 100% {
opacity: 0;
transform: translate3d(0, 0, 0);
clip-path: polygon(0 0, 0 0, 0 0, 0 0);
}
}
霓虹元素
在赛博朋克场景中,如电影《银翼杀⼿》《机壳特⼯队》、游戏《看门狗》《赛博朋克2077》中⽆论是在废弃的建筑物 、还是繁华的歌舞町  ,都存在⼤量的霓虹neon元素。
我们同样可以使⽤⼤量霓虹元素来装饰页⾯,⽐如页⾯标题、按钮、表单边框等都可以使⽤霓虹效果,下⾯是霓虹⽂字实现的简要⽰例:
.neon和.flux两个元素是两个⽂本载体,将被应⽤不同的霓虹效果样式和动画。
<div class="neon">CYBER</div>
<div class="flux">PUNK</div>
⽂字的霓虹效果主要通过text-shadow属性实现,闪烁效果也是通过添加与⽂字颜⾊相近的text-shadow动画来实现,其中.neon元素被应⽤了ease-in-out运动曲线,.flux元素被应⽤
了linear运动曲线,可以看出两者之间的差别吗。
.neon {
text-shadow: 0 0 3vw #F4BD0A;
animation: neon 2s ease-in-out infinite;
}
.flux {
text-shadow: 0 0 3vw #179E05;
animation: flux 2s linear infinite;
}
@keyframes neon {
0%, 100% {
text-shadow: 0 0 1vw #FA1C16, 0 0 3vw #FA1C16, 0 0 10vw #FA1C16, 0 0 10vw #FA1C16, 0 0 .4vw #FED128, .5vw .5vw .1vw #806914;
color: #FFFC00;
}
50% {
text-shadow: 0 0 .5vw #800E0B, 0 0 1.5vw #800E0B, 0 0 5vw #800E0B, 0 0 5vw #800E0B, 0 0 .2vw #800E0B, .5vw .5vw .1vw #40340A;
color: #806914;
}
}
@keyframes flux {
0%, 100% {
text-shadow: 0 0 1vw #10ff4c, 0 0 3vw #1041FF, 0 0 10vw #1041FF, 0 0 10vw #1041FF, 0 0 .4vw #8BFDFE, .5vw .5vw .1vw #147280;
color: #03C03C;
}
50% {
text-shadow: 0 0 .5vw #024218, 0 0 1.5vw #024713, 0 0 5vw #023812, 0 0 5vw #012707, 0 0 .2vw #022201, .5vw .5vw .1vw #011a06;
color: #179E05;
}
}
不规则⽂本框
赛博朋克2077中可以看到很多⽂本展⽰框都是这种不规则图形的,是不是很酷呢,这部分内容将介绍如何实现2077风格的⽂本框。
上⾯3个⽂本框分别由3个p标签构成,.inverse类表⽰反⾊背景,.dotted将实现点状背景。
<p class="cyberpunk">经典的赛博朋克⾓⾊是边缘且性格疏远的独⾏者。他们⽣活在社会体的边缘,⼀个弥漫反乌托邦氛围的未来:⽇常⽣活受到急剧改变的科技影响,普及的计算机化信息笼罩全球,以及侵⼊性的⼈体改造。</p>
<p class="cyberpunk inverse">经典的赛博朋克⾓⾊是边缘且性格疏远的独⾏者。他们⽣活在社会体的边缘,⼀个弥漫反乌托邦氛围的未来:⽇常⽣活受到急剧改变的科技影响,普及的计算机化信息笼罩全球,以及侵⼊性的⼈体改造。
<p class="cyberpunk inverse dotted">经典的赛博朋克⾓⾊是边缘且性格疏远的独⾏者。他们⽣活在社会体的边缘,⼀个弥漫反乌托邦氛围的未来:⽇常⽣活受到急剧改变的科技影响,普及的计算机化信息笼罩全球,以及侵⼊性的⼈体改造。⽂本框不规则的形状主要由clip-path: polygon实现,通过
以下⼏个坐标的裁切,就可以实现2077风格的多边形了。
clip-path: polygon(
0px 25px,
26px 0px,
calc(60% - 25px) 0px,
头像国旗怎么来的60% 25px,
100% 25px,
100% calc(100% - 10px),
calc(100% - 15px) calc(100% - 10px),
calc(80% - 10px) calc(100% - 10px),
calc(80% - 15px) 100%,
80px calc(100% - 0px),
65px calc(100% - 15px),
0% calc(100% - 15px)
);
完整代码:
:root {
--yellow-color: #f9f002;
--border-color: #8ae66e;
}
.cyberpunk {
padding: 5px;
position: relative;
font-size: 1.2rem;
color: var(--yellow-color);
border: 30px solid var(--yellow-color);
border-right: 5px solid var(--yellow-color);
border-left: 5px solid var(--yellow-color);
border-bottom: 24px solid var(--yellow-color);
background-color: #000;
clip-path: polygon(0px 25px, 26px 0px, calc(60% - 25px) 0px, 60% 25px, 100% 25px, 100% calc(100% - 10px), calc(100% - 15px) calc(100% - 10px), calc(80% - 10px) calc(100% - 10px), calc(80% - 15px) 100%, 80px calc(100% -
}
.cyberpunk.inverse {
无线网密码破解
border: none;
padding: 40px 15px 30px;
color: #000;
background-color: var(--yellow-color);
border-right: 2px solid var(--border-color);
}
.dotted, .dotted:before, .dotted:after {
background: var(--yellow-color);
background-image: radial-gradient(#00000021 1px, transparent 0);
background-size: 5px 5px;
background-position: -13px -3px;
}
/* ⽂本框右侧⼩编号样式 */
.cyberpunk:before {
content: "P-14";
display: block;
position: absolute;
三国武将
bottom: -12px;
right: 25px;
padding: 2px 2px 0px 2px;
font-size: 0.6rem;
color: #000;
background-color: var(--yellow-color);
border-left: 2px solid var(--border-color);
}
.cyberpunk.inverse:before {
content: "T-71";
right: 90px;
bottom: 9px;
}
.cyberpunk.inverse:before, .cyberpunk:before {
background-color: #000;
color: var(--yellow-color);
}
炫酷的表单元素
2077的表单也很有特⾊,输⼊框元素input和textarea同样可以使⽤clip-path: polygon实现不规则形状,单选框和多选框则可以利⽤伪元素:before、:after进⾏装饰。
<input class="cyberpunk" type="text" placeholder="input 输⼊框" />
<textarea class="cyberpunk" placeholder="textarea ⽂本框"></textarea>
<label class="cyberpunk"><input class="cyberpunk" name="test" type="radio" />单选框1</label>
<label class="cyberpunk"><input class="cyberpunk" name="test" type="radio" />单选框2</label><br />
<label class="cyberpunk"><input class="cyberpunk" type="checkbox" />多选框</label><br />
完整实现如下:
input[type="text"].cyberpunk, berpunk {
width: calc(100% - 30px);
border: 30px solid #000;
border-left: 5px solid #000;
border-right: 5px solid #000;
border-bottom: 15px solid #000;
clip-path: polygon(0px 25px, 26px 0px, calc(60% - 25px) 0px, 60% 25px, 100% 25px, 100% calc(100% - 10px), calc(100% - 15px) calc(100% - 10px), calc(80% - 10px) calc(100% - 10px), calc(80% - 15px) calc(100% - 0px), 10px calc(  padding: 12px;
}
input[type="radio"].cyberpunk {
border-radius: 15%;
z-index: 100;
height: 14px;
width: 20px;
appearance: none;
outline: none;
background-color: #000;
cursor: pointer;
position: relative;
margin: 0px;
display: inline-block;
}
input[type="radio"].cyberpunk:after {
content: "";
display: block;
width: 8px;
height: 6px;
background-color: var(--yellow-color);
position: absolute;
top: 2px;
left: 2px;
transition: background 0.3s, left 0.3s;
}
input[type="radio"].cyberpunk:checked:after {
background-color: var(--border-color);
left: 10px;
}
input[type="checkbox"].cyberpunk {
border-radius: 15%;
z-index: 100;
height: 20px;
width: 20px;
appearance: none;
outline: none;
background-color: #000;
cursor: pointer;
position: relative;
margin: 0px;
margin-bottom: -3px;
display: inline-block;
}
input[type="checkbox"].cyberpunk:before {
content: "";
display: block;
width: 8px;
height: 8px;
border: 2px solid var(--yellow-color);
border-top: 2px solid transparent;
border-radius: 50%;
position: absolute;
top: 5px;
left: 4px;
}
input[type="checkbox"].cyberpunk:after {
content: "";
display: block;
width: 2px;
height: 7px;
background-color: var(--yellow-color);
position: absolute;
top: 3px;
left: 9px;
}
input[type="checkbox"].cyberpunk:checked:before {
border-color: var(--border-color);
border-top-color: transparent;
}
input[type="checkbox"].cyberpunk:checked:after {
background-color: var(--border-color);
}
标题和⽂本
赛博朋克风格⽹页在⽂本展⽰中,常常⽤到如下图所⽰的输⼊光标闪烁样式及屏幕故障风格的样式,我们可以统⼀为h1 - h5标题,hr等元素增加下划线装饰和故障动画效果,下⾯
来看看如何实现这样的⽂字效果的。
<h1 class="cyberpunk">H1 title</h1>
<h1 class="cyberpunk glitched">H1 title glitched</h1>
position: relative;
}
content: "";
display: block;
position: absolute;
bottom: 0px;
left: 2px;
width: 100%;
height: 10px;
background-color: #000;
clip-path: polygon(0px 0px, 85px 0px, 90px 5px, 100% 5px, 100% 6px, 85px 6px, 80px 10px, 0px 10px);
}
animation-name: glitched;
animation-duration: calc(.9s * 1.4);
animation-iteration-count: infinite;
animation-timing-function: linear;
}
@keyframes glitched {
0% { left: -4px; transform: skew(-20deg); }
11% { left: 2px; transform: skew(0deg); }
50% { transform: skew(0deg); }
51% { transform: skew(10deg); }
60% { transform: skew(0deg); }
100% { transform: skew(0deg); }
}
animation-name: beforeglitched;
animation-duration: calc(.9s * 2);
animation-iteration-count: infinite;
animation-timing-function: linear;
}
@keyframes beforeglitched {
0% {
left: -4px;
transform: skew(-20deg);
clip-path: polygon(0px 0px, 85px 0px, 90px 5px, 100% 5px, 100% 6px, 85px 6px, 80px 10px, 0px 10px);
}
西安宠物用品批发11% {
left: 2px;
transform: skew(0deg);
clip-path: polygon(0px 0px, 85px 0px, 90px 5px, 100% 5px, 100% 6px, 85px 6px, 80px 10px, 0px 10px);
}
50% {
transform: skew(0deg);
clip-path: polygon(0px 0px, 85px 0px, 90px 5px, 100% 5px, 100% 6px, 85px 6px, 80px 10px, 0px 10px);
}
51% {
transform: skew(0deg);
clip-path: polygon(0px 0px, 85px 0px, 90px 5px, 100% 5px, 40% 5px, calc(40% - 30px) 0px, calc(40% + 30px) 0px, calc(45% - 15px) 5px, 100% 5px, 100% 6px, calc(45% - 14px) 6px, calc(40% + 29px) 1px, calc(40% - 29px) 1px,
}
60% {
transform: skew(0deg);
clip-path: polygon(0px 0px, 85px 0px, 90px 5px, 100% 5px, 100% 6px, 85px 6px, 80px 10px, 0px 10px);
}
100% {
transform: skew(0deg);
clip-path: polygon(0px 0px, 85px 0px, 90px 5px, 100% 5px, 100% 6px, 85px 6px, 80px 10px, 0px 10px);
}
}
⾦属质感
在赛博朋克2077的⽹页⾥,为了突显科技感,很多页⾯元素都具有⾦属质感,如模态弹窗的背景、⽂本展⽰块的边框等。这部分内容看看如何实现简单的⾦属材质背景。
4个button元素,将被分别添加⾦、银、铜、钛的⾦属背景⾊效果。
<button class="gold">gold ⾦</button>
<button class="silver">silver 银</button>
<button class="bronze">bronze 铜</button>
<button class="titanium">titanium 钛</button>
实现⾦属光泽效果,主要以下⼏个个css属性:
box-shadow:增加阴影,突出⽴体质感。
background: radial-gradient:径向渐变,添加底部阴影。
background: linear-gradient:线性渐变,主⾊调背景。
background: conic-gradient:圆锥渐变,最终反光⾦属效果。
依次添加以上三种渐变如下图所⽰:
⽰例完整实现代码:
button {
padding: 2px;
width: 250px;
height: 250px;
border-radius: 12px;
border: groove 1px transparent;
}
.gold {
box-shadow: inset 0 0 0 1px #eedc00, inset 0 1px 2px rgba(255, 255, 255, 0.5), inset 0 -1px 2px rgba(0, 0, 0, 0.5);
background: conic-gradient(#edc800, #e3b600, #f3cf00, #ffe800, #ffe900, #ffeb00, #ffe000, #ebc500, #e0b100, #f1cc00, #fcdc00, #d4c005fb, #fad900, #eec200, #e7b900, #f7d300, #ffe800, #ffe300, #f5d100, #e6b900, #e3b600, #f4d000, #ffe400 }
.
silver {
box-shadow: inset 0 0 0 1px #c9c9c9, inset 0 1px 2px rgba(255, 255, 255, 0.5), inset 0 -1px 2px rgba(0, 0, 0, 0.5);
background: conic-gradient(#d7d7d7, #c3c3c3, #cccccc, #c6c6c6, #d3d3d3, #d8d8d8, #d5d5d5, #d8d8d8, #d3d3d3, #c5c5c5, #c0c0c0, #bfbfbf, #d0d0d0, #d9d9d9, #d1d1d1, #c5c5c5, #c8c8c8, #d7d7d7, #d5d5d5, #cdcdcd, #c4c4c4, #d9d9d9, # }
.bronze {
box-shadow: inset 0 0 0 1px #bc7e6b, inset 0 1px 2px rgba(255, 255, 255, 0.5), inset 0 -1px 2px rgba(0, 0, 0, 0.5);
background: conic-gradient(#d95641, #b14439, #b2453a, #d25645, #d56847, #d05441, #b85137, #b2453a, #c34f40, #df4647, #a94338, #c94943, #c85442, #a4413c, #d9543a, #d1564e, #ab4338, #bb4a3c, #dc5843, #b94839, #aa4237, #c24e42, }
.titanium {
box-shadow: inset 0 0 0 1px #c7aca0, inset 0 1px 2px rgba(255, 255, 255, 0.5), inset 0 -1px 2px rgba(0, 0, 0, 0.5);
background: conic-gradient(#e6c9bf, #d2b5aa, #cbaea3, #d4b5ab, #e5c3bd, #d9c0b4, #d9bcb1, #c5a399, #e3c6bc, #e7cac0, #dec0b5, #d3b6ab, #cfada1, #d4b6ac, #e2c6c0, #e2c6c0, #d2b1a6, #d2b1a6, #d1b4a9, #e1c4ba, #e5c9be, #dec1b6, }
结合3种渐变,还能创造出更多复杂好看的⾦属材质效果,完整代码可预览⽂章尾部的对应链接 。
其他
除了上述⼏个⽅⾯,还有哪些赛博朋克风格的元素是值得我们学习的呢?通过以下⼏点,也可以提升⽹页的科技艺术感和⽤户体验,你有没有更好的想法呢?
使⽤扁平、像素化字体;
科技感满满的页⾯加载动画、滚动动画、滚动条;
中/⽇/英混杂的⽂案突出未来世界的⽂化融合;
根据⿏标移动增加透视效果,可以看我另⼀篇⽂章《如何在CSS中映射的⿏标位置,并实现通过⿏标移动控制页⾯元素效果》。
...
阅读更多
故障图⽚效果⽰例完整版
复杂的⾦属效果
标题⽂本
赛博朋克404页⾯