Pure TailwindMIT licensed

Brutalist Tailwind Blockquote Design

Neo-brutalist quote: 3px ink borders, a hard shadow-[8px_8px_0_…], zero radius and a tilted sticker for attribution, on ruled-paper background. Hover presses the card halfway into its shadow; active: presses it flat. The port drops the original's tabindex="0" on a non-interactive card and gives the sticker a group-hover:rotate-1 wobble instead.

Live Demo
Plain CSSTailwind v4
Try it

Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time

Untitled UI React · Affiliate link

Get Untitled UI Pro

The code

<section class="tbq-08 w-full min-h-svh grid place-items-center bg-tbq08-bg bg-[repeating-linear-gradient(0deg,transparent_0_23px,var(--color-tbq08-line)_23px_24px)] px-6 py-16 font-tbq08-sans text-tbq08-ink" aria-label="Brutalist blockquote demo">
  <div class="grid w-full justify-items-center gap-14">
    <figure class="group relative w-full max-w-[540px]">
      <div class="border-3 border-tbq08-ink bg-tbq08-pop px-7 pt-6.5 pb-9 shadow-[8px_8px_0_var(--color-tbq08-ink)] transition-[translate,box-shadow] duration-150 ease-out hover:translate-x-1 hover:translate-y-1 hover:shadow-[4px_4px_0_var(--color-tbq08-ink)] active:translate-x-2 active:translate-y-2 active:shadow-[0_0_0_var(--color-tbq08-ink)] motion-reduce:transition-none">
        <p class="mb-4 inline-flex items-center gap-2 bg-tbq08-ink px-2.5 py-1.5 font-tbq08-mono text-[11px] font-bold tracking-[0.08em] uppercase text-tbq08-paper"><span aria-hidden="true" class="size-2 bg-tbq08-pop"></span>Quote_004.txt</p>
        <blockquote>
          <p class="text-[clamp(21px,2.8vw,28px)] leading-[1.28] font-bold tracking-[-0.02em] text-pretty">Perfection is a lie the tools sell you. Ship the thing with the seams showing — at least everyone can see how it's made.</p>
        </blockquote>
      </div>
      <figcaption class="absolute -right-2.5 -bottom-6 -rotate-2 border-3 border-tbq08-ink bg-tbq08-paper px-3 py-2 font-tbq08-mono text-[11.5px] font-bold tracking-[0.06em] shadow-[5px_5px_0_var(--color-tbq08-ink)] transition-transform duration-200 group-hover:rotate-1 motion-reduce:transition-none">— RIKO TANAKA, ZINE PUBLISHER</figcaption>
    </figure>
    <p aria-hidden="true" class="border-2 border-tbq08-ink bg-tbq08-paper px-3.5 py-2 font-tbq08-mono text-[11.5px] font-bold">shadow-[8px_8px_0] · hover:translate · active:press flat</p>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tbq08-bg: #ece8d9;
  --color-tbq08-bg: oklch(0.93 0.02 95);
  --color-tbq08-line: #d5d1c3;
  --color-tbq08-line: oklch(0.86 0.02 95);
  --color-tbq08-ink: #181611;
  --color-tbq08-ink: oklch(0.2 0.01 90);
  --color-tbq08-pop: #fadf27;
  --color-tbq08-pop: oklch(0.9 0.18 100);
  --color-tbq08-paper: #fdfcf8;
  --color-tbq08-paper: oklch(0.99 0.005 95);
  --font-tbq08-sans: 'Space Grotesk', system-ui, sans-serif;
  --font-tbq08-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
   stage is sized before the browser build compiles. */

.tbq-08 {
  width: 100%;
  min-height: 100svh;
}

Setup — do this once per project

Skip this if your project already runs Tailwind v4.

1Load Tailwind
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>

Compiles in the browser — perfect for a CodePen or a quick test, not for production.

2Add the stylesheetRequiredthe @theme block is what makes the custom utilities exist
@import "tailwindcss";

@theme {
  --color-tbq08-bg: #ece8d9;
  --color-tbq08-bg: oklch(0.93 0.02 95);
  --color-tbq08-line: #d5d1c3;
  --color-tbq08-line: oklch(0.86 0.02 95);
  --color-tbq08-ink: #181611;
  --color-tbq08-ink: oklch(0.2 0.01 90);
  --color-tbq08-pop: #fadf27;
  --color-tbq08-pop: oklch(0.9 0.18 100);
  --color-tbq08-paper: #fdfcf8;
  --color-tbq08-paper: oklch(0.99 0.005 95);
  --font-tbq08-sans: 'Space Grotesk', system-ui, sans-serif;
  --font-tbq08-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
   stage is sized before the browser build compiles. */

.tbq-08 {
  width: 100%;
  min-height: 100svh;
}
3Fonts used by this demooptional — skip if you have your own type stack
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400..700&family=JetBrains+Mono:wght@400;500;600;700&display=swap">

What changed in the port

Which parts became utilities, which stayed CSS, and why.

  • translate:4px 4px on hover became hover:translate-x-1 hover:translate-y-1; v4 emits the same standalone translate property, so the original's transition list carried over as transition-[translate,box-shadow].
  • The ruled-paper stage is one arbitrary bg-[repeating-linear-gradient(…)].
  • UI upgrade from the CSS original: removed tabindex="0" from the non-interactive card (it created a dead tab stop) and added a full active: press to zero offset, so a click feels physical.
  • UI upgrade: Space Grotesk replaces the system sans for a sharper brutalist voice, the file label gained a pop-colour square, and the sticker counter-rotates on hover (group-hover:rotate-1).
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 demo 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 Tailwind Blockquote Design
Source: https://codefronts.com/snippets/tailwind-css-blockquotes/brutalist-tailwind-blockquote-design/

Neo-brutalist quote: 3px ink borders, a hard shadow-[8px_8px_0_…], zero radius and a tilted sticker for attribution, on ruled-paper background. Hover presses the card halfway into its shadow; active: presses it flat. The port drops the original's tabindex="0" on a non-interactive card and gives the sticker a group-hover:rotate-1 wobble instead.
## HTML
```html
<section class="tbq-08 w-full min-h-svh grid place-items-center bg-tbq08-bg bg-[repeating-linear-gradient(0deg,transparent_0_23px,var(--color-tbq08-line)_23px_24px)] px-6 py-16 font-tbq08-sans text-tbq08-ink" aria-label="Brutalist blockquote demo">
  <div class="grid w-full justify-items-center gap-14">
    <figure class="group relative w-full max-w-[540px]">
      <div class="border-3 border-tbq08-ink bg-tbq08-pop px-7 pt-6.5 pb-9 shadow-[8px_8px_0_var(--color-tbq08-ink)] transition-[translate,box-shadow] duration-150 ease-out hover:translate-x-1 hover:translate-y-1 hover:shadow-[4px_4px_0_var(--color-tbq08-ink)] active:translate-x-2 active:translate-y-2 active:shadow-[0_0_0_var(--color-tbq08-ink)] motion-reduce:transition-none">
        <p class="mb-4 inline-flex items-center gap-2 bg-tbq08-ink px-2.5 py-1.5 font-tbq08-mono text-[11px] font-bold tracking-[0.08em] uppercase text-tbq08-paper"><span aria-hidden="true" class="size-2 bg-tbq08-pop"></span>Quote_004.txt</p>
        <blockquote>
          <p class="text-[clamp(21px,2.8vw,28px)] leading-[1.28] font-bold tracking-[-0.02em] text-pretty">Perfection is a lie the tools sell you. Ship the thing with the seams showing — at least everyone can see how it's made.</p>
        </blockquote>
      </div>
      <figcaption class="absolute -right-2.5 -bottom-6 -rotate-2 border-3 border-tbq08-ink bg-tbq08-paper px-3 py-2 font-tbq08-mono text-[11.5px] font-bold tracking-[0.06em] shadow-[5px_5px_0_var(--color-tbq08-ink)] transition-transform duration-200 group-hover:rotate-1 motion-reduce:transition-none">— RIKO TANAKA, ZINE PUBLISHER</figcaption>
    </figure>
    <p aria-hidden="true" class="border-2 border-tbq08-ink bg-tbq08-paper px-3.5 py-2 font-tbq08-mono text-[11.5px] font-bold">shadow-[8px_8px_0] · hover:translate · active:press flat</p>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tbq08-bg: #ece8d9;
  --color-tbq08-bg: oklch(0.93 0.02 95);
  --color-tbq08-line: #d5d1c3;
  --color-tbq08-line: oklch(0.86 0.02 95);
  --color-tbq08-ink: #181611;
  --color-tbq08-ink: oklch(0.2 0.01 90);
  --color-tbq08-pop: #fadf27;
  --color-tbq08-pop: oklch(0.9 0.18 100);
  --color-tbq08-paper: #fdfcf8;
  --color-tbq08-paper: oklch(0.99 0.005 95);
  --font-tbq08-sans: 'Space Grotesk', system-ui, sans-serif;
  --font-tbq08-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
   stage is sized before the browser build compiles. */

.tbq-08 {
  width: 100%;
  min-height: 100svh;
}
```

How this works

The press illusion is arithmetic. Move the card by N pixels and shrink the shadow offset by N; the shadow's far edge never moves, so the card appears to sink into the page:

shadow-[8px_8px_0_var(--color-tbq08-ink)]
hover:translate-x-1 hover:translate-y-1 hover:shadow-[4px_4px_0_var(--color-tbq08-ink)]
active:translate-x-2 active:translate-y-2 active:shadow-[0_0_0_var(--color-tbq08-ink)]

Transition the right properties. Tailwind v4 translate utilities write the standalone translate property, so the transition list is [translate,box-shadow] — transition-transform would miss it.

The ruled paper is a single repeating-linear-gradient with hard stops at 23px and 24px.

Make it yours

  • Different pop colour: change --color-tbq08-pop; hot pink or electric blue both read well at L ≈ 0.85.
  • Make it a link card: wrap in <a> and add focus-visible:outline-3 focus-visible:outline-dashed.
  • Chunkier: border-4 with a 12px shadow.

Gotchas — read before shipping

  • active:shadow-none would snap instead of animate — use a zero-offset shadow of the same colour so it interpolates.
  • Don't add tabindex="0" to decorative cards: it creates a tab stop that does nothing.
  • The sticker is absolutely positioned outside the card; keep horizontal padding on the section so it can't overflow narrow screens.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

Standalone translate/rotate are Chrome 104 / Safari 14.1 / Firefox 72.

Techniques used in this demo

Utilitiesfirst-class utility or variant

Arbitraryneeds bracket syntax

Search CodeFronts

Loading…