22 CSS Brutalism

16 Pure CSS6 Light JSPublished 14 new designs · Updated on

22 hand-coded brutalist and neubrutalist designs covering the whole spectrum — from the raw anti-design brutalism of 2014 to the pastel neubrutalism that Gumroad made mainstream. Thick black borders, hard offset shadows with zero blur, and flat colour blocks throughout. Includes pastel SaaS pricing with sticker badges, an admin dashboard, a native <dialog> modal and chunky toggles, plus the harsher half: monochrome dashboards and Windows 95 chrome. Scoped under .brt-NN for no-collision pasting, prefers-reduced-motion guarded, framework-agnostic.

Related20 CSS Retro UI20 CSS Neon Effects20 CSS Minimalist UI20 CSS Claymorphism

Premium design systemPartner: Untitled UI

Affiliate link

Taking this style from one component to a whole product?

You just browsed 22 designs. Untitled UI is the Figma UI kit 380,000+ designers use, with 10,000+ components and variants in Pro, plus a matching React library on Tailwind CSS. Figma Pro is a one-time purchase from $129.

Get Untitled UI Pro

Untitled UI. We may earn a commission, at no extra cost to you.

01. Neubrutalist SaaS Pricing Cards (opens in a new tab)

Published

Pure CSSNEW
Three pastel tiers in flat blocks with a 3px black edge and a zero-blur 4px 4px 0 shadow — the whole neubrutalist grammar in one surface. The monthly/yearly switch is a real radio group read with :has(), so prices, savings copy and the billing note all change with zero JavaScript, and the CTA buttons demonstrate the press mechanic the rest of the collection reuses: translate: 2px 2px while the shadow halves.

02. Pastel Dashboard with Hard Shadows (opens in a new tab)

Published

Pure CSSNEW
A complete admin surface — sidebar, four stat blocks, a pure-CSS bar chart and a recent-activity table — where every panel is a bordered block sitting on its own hard shadow. The chart bars are a grid of <div>s sized from a single --v custom property per bar, so the data lives in the markup and the CSS never changes.

03. Neubrutalist Signup Form (opens in a new tab)

Published

Light JSNEW
A centred signup card where the inputs carry the aesthetic: a 3px black edge that thickens to 4px on :focus-visible while the offset shadow shifts, so focus is felt as movement rather than a coloured glow. Validation is announced through aria-live, the tick is a pure-CSS chunky check, and there is no submit handler — Enter and click are wired directly, which is what keeps it working inside sandboxed playground iframes.

04. Sticker Style Feature Cards (opens in a new tab)

Published

Pure CSSNEW
Six feature cards pasted onto the page at slightly different angles, each one straightening under the pointer as its shadow deepens. Every card's tilt is a single --rot value set inline, so the composition is data, not a pile of :nth-child overrides — and because rotate is its own property now, the hover transition can't fight a transform shorthand.

05. Neubrutalist Navbar with Offset Shadow (opens in a new tab)

Published

Light JSNEW
A sticky header block with a hard bottom shadow: wordmark left, links centre, black CTA right. The active link sits on a rotated pastel highlight block drawn with ::before, and at narrow widths a 20-line aria-expanded toggle opens a bordered panel — with @starting-style and transition-behavior: allow-discrete so the panel animates in and out of display:none.

06. Playful Button Set (opens in a new tab)

Published

Light JSNEW
The demo that teaches the mechanic the whole collection is built on: ten button variants — primary, pastel, outline, pill, icon-only, split, disabled, loading, toggle and destructive — all sharing one press recipe of translate: 2px 2px with the shadow halving. Every state is real (:active, :disabled, aria-busy, aria-pressed) so you can copy any row straight into a design system.
Newsletter

Enjoying these demos? Get new ones by email.

A short email when a new collection ships. Unsubscribe any time.

at

Almost there: check your inbox to confirm.Manage

07. Neubrutalist Modal Dialog (opens in a new tab)

Published

Light JSNEW
A native <dialog> opened with showModal() — so the focus trap, Escape handling and inert background come from the platform, not from 200 lines of JavaScript. The block has a pastel header strip, a black close button in the corner and a flat semi-opaque ::backdrop with no blur, because blur is the one thing this aesthetic never does.

08. Bold Testimonial Wall (opens in a new tab)

Published

Pure CSSNEW
A wall of quote cards in mixed pastel fills, laid out with CSS columns so the heights stagger naturally by quote length — real masonry without a script or a library. Each card is semantic <blockquote> plus <figcaption>, with an oversized quote mark drawn as a ::before that bleeds past the card edge.

09. Neubrutalist Blog Card Grid (opens in a new tab)

Published

Pure CSSNEW
Three article cards with black-framed cover images, a rotated pastel category chip, a heavy headline and a byline row. Hover moves the card toward its shadow rather than away from it — a small inversion of the usual lift that makes the block feel like a physical object being pressed onto the page.

10. Chunky Toggle and Checkbox Set (opens in a new tab)

Published

Pure CSSNEW
A settings panel built entirely from native inputs: three switches with thick black tracks and a hard-shadowed knob that slides, three checkboxes with heavy ticks, and two radios — every state from :checked, zero JavaScript. Each row keeps its label and a muted description, which is what makes a control set feel like a real product rather than a component demo.

11. Neubrutalist Hero Section (opens in a new tab)

Published

Pure CSSNEW
A landing hero with a clamped 4-6rem headline, one word sitting on a rotated pastel highlight block, two buttons and a bordered sticker card floating beside the copy. The load sequence is a single staggered CSS animation driven by --i per element — no JS, no observer, and it switches itself off under prefers-reduced-motion.

Published

Pure CSSNEW
Six photographs in thick black frames, each tilted at an alternating angle and sitting on a hard offset shadow. Hover or keyboard focus straightens the frame and pushes the shadow out; captions sit below in bold uppercase. Every frame declares its ratio up front, so the grid never reflows as photos arrive.

13. Neubrutalist Stats Panel (opens in a new tab)

Published

Pure CSSNEW
Four big-number blocks in alternating pastels, each with a trend arrow and delta, above a wide panel holding a segmented progress visual built from custom properties. Figures are real text with tabular-nums — not CSS counters — so they are selectable, searchable and readable by assistive tech.

Published

Pure CSSNEW
A site footer as one thick-bordered pastel block: four link columns, a newsletter row, social buttons in bordered squares and a bottom bar. Radii run 12-16px throughout, which is the clearest demonstration of how neubrutalism's softness separates it from the hard-cornered brutalist half of this collection.
Newsletter

Enjoying these demos? Get new ones by email.

A short email when a new collection ships. Unsubscribe any time.

at

Almost there: check your inbox to confirm.Manage

15. Brutalist Product Card Grid (opens in a new tab)

PublishedUpdated

Pure CSS
Raw e-commerce: Times body copy, zero radius, visible black frames on every image and prices set in plain bold. The spacing is deliberately uneven — 1rem here, 3rem there — because brutalism is anti-design, and evenly-distributed comfort is exactly the thing it refuses. Everything still works: focus states, semantic structure, real product data.

16. Brutalist Form Controls (opens in a new tab)

PublishedUpdated

Light JS
A full form rendered with its structure showing: 3px black field borders, uppercase monospace labels, a select that keeps a plain default arrow, and a submit that looks like an unstyled HTML button. Focus inverts the field to white-on-black rather than glowing, and validation is reported through a live region — with no submit handler anywhere.

17. Brutalist Data Dashboard (opens in a new tab)

PublishedUpdated

Pure CSS
Information density over comfort: a monochrome operations dashboard with a heavy-ruled data table, a black-and-white pure-CSS bar chart and stat blocks divided by 3px rules. Every number is monospace with tabular figures so columns line up to the pixel, and there is not a single rounded corner or coloured pixel in it.

18. Brutalist Portfolio Grid (opens in a new tab)

PublishedUpdated

Pure CSS
A "Selected Work" index built as numbered rows with heavy horizontal rules, oversized titles and monospace metadata. Hovering or focusing a row inverts it to black and reveals a thumbnail that follows the row — a pure-CSS preview with no JavaScript, no mouse tracking and no layout shift.

19. Brutalist Indie SaaS Pricing (opens in a new tab)

PublishedUpdated

Pure CSS
Three plans as bordered monochrome blocks with no hierarchy trickery — no scaling, no colour, no badge glow. The recommended plan is simply filled black. Prices are oversized in the system UI font, features are a plain bulleted list, and a comparison table below states everything the blocks leave out.

20. Windows 95 Desktop UI (opens in a new tab)

PublishedUpdated

Light JS
Window chrome, done properly: a beveled grey frame, a title bar with minimise/maximise/close boxes, a menu bar with a working keyboard-accessible dropdown, an inset content well, and a taskbar with a Start button and a live clock. The bevels are pure box-shadow — four inset shadows per element, no images and no borders faked with gradients.

21. Brutalist Editorial Long Read (opens in a new tab)

PublishedUpdated

Pure CSS
An editorial long read with zero decoration: an oversized serif headline, a hard-ruled byline strip, one wide-measure column, pull quotes set off by 6px rules rather than styling, and a drop cap built with initial-letter. The reading-progress bar at the top is a scroll-driven CSS animation — no scroll listener, no JavaScript at all.

22. Brutalist Streetwear Catalog (opens in a new tab)

PublishedUpdated

Pure CSS
A drop catalogue with lookbook energy and no polish: condensed uppercase type, black-framed product shots, prices in plain bold, and sizes as bordered square chips that are real radio inputs — so selection works with no JavaScript and reads correctly to a screen reader. Sold-out sizes are disabled and hatched, not merely greyed.
FAQ

Frequently asked questions

What is the difference between brutalism and neubrutalism?
They share a visual vocabulary and have opposite intentions. Brutalist web design, roughly 2014-2018, was a reaction against polished templated design — raw HTML defaults, system fonts, unstyled blue links, harsh contrast, deliberately uncomfortable. The reference was Brutalist architecture: exposed concrete, structure left visible. Neubrutalism, from about 2021, borrowed the surface — thick black borders, hard offset shadows, flat colour blocks — and dropped the ideology. It added bright pastels, rounded corners, playful illustration and careful spacing. Gumroad's 2022 redesign is the canonical example. So brutalism is anti-design; neubrutalism only looks anti-design while being fully designed and deliberately friendly. In practice searchers use the terms interchangeably, which is why this collection covers both on one page: positions 01-14 are the neubrutalist half, 15-22 the harsher original. If you are choosing between them, ask whether you want the page to feel welcoming or confrontational — that is the real decision, not the border width.
How do I make the hard offset shadow correctly?
One declaration, and the detail everyone gets wrong is the blur: box-shadow: 4px 4px 0 #000. The fourth value must be zero. A blurred shadow reads as neumorphism or plain material depth — the opposite aesthetic — and it is the single fastest way to make a brutalist design look like a mistake. Offsets are typically 4-8px on cards and 2-4px on small controls, always positive on both axes so the light reads as coming from the top left. The border matters as much: 2-4px solid black, never a lighter grey, or the shadow floats free of its shape. For the press interaction, move the element toward its own shadow and halve the offset simultaneously: :active { translate: 2px 2px; box-shadow: 2px 2px 0 #000 }. That reads as the element physically depressing. Keep the transition short — 120-200ms — because slow easing on this aesthetic feels wrong; it wants to be snappy.
What colours does neubrutalism actually use?
Bright, saturated pastels against black borders and an off-white page. The recurring palette is lilac (#c4b5fd), mint (#86efac), coral (#fda4af), butter (#fde68a) and sky (#93c5fd), with near-black #0a0a0a for borders, text and shadows. The page background is usually a warm off-white rather than pure white, which stops the pastels looking clinical. Two rules keep it from collapsing. First, use one pastel per block — the effect comes from adjacent blocks in different colours, not from gradients or blends within a block. Second, text is almost always black regardless of the fill, because black on a light pastel passes contrast easily while a coloured text on a coloured fill rarely does. The brutalist half inverts this entirely: black, white, and at most one accent, with the page itself often left at browser default. Check every combination against WCAG AA rather than trusting that a pastel is light enough.
Is brutalist design accessible?
It can be excellent or terrible, and the difference is deliberate. The aesthetic gives you two advantages for free: very high contrast, since black-on-pastel and black-on-white both clear 4.5:1 comfortably, and large obvious hit targets, because chunky is the point. Focus states are also easier than usual — a thick black or inverted outline fits the look rather than fighting it, so there is no excuse for removing the ring. The risks are specific. Historical brutalism sometimes used unreadable type sizes or hostile colour as a statement, which is a straightforward WCAG failure. Rotated elements — the sticker cards here sit at 1-2 degrees — must stay subtle, since heavy rotation harms readability for dyslexic users. And every demo in this collection guards prefers-reduced-motion, because the press-and-shift interaction is motion even though it is small. Every design here uses semantic HTML, real buttons, 44px minimum targets and visible focus rings.
How do I build the sticker or rotated card effect?
A small rotation plus the offset shadow, and the restraint is what makes it work. Apply rotate: -2deg to the card and let its shadow rotate with it — the shadow must be part of the same element, not a separate layer, or the illusion breaks. Alternate the direction between siblings (-2deg, 1.5deg, -1deg) so the grid reads as hand-placed rather than systematically skewed. Keep every angle under about 3 degrees; past that the text becomes genuinely harder to read and the effect tips from playful into chaotic. For a badge pinned to a card corner, position it absolutely with a larger rotation — 6-12 degrees is fine on a two-word label — and give it its own border and shadow so it reads as a separate sticker rather than a corner ribbon. On hover, straightening the card to rotate: 0 while deepening the shadow gives a satisfying lift. Remember rotation does not affect layout, so a rotated card can overlap its neighbour: leave gap room.
Which products actually use this style?
Neubrutalism became mainstream through indie SaaS and creator tools. Gumroad's 2022 redesign is the reference point almost everyone cites — thick borders, flat pastels, hard shadows, and a deliberate rejection of the soft gradient look that dominated SaaS before it. Figma's marketing pages, Neobrutalism.dev, Bear Blog and Poolside FM all sit in the same family, and the style spread quickly through Product Hunt launches and design-tool landing pages because it photographs well and signals independence. The harsher original brutalism has a different lineage: brutalistwebsites.com catalogued it, Craigslist embodies it accidentally, and Bloomberg Businessweek ran an editorial version around 2016. The practical read is that neubrutalism suits products wanting to feel human, small and confident — creator tools, indie SaaS, developer products. True brutalism suits work that wants to feel uncompromising or anti-commercial: portfolios, editorial, art direction. Neither suits enterprise software, where the visual noise reads as unserious.
Do these designs work in dark mode?
Yes, but the shadow needs rethinking rather than inverting. The naive approach — swap the page to dark and keep box-shadow: 4px 4px 0 #000 — makes the shadow disappear entirely, since black on near-black is invisible, and the whole aesthetic collapses because the shadow is the aesthetic. Two approaches work. Either keep the pastel blocks and switch the shadow to a light tone (a warm off-white or a brighter version of the block colour), which preserves the offset relationship while staying visible; or invert fully to a dark block with a coloured border and a coloured shadow, which reads as a neon-adjacent variant. Every demo here uses the first approach, driven by CSS custom properties on the root so the swap is a handful of token changes rather than a rewrite. Both @media (prefers-color-scheme: dark) and a [data-theme="dark"] override are supported, and each demo carries its own toggle so you can see both states.
How do these port to React, Vue, Svelte and Tailwind?
The CSS ports unchanged — every .brt-NN selector and custom property is framework-agnostic, and 16 of the 22 designs need no JavaScript at all. In component terms, the offset shadow and press interaction are worth extracting once rather than repeating: a single .brutal utility class carrying border, shadow and the :active transform can then be composed onto buttons, cards and inputs. For Tailwind, the shadow needs an arbitrary value because the default scale is all blurred — shadow-[4px_4px_0_#000] — or better, add it to your @theme block as a named token so it stays consistent. Borders map to border-[3px] border-black, and the pastels belong in your theme rather than as arbitrary hex values scattered through the markup. The six JavaScript demos are small init functions: useEffect with a returned cleanup in React, onMounted plus onBeforeUnmount in Vue, onMount returning cleanup in Svelte. The modal uses native <dialog>, so no library is needed for focus trapping.

Related collections

20 CSS 3D Effects preview

20 CSS 3D Effects

20 hand-coded CSS 3D patterns covering the transform pipeline reference build, the perspective property versus the perspective function, perspective-origin as the camera position, why transform function order changes the result, backface-visibility on two sided elements, what silently flattens preserve-3d, building a cube from six faces, transform-origin in three dimensions, translateZ versus scale for depth, z-fighting on coplanar surfaces, rotate3d and the transform matrix, plus ring layouts, stacked z-planes, pointer tilt with parallax, a hinged page-turn flipbook, a drag-rotate cube navigator, an extruded synth panel, perspective floor geometry, nested 3D contexts, and helix distribution. 14 demos are pure CSS; 6 use vanilla JavaScript.

20 CSS Claymorphism preview

20 CSS Claymorphism

20 hand-coded CSS claymorphism designs covering the three-layer shadow recipe that defines the style, inner highlight and inner shadow layering, the border radius scale that makes shapes read as puffy rather than merely rounded, claymorphism compared side by side with neumorphism, a clay and glassmorphism hybrid, single light-source discipline across a layout, depth tiers for visual hierarchy, a Tailwind implementation with both arbitrary values and theme tokens, squishy button press states, toggles and checkboxes, inset input wells and search bars, badge and pill systems, cards, popover-based modals, pricing tables, mobile tab bars, app icon grids, toast and alert bubbles, dark mode shadow recalibration, and the paint cost of animating shadows. 19 demos are pure CSS; 1 uses vanilla JavaScript.

22 CSS Dark Mode UI preview

22 CSS Dark Mode UI

22 hand-coded CSS dark-mode UI patterns — prefers-color-scheme root strategy, data-theme attribute override, color-mix token system, light-dark() function, sidebar navigation, dashboard card grid, modal dialog, focus-ring contrast audit, three-state switcher, code editor surface, OLED true black, layered slate, aurora dim and more.

Search CodeFronts

Loading…