如何用 CSS 制作 Cyberpunk 2077 按钮
大家好!在这篇文章中,我将向大家展示如何仅使用 CSS 制作一个以 Cyberpunk 2077 为主题的按钮。武士们,我们来吧,我们有一个文本编辑器要烧了🔥
获取颜色、字体和 HTML 结构
颜色
对于这篇文章,我将使用一些特定的调色板,我将在这里列出它们:
- 黄色(主要):#fcee09
- 黑色的:#050a0e
- 蓝色的:#00f0ff
- 红色(次要):#ff003c
我也在 Adobe Colors 上发布了这个配色方案,因此您可以将其下载为 CSS、SASS 或 SCSS。
字体
对于字体,让我们从谷歌字体导入一些,我选择了以下一组字体:Barlow 和 Tommorrow。
@import url("https://fonts.googleapis.com/css?family=Barlow|Tomorrow:400,700&display=swap");
HTML
现在,我们只会使用<button>带有一些类的纯标签。
<button class="btn">Get your copy now_</button>
构建主按钮
现在让我们从按钮的主要状态开始
@import url("https://fonts.googleapis.com/css?family=Barlow|Tomorrow:400,700&display=swap");
:root {
  --yellow-color: #fcee09; 
  --red-color: #ff003c;
  --black-color: #050a0e;
  --blue-color: #00f0ff;
}
.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  outline: none;
  background-color: var(--yellow-color);
  color: var(--black-color);
  cursor: pointer;
  padding: 20px 25px;
  position: relative;
  font-family: Tomorrow, sans-serif;
  font-size: .85rem;
  text-transform: uppercase;
}
此时你应该看到类似这样的内容:
添加折角效果
好吧,为了实现这种效果,我们可以使用两种方法,第一种方法非常简单,第二种方法更复杂(而且无聊),让我们看看如何做到这一点。
解决方案 1:在每个角落使用浮动框
对于该类,使用上面的相同代码.btn,我们可以使用::before和::after:
.btn::before {
  content: "";
  width: 24px;
  height: 24px;
  position: absolute;
  bottom: -14px;
  left: -13px;
  background-color: var(--yellow-color);
  border-top: 2px solid var(--black-color);
  transform: rotate(45deg);
}
.btn::after {
  content: "";
  width: 24px;
  height: 24px;
  position: absolute;
  top: -14px;
  right: -13px;
  background-color: var(--yellow-color);
  border-bottom: 2px solid var(--black-color);
  transform: rotate(45deg);
}
解释:在中我们创建了一个宽度和高度.btn::before的框,然后使用它将其放在按钮的左下方,我们添加了一个和黄色,因此按钮的边框不会出现在我们的框后面。在中也应用了同样的方法,我们只是将位置改为右上方,将边框改为底部。24pxposition: absolute;border-top2pxbackground-color.btn::after
完成所有这些后,我们的按钮应该如下所示:
它看起来很酷,但是我们的浮动框的背景颜色是可见的,隐藏它的唯一方法是在主体上设置与按钮相同颜色的背景颜色。😔
解决方案 2:使用 CSS clip-path
我承认,我发现我很烂clip-path,我花了一段时间才理解它,所以使用这种方法我们有一些优点和缺点:
优点
- 你不需要浮动框并在主体上设置背景颜色
- clip-path 非常有效(如果你知道如何使用这个噩梦)
缺点
- 你不能在被剪切的元素上设置边框(这很糟糕)
- 甚至尝试放置边框::before但::after不起作用(剪切区域中的所有内容都被隐藏)
现在使用clip-path,我们必须.btn稍微修改一下我们的类,为了设置边框,我必须在父元素上设置固定的宽度和高度:<button>然后添加一个带有类的子元素.btn__content,带有黄色背景,而父元素为黑色,这是一种模拟边框的解决方法。
.btn {
  width: 230px;
  height: 60px; 
  border: 0;
  outline: none;
  background-color: var(--black-color);
  cursor: pointer;
  position: relative;
  font-family: Tomorrow, sans-serif;
  font-size: .85rem;
  text-transform: uppercase;
  color: var(--black-color);
  clip-path: polygon(92% 0, 100% 25%, 100% 100%, 8% 100%, 0% 75%, 0 0);
}
.btn__content {
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
  top: 2px;
  left: 2px;
  right: 2px;
  bottom: 2px;
  background-color: var(--yellow-color);
  clip-path: polygon(92% 0, 100% 25%, 100% 100%, 8% 100%, 0% 75%, 0 0);
}
我们可以设置默认的宽度和高度,并添加类来改变按钮的大小,如:btn--small,btn--large...
最后的润色
为了给我们的按钮添加更多细节,我们只需在按钮的角落添加一个小标签:
HTML
<button class="btn">
  <div class="btn__content">
  The future is now_
  </div>
  <span class="btn__label">r25</span>
</button>
CSS
.btn__label {
  height: 10px;
  font-size: .40rem;
  position: absolute;
  bottom: -4px;
  right: 8%;
  padding: 0 5px;
  background-color: var(--yellow-color);
  z-index: 3;
}
下面我向您展示了具有该类的相同按钮btn--secondary,这会将背景颜色更改为红色。
悬停时出现故障效果
为了重现故障效果,我们再次使用clip-path变换,基本上我们只是在动画的每个步骤中显示以不同大小切片的按钮,之后我们在我们的里面调用这个动画:hover,这应用于btn__content::after和btn__glitch(你必须在我们的按钮里面添加更多)<span>。
<button class="btn">
  <span class="btn__content">Get your copy now_</span>
  <span class="btn__glitch"></span>
  <span class="btn__label">r25</span>
</button>
这是带有故障元素样式的悬停:
.btn__glitch {
  display: none;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: var(--yellow-color);
  filter: drop-shadow(-2px 3px #67e3f3) drop-shadow(-1px -3px #02d8f3) drop-shadow(2px 1px #02d8f3);
}
.btn--secondary .btn__glitch {
  background-color: var(--red-color);
}
.btn:hover .btn__glitch,
.btn:hover .btn__content::after,
.btn:focus .btn__glitch,
.btn:focus .btn__content::after {
  display: block;
  animation: glitch-animation 2s linear 0s infinite;
}
/* secret trick */
@keyframes glitch-animation {
  0% {
    opacity: 1;
    transform: translateZ(0);
    clip-path: polygon(0 2%, 100% 2%, 100% 5%, 0 5%);
  }
  2% {
    clip-path: polygon(0 78%, 100% 78%, 100% 100%, 0 100%);
    transform: translate(-5px);
  }
  6% {
    clip-path: polygon(0 78%, 100% 78%, 100% 100%, 0 100%);
    transform: translate(5px);
  }
  8% {
    clip-path: polygon(0 78%, 100% 78%, 100% 100%, 0 100%);
    transform: translate(-5px);
  }
  9% {
    clip-path: polygon(0 78%, 100% 78%, 100% 100%, 0 100%);
    transform: translate(0);
  }
  10% {
    clip-path: polygon(0 54%, 100% 54%, 100% 44%, 0 44%);
    transform: translate3d(5px, 0, 0);
  }
  13% {
    clip-path: polygon(0 54%, 100% 54%, 100% 44%, 0 44%);
    transform: translateZ(0);
  }
  13.1% {
    clip-path: polygon(0 0, 0 0, 0 0, 0 0);
    transform: translate3d(5px, 0, 0);
  }
  15% {
    clip-path: polygon(0 60%, 100% 60%, 100% 40%, 0 40%);
    transform: translate3d(5px, 0, 0);
  }
  20% {
    clip-path: polygon(0 60%, 100% 60%, 100% 40%, 0 40%);
    transform: translate3d(-5px, 0, 0);
  }
  20.1% {
    clip-path: polygon(0 0, 0 0, 0 0, 0 0);
    transform: translate3d(5px, 0, 0);
  }
  25% {
    clip-path: polygon(0 85%, 100% 85%, 100% 40%, 0 40%);
    transform: translate3d(5px, 0, 0);
  }
  30% {
    clip-path: polygon(0 85%, 100% 85%, 100% 40%, 0 40%);
    transform: translate3d(-5px, 0, 0);
  }
  30.1% {
    clip-path: polygon(0 0, 0 0, 0 0, 0 0);
  }
  35% {
    clip-path: polygon(0 63%, 100% 63%, 100% 80%, 0 80%);
    transform: translate(-5px);
  }
  40% {
    clip-path: polygon(0 63%, 100% 63%, 100% 80%, 0 80%);
    transform: translate(5px);
  }
  45% {
    clip-path: polygon(0 63%, 100% 63%, 100% 80%, 0 80%);
    transform: translate(-5px);
  }
  50% {
    clip-path: polygon(0 63%, 100% 63%, 100% 80%, 0 80%);
    transform: translate(0);
  }
  55% {
    clip-path: polygon(0 10%, 100% 10%, 100% 0, 0 0);
    transform: translate3d(5px, 0, 0);
  }
  60% {
    clip-path: polygon(0 10%, 100% 10%, 100% 0, 0 0);
    transform: translateZ(0);
    opacity: 1;
  }
  60.1% {
    clip-path: polygon(0 0, 0 0, 0 0, 0 0);
    opacity: 1;
  }
  to {
    clip-path: polygon(0 0, 0 0, 0 0, 0 0);
    opacity: 1;
  }
}
就是这样!您可以在此要点中看到最终的代码。
我也在 codepen 上制作了这支笔,看看吧!
奖金
prefers-reduced-motion如果您担心可访问性,可以添加:
@media (prefers-reduced-motion: reduce) {
  .btn:hover .btn__glitch,
  .btn:hover .btn__content::after,
  .btn:focus .btn__glitch,
  .btn:focus .btn__content::after {
    display: none;
    animation: none;
  }
}
感谢 Karen 的提示!
 后端开发教程 - Java、Spring Boot 实战 - msg200.com
            后端开发教程 - Java、Spring Boot 实战 - msg200.com
          
这真是太酷了!谢谢你发这篇文章!
您是否考虑过
prefers-reduced-motion为对动作敏感的人们添加媒体查询?做得很棒,谢谢分享!