28 CSS Close Buttons27 / 28

Pure CSSMIT licensed

Brutalist Stamp Close Button

Neo-brutalism's signature move on a close button: thick 3px black border, flat acid-yellow fill, zero border-radius apology, and a hard offset shadow the button physically travels into — hover lifts it to -4px,-4px with the shadow growing to match; press SLAMS it flush with the surface. No blur anywhere; blur is fear.

Published Updated

Live Demo
Try it

The code

<section class="ccb-27" aria-label="Brutalist close button demo">
  <div class="ccb-27__card">
    <div class="ccb-27__head">
      <span class="ccb-27__tag">NOTICE №4</span>
      <button class="ccb-27__close" type="button" aria-label="Close notice">
        <span class="ccb-27__x" aria-hidden="true"></span>
      </button>
    </div>
    <p class="ccb-27__text">Your free trial ends in 3 days.</p>
  </div>
</section>
.ccb-27,
.ccb-27 *,
.ccb-27 *::before,
.ccb-27 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.ccb-27 {
  --paper: oklch(0.9 0.18 100);
  font-family: ui-monospace,'Cascadia Code',Menlo,monospace;
  width: 100%;
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 48px 24px;
  background: oklch(0.93 0.005 90);
}

.ccb-27 .ccb-27__card {
  width: min(340px,100%);
  background: #fff;
  border: 3px solid #000;
  box-shadow: 8px 8px 0 #000;
  padding: 20px;
}

.ccb-27 .ccb-27__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
}

.ccb-27 .ccb-27__tag {
  font: 700 12px/1.2 ui-monospace,Menlo,monospace;
  letter-spacing: .08em;
  background: #000;
  color: var(--paper);
  padding: 6px 8px;
}

.ccb-27 .ccb-27__text {
  font-size: 14px;
  line-height: 1.5;
  color: #000;
}

.ccb-27 .ccb-27__close {
  position: relative;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border: 3px solid #000;
  background: var(--paper);
  cursor: pointer;
  box-shadow: 4px 4px 0 #000;
  transition: transform .1s ease-out,box-shadow .1s ease-out;
}

.ccb-27 .ccb-27__close:hover {
  transform: translate(-4px,-4px);
  box-shadow: 8px 8px 0 #000;
}

.ccb-27 .ccb-27__close:active {
  transform: translate(4px,4px);
  box-shadow: 0 0 0 #000;
}

.ccb-27 .ccb-27__close:focus-visible {
  outline: 3px solid #000;
  outline-offset: 3px;
}

.ccb-27 .ccb-27__x {
  position: relative;
  width: 18px;
  height: 18px;
}

.ccb-27 .ccb-27__x::before,
.ccb-27 .ccb-27__x::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 20px;
  height: 4px;
  background: #000;
}

.ccb-27 .ccb-27__x::before {
  transform: translate(-50%,-50%) rotate(45deg);
}

.ccb-27 .ccb-27__x::after {
  transform: translate(-50%,-50%) rotate(-45deg);
}

@media (prefers-reduced-motion: reduce) {
  .ccb-27 .ccb-27__close {
    transition: none;
  }
}
/* No JavaScript — transform and a zero-blur shadow move in opposition: lift grows the shadow, press slams both flat. */
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Close Button from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Brutalist Stamp Close Button
Source: https://codefronts.com/components/css-close-buttons/brutalist-stamp/

Neo-brutalism's signature move on a close button: thick 3px black border, flat acid-yellow fill, zero border-radius apology, and a hard offset shadow the button physically travels into — hover lifts it to -4px,-4px with the shadow growing to match; press SLAMS it flush with the surface. No blur anywhere; blur is fear.
## HTML
```html
<section class="ccb-27" aria-label="Brutalist close button demo">
  <div class="ccb-27__card">
    <div class="ccb-27__head">
      <span class="ccb-27__tag">NOTICE №4</span>
      <button class="ccb-27__close" type="button" aria-label="Close notice">
        <span class="ccb-27__x" aria-hidden="true"></span>
      </button>
    </div>
    <p class="ccb-27__text">Your free trial ends in 3 days.</p>
  </div>
</section>
```
## CSS
```css
.ccb-27,
.ccb-27 *,
.ccb-27 *::before,
.ccb-27 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.ccb-27 {
  --paper: oklch(0.9 0.18 100);
  font-family: ui-monospace,'Cascadia Code',Menlo,monospace;
  width: 100%;
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 48px 24px;
  background: oklch(0.93 0.005 90);
}

.ccb-27 .ccb-27__card {
  width: min(340px,100%);
  background: #fff;
  border: 3px solid #000;
  box-shadow: 8px 8px 0 #000;
  padding: 20px;
}

.ccb-27 .ccb-27__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
}

.ccb-27 .ccb-27__tag {
  font: 700 12px/1.2 ui-monospace,Menlo,monospace;
  letter-spacing: .08em;
  background: #000;
  color: var(--paper);
  padding: 6px 8px;
}

.ccb-27 .ccb-27__text {
  font-size: 14px;
  line-height: 1.5;
  color: #000;
}

.ccb-27 .ccb-27__close {
  position: relative;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border: 3px solid #000;
  background: var(--paper);
  cursor: pointer;
  box-shadow: 4px 4px 0 #000;
  transition: transform .1s ease-out,box-shadow .1s ease-out;
}

.ccb-27 .ccb-27__close:hover {
  transform: translate(-4px,-4px);
  box-shadow: 8px 8px 0 #000;
}

.ccb-27 .ccb-27__close:active {
  transform: translate(4px,4px);
  box-shadow: 0 0 0 #000;
}

.ccb-27 .ccb-27__close:focus-visible {
  outline: 3px solid #000;
  outline-offset: 3px;
}

.ccb-27 .ccb-27__x {
  position: relative;
  width: 18px;
  height: 18px;
}

.ccb-27 .ccb-27__x::before,
.ccb-27 .ccb-27__x::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 20px;
  height: 4px;
  background: #000;
}

.ccb-27 .ccb-27__x::before {
  transform: translate(-50%,-50%) rotate(45deg);
}

.ccb-27 .ccb-27__x::after {
  transform: translate(-50%,-50%) rotate(-45deg);
}

@media (prefers-reduced-motion: reduce) {
  .ccb-27 .ccb-27__close {
    transition: none;
  }
}
```

## JavaScript
```js
/* No JavaScript — transform and a zero-blur shadow move in opposition: lift grows the shadow, press slams both flat. */
```

How this works

The paper-stack illusion is transform + box-shadow moving in exact opposition: rest is shadow 4px 4px 0 #000; hover is translate(-4px,-4px) with shadow 8px 8px 0 #000 — the element rises off the page but its shadow stays pinned to the surface. Press inverts it: translate(4px,4px) with shadow 0 0 — slammed flat. The zero-blur shadow (third value 0) is the whole aesthetic.

The × is fittingly heavy: 4px bars, square ends (border-radius:0), pure #000 on the acid fill. Focus gets brutalism's honest treatment — a thick 3px offset outline, no soft ring. Every transition is a blunt 100ms ease-out; slow morphing would betray the movement's anti-polish stance.

Make it yours

  • Acid palette rotation: yellow → cyan → magenta via --paper; keep #000 structure.
  • Heavier stock: 3px → 5px borders with 6px travel.
  • Add uppercase 'CLOSE' in a mono font beside the × for full zine energy.
  • Rotate the whole button -2deg at rest for the hand-stamped look.

Gotchas — read before shipping

  • The shadow must have ZERO blur — one pixel of softness collapses the entire aesthetic into 'bad material design'.
  • Travel distance and shadow growth must match exactly (4px lift = +4px shadow) or the physics reads wrong.
  • Brutalism still needs accessibility: the focus outline stays, contrast stays ≥7:1 — raw ≠ careless.

Browser support

ChromeSafariFirefoxEdge
111+16.4+113+111+

Nothing modern required at all — which is itself very brutalist.

Techniques used in this demo

Search CodeFronts

Loading…