How to make a Cyberpunk 2077 button with CSS
Tags: css, cyberpunk2077
Published: 2020-02-27 17:56:50

---
title: How to make a Cyberpunk 2077 button with CSS
published: true
description: learn how to use pure CSS to make a simple button with cyberpunk 2077 theme
tags: CSS, Cyberpunk 2077
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/cxbzde4figpnb5wwmmt4.jpg
---

hello people! in this post, i will show you how to make a button with the theme Cyberpunk 2077 using just CSS. let's go samurai, we a have a text editor to burn 🔥

## Get Colors, Fonts and HTML structure

### Colors
to this post, i will use some specific color pallete, i will list them here:
- yellow (primary): `#fcee09`
- black: `#050a0e`
- blue: `#00f0ff`
- red (secondary): `#ff003c`

[i published this color scheme on adobe colors too](https://color.adobe.com/pt/Cyberpunk-2077-color-theme-14418458), so you can download it as CSS, SASS or SCSS.

### Fonts
for fonts, let's import some from google fonts, i picked the following set of fonts: Barlow and Tommorrow.

```css
@import url("https://fonts.googleapis.com/css?family=Barlow|Tomorrow:400,700&display=swap");
```

### HTML
for now, we will just use a pure `<button>` tag with some classes.

```html
<button class="btn">Get your copy now_</button>
```

## Building the Primary button
now let's start with the primary state of the button

```css
@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;
}
```
at this point you should have something like this:
{% jsfiddle https://jsfiddle.net/leandrorr/cxnt3ey1/40/ result,css %}

## Adding the folded corners effect
well, for this effect we can use two approaches, the first is very simple, the second is more complex (and boring), let's see how we can make that.

### Solution 1: using floating boxes in each corner
using same code above for the `.btn` class, we can use the `::before` and `::after`:

```css
.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);
}
```
**Explaining**: in the `.btn::before` we created a box of `24px` of width and height, then using `position: absolute;` to put it in the left bottom of our button, we added a `border-top` of `2px` and a `background-color` yellow, so the border of the button will not appear behind our boxes. the same was applied in `.btn::after`, we just changed the position to top right and the border to bottom.

after all this, our button should look like this:
{% jsfiddle https://jsfiddle.net/leandrorr/j8r05utv/5/ result,css %}

it looks cool, but the background color of our floating boxes is visible, the only way to hide it is to set a background color on the body with the same color as the button. 😔

{% jsfiddle https://jsfiddle.net/leandrorr/j8r05utv/7/ result,css %}

### Solution 2: using CSS clip-path
I confess, I found out that I suck at `clip-path`, it really took me a while to understand it, so using this approach we have some pros and cons:

**Pros**
- you don't need floating boxes and set a background-color on body
- clip-path works like a charm (if you know how to use this nightmare)

**Cons**
- you can't set borders on elements clipped (it sucks)
- even trying put borders with `::before` and `::after` not work (everything in the clipped area is hidden)

Now using `clip-path`, we have to modify our `.btn`class a bit, to set the borders i have to set a fixed width and height at the parent element: `<button>` then add a children element with the class `.btn__content`, with our yellow background, while the parent has black, this is a workaround to simulate a border.

```css
.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);
}
```

{% jsfiddle https://jsfiddle.net/leandrorr/cxnt3ey1/116/ result,html,css %}

we can make a default width and height and add classes to change the size of the button like: `btn--small`, `btn--large`...

### Final touch
to add more details to our button, let's just add that little label in the corner of our button:

HTML

```html
<button class="btn">
  <div class="btn__content">
  The future is now_
  </div>
  <span class="btn__label">r25</span>
</button>
```
CSS

```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;
}
```
{% jsfiddle https://jsfiddle.net/leandrorr/j420g61v/11/ result,html,css %}

below i show you the same button with the class `btn--secondary`, this changes the bg color to red.

{% jsfiddle https://jsfiddle.net/leandrorr/cxnt3ey1/121/ result,html,css %}

## Hover with glitch effect
to reproduce the glitch effect, again we use `clip-path` with transform, basically we just show the button sliced in different sizes in each step of the animation, after that we call this animation inside our `:hover`, this is applied to the `btn__content::after` and `btn__glitch` (you have to add more one `<span>` inside our button.

```html
<button class="btn">
  <span class="btn__content">Get your copy now_</span>
  <span class="btn__glitch"></span>
  <span class="btn__label">r25</span>
</button>
```

and this is the hover with the glitch element being styled:

```css
.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;
}
```

```css
/* 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;
  }
}
```

{% jsfiddle https://jsfiddle.net/leandrorr/cxnt3ey1/134/ result,html,css %}

that's it! the final code you can see in [this gist](https://gist.github.com/leandroruel/4f0e6a7919ac6ef6459abd55bc40a12e).

i made [this pen at codepen too](https://codepen.io/leandroruel/pen/XWbpbmR), check it out!

## Bonus
you can add `prefers-reduced-motion` if you are concerned with accessibility:

```css
@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;
  }
}
```
thanks for the tip Karen!
{% devcomment m3l7 %}