Neo-Brutalist Card — Free HTML CSS Hard Shadow Snippet
Neo-Brutalist Card · Cards · Plain HTML, CSS & JS · Live preview
What's included
Features
About this UI Snippet
Neo-Brutalist Card — Hard Shadows, Thick Borders, Tactile Press

Neo-brutalism is the high-contrast design trend that strips away soft gradients and blurred shadows in favor of thick black outlines, flat saturated color blocks, and chunky offset shadows that look like the element was cut from paper and dropped on the page. This snippet builds a complete neo-brutalist product card in plain HTML, CSS, and a few lines of vanilla JavaScript — no framework, no images, no blur filters.
The defining hard shadow
The whole look hinges on one property: box-shadow: 8px 8px 0 #111. The zero blur radius is what makes it "brutalist" — instead of a soft drop shadow, you get a crisp solid duplicate offset down and to the right, as if a second black card sits directly behind it. Combined with a 3px solid #111 border on every element, the card reads as a bold sticker rather than a floating surface. The same recipe is applied to the thumbnail, the button, and the rotated "NEW" tag so the entire composition feels consistent.
A press that moves in space
On :hover and keyboard :focus-visible the card translates up-left with translate(-4px,-4px) while the shadow grows to 12px 12px — the card appears to lift off the page. On :active it does the opposite: it translates down-right and the shadow shrinks to 4px, so clicking physically pushes the card toward its shadow like a real button. Because the transform and box-shadow both transition over .12s, the motion is snappy rather than floaty, which is exactly the brutalist feel. The button repeats this lift-and-press at a smaller scale so nested controls behave the same way.
Color as structure
Brutalism leans on flat, unapologetic color. The page background is a saturated yellow, the card is pure white, the icon tile is hot pink, the CTA is lime, and the tag is cyan — each separated by the same black border so the palette never turns muddy. There are no opacity tricks or gradients; every surface is a solid fill. This makes the card trivially themeable: swap the five hex values and you have a new variant without touching layout.
The rotated accent tag
The "NEW" badge is absolutely positioned outside the card's top edge and rotated 4deg with transform: rotate(4deg). That tiny tilt is a brutalist signature — perfectly aligned elements feel corporate, while a single rotated sticker feels handmade and energetic. Because it is a normal positioned element, you can move it to any corner or change the angle freely.
What the JavaScript adds
The aesthetic is entirely CSS; JavaScript only provides tactile feedback. Clicking the button swaps its label to "Added ✓" and inverts its colors for 1.1 seconds before reverting, giving a satisfying confirmation without a state library. A keydown handler on the card maps Enter and Space to the button so the whole component is operable from the keyboard, and stopPropagation keeps the button click from bubbling to the card.
Customizing it
Resize the shadow offset to make the card feel heavier or lighter, change the border radius from the rounded 14px to 0 for a stricter brutalist look, or drop the card into a CSS grid to build a whole bento wall of them. Pair it with a pricing card grid or use the same shadow recipe on a shimmer button to keep a consistent design language across a landing page.
Build with AI
Build, Understand, Optimize, and Extend It With AI
Rather than eyeballing the shadow numbers, paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly why a zero-blur box-shadow paired with a thick solid border is what reads as brutalist rather than a normal material-design elevation shadow, and how the hover translate and the shadow's growth from 8px to 12px are coordinated to sell the "lifting off the page" illusion. The same assistant can help optimize it, for instance checking whether the transition timing on :hover, :focus-visible, and :active is consistent enough that keyboard and mouse interactions feel identical, or whether the inline style.background/style.color mutation in the click handler should be replaced with a toggled class for easier theming. It's also useful for extending the card: ask it to generate a whole grid of these cards with randomized rotation on each tag, add a second accent color variant driven by a data attribute, or make the click confirmation state persist instead of reverting after a timeout. Treat the code less like a finished artifact and more like a starting point for a conversation.
Prompt to recreate it
Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:
Build a "neo-brutalist" product card in plain HTML, CSS, and a few lines of JavaScript using only solid colors and zero-blur box-shadows — no gradients, no blur filters, no images.
Requirements:
- A card with a thick solid border (a few pixels, one solid dark color) and a box-shadow with zero blur radius and a solid color matching the border, offset several pixels down and to the right, so it reads as a duplicate flat copy sitting behind the card rather than a soft drop shadow.
- On hover and on keyboard focus (using :focus-visible, since the card must be focusable via tabindex), the card must translate up and to the left while its shadow offset grows larger, giving the illusion the card is lifting off the page; on active/press, it must do the opposite — translate down and to the right while the shadow shrinks — so clicking visibly pushes the card toward its own shadow.
- A small badge/tag element positioned so it overlaps the card's top edge, rotated a few degrees off-axis, using the same thick-border-plus-hard-shadow treatment at a smaller scale.
- An icon tile and a call-to-action button that repeat the identical hard-shadow-and-border recipe at their own scale, each with their own hover-lift and active-press behavior independent of the outer card's.
- Every fill color on the card (background, icon tile, button, tag) must be a flat solid hex value with no gradients or transparency, so the whole palette could be swapped by changing five color values and nothing else.
- Clicking the CTA button must give brief non-navigating feedback — swap its label and invert its two colors for about a second before reverting — and pressing Enter or Space while the card itself is focused must trigger that same button action.Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.
Step by step
How to Use
- 1Paste HTML, CSS, and JSA bold yellow stage renders a white card with a hard black offset shadow.
- 2Hover or tab to the cardIt lifts up-left and the solid shadow grows, with no blur.
- 3Press itThe card pushes down-right toward its shadow like a physical button.
- 4Click Get itThe lime CTA flips to a dark Added confirmation for a moment.
- 5Recolor the paletteSwap the five flat hex fills to create a new brutalist variant.
- 6Tile into a gridDrop multiple cards into a CSS grid for a bento-style wall.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
The blur radius is zero: box-shadow: 8px 8px 0 #111 paints a solid offset copy of the element rather than a soft fade. Paired with a thick 3px solid black border, the card reads as a flat cut-out sticker instead of a floating material surface, which is the core of the neo-brutalist aesthetic.
On hover it translates up-left while the shadow grows, so it lifts off the page; on active it translates down-right and the shadow shrinks, so a click pushes it toward its shadow. Both the transform and box-shadow transition over 0.12s, giving a snappy mechanical press rather than a floaty animation.
Yes. Every surface is a flat solid fill — the yellow background, white card, pink icon tile, lime button, and cyan tag are independent hex values with no gradients or opacity. Swap any of the five colors to create a new variant without touching the layout or shadow rules.
The card has tabindex="0" and a focus-visible style identical to its hover state, so keyboard users see the same lift. A keydown handler maps Enter and Space to the CTA, and stopPropagation keeps the button from double-firing through the card. Replace the icon SVG with a real label if it conveys meaning.
The markup and CSS port directly — drop the JSX or template in and keep the class names. Move the button click and card keydown listeners into the framework: an onClick handler that toggles an added boolean in state (React), a @click and ref in Vue, or an (click)/(keydown) binding in Angular. In Tailwind, express the look with border-[3px] border-black shadow-[8px_8px_0_#111] and hover:-translate-x-1 hover:-translate-y-1.