26 CSS Dividers10 / 26
Neo-Brutalist Heavy Border Divider CSS
Brutalism's whole grammar in one divider: a 6px black slab, a hard unblurred offset shadow, zero border-radius, and a marching hazard-stripe rule built from a single repeating-linear-gradient. The trick that makes stripes scroll seamlessly is animating background-position by exactly one tile — get that number wrong and the pattern visibly stutters every loop.
Published Updated
The code
<section class="div-10" aria-label="Neo-brutalist heavy border divider demo">
<div class="div-10__stage">
<div class="div-10__card">
<p class="div-10__eyebrow">SECTION 01 / SPECS</p>
<h2 class="div-10__title">HEAVY<br>BORDERS</h2>
</div>
<hr class="div-10__slab">
<div class="div-10__hazard" role="separator" aria-label="Hazard divider">
<span class="div-10__stamp">DIVIDER</span>
</div>
<hr class="div-10__slab div-10__slab--thin">
<p class="div-10__note">Unblurred offset shadows. Zero radius. √2 stripe travel.</p>
<p class="div-10__chip">repeating-linear-gradient(45deg) · background-position × 1.414</p>
</div>
</section><section class="div-10" aria-label="Neo-brutalist heavy border divider demo">
<div class="div-10__stage">
<div class="div-10__card">
<p class="div-10__eyebrow">SECTION 01 / SPECS</p>
<h2 class="div-10__title">HEAVY<br>BORDERS</h2>
</div>
<hr class="div-10__slab">
<div class="div-10__hazard" role="separator" aria-label="Hazard divider">
<span class="div-10__stamp">DIVIDER</span>
</div>
<hr class="div-10__slab div-10__slab--thin">
<p class="div-10__note">Unblurred offset shadows. Zero radius. √2 stripe travel.</p>
<p class="div-10__chip">repeating-linear-gradient(45deg) · background-position × 1.414</p>
</div>
</section>.div-10 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--div-10-bg);
--div-10-bg: oklch(0.93 0.13 105);
--div-10-ink: oklch(0.18 0.012 265);
--div-10-acc: oklch(0.99 0 0);
--div-10-acc2: oklch(0.68 0.21 355);
--div-10-tile: 30px;
font-family: 'Segoe UI',system-ui,-apple-system,sans-serif;
color: var(--div-10-ink);
}
.div-10 *,
.div-10 *::before,
.div-10 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.div-10__stage {
min-height: 100svh;
display: grid;
place-content: center;
justify-items: stretch;
gap: clamp(18px,3.4vw,30px);
padding: clamp(28px,6vw,72px) clamp(20px,5vw,56px);
width: min(94vw,660px);
margin-inline: auto;
}
.div-10__card {
background: var(--div-10-acc);
border: 4px solid var(--div-10-ink);
box-shadow: 9px 9px 0 0 var(--div-10-ink);
padding: clamp(22px,4vw,34px);
}
.div-10__eyebrow {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
letter-spacing: .2em;
color: var(--div-10-acc2);
font-weight: 700;
margin-bottom: 10px;
}
.div-10__title {
font-size: clamp(38px,9vw,86px);
line-height: .9;
letter-spacing: -.045em;
font-weight: 900;
text-transform: uppercase;
}
.div-10__slab {
border: 0;
height: 9px;
background: var(--div-10-ink);
box-shadow: 7px 7px 0 0 var(--div-10-acc2);
}
.div-10__slab--thin {
height: 4px;
box-shadow: 5px 5px 0 0 var(--div-10-ink);
}
.div-10__hazard {
position: relative;
height: clamp(46px,7vw,62px);
border: 4px solid var(--div-10-ink);
background: repeating-linear-gradient(45deg,var(--div-10-ink) 0 calc(var(--div-10-tile)/2),var(--div-10-acc) calc(var(--div-10-tile)/2) var(--div-10-tile));
animation: div-10-march 1.15s linear infinite;
display: grid;
place-items: center;
box-shadow: 9px 9px 0 0 var(--div-10-ink);
}
@keyframes div-10-march {
to {
background-position: calc(var(--div-10-tile) * 1.414) 0;
}
}
.div-10__stamp {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: clamp(13px,2.2vw,17px);
font-weight: 800;
letter-spacing: .24em;
background: var(--div-10-bg);
border: 3px solid var(--div-10-ink);
padding: 7px 16px;
color: var(--div-10-ink);
}
.div-10__note {
font-size: clamp(14px,2vw,17px);
font-weight: 700;
line-height: 1.5;
text-transform: uppercase;
letter-spacing: .01em;
}
.div-10__chip {
justify-self: start;
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11px;
padding: 8px 14px;
border: 2.5px solid var(--div-10-ink);
background: var(--div-10-acc);
max-width: 100%;
overflow-wrap: anywhere;
}
@media (prefers-reduced-motion: reduce) {
.div-10__hazard {
animation: none;
}
}.div-10 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--div-10-bg);
--div-10-bg: oklch(0.93 0.13 105);
--div-10-ink: oklch(0.18 0.012 265);
--div-10-acc: oklch(0.99 0 0);
--div-10-acc2: oklch(0.68 0.21 355);
--div-10-tile: 30px;
font-family: 'Segoe UI',system-ui,-apple-system,sans-serif;
color: var(--div-10-ink);
}
.div-10 *,
.div-10 *::before,
.div-10 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.div-10__stage {
min-height: 100svh;
display: grid;
place-content: center;
justify-items: stretch;
gap: clamp(18px,3.4vw,30px);
padding: clamp(28px,6vw,72px) clamp(20px,5vw,56px);
width: min(94vw,660px);
margin-inline: auto;
}
.div-10__card {
background: var(--div-10-acc);
border: 4px solid var(--div-10-ink);
box-shadow: 9px 9px 0 0 var(--div-10-ink);
padding: clamp(22px,4vw,34px);
}
.div-10__eyebrow {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
letter-spacing: .2em;
color: var(--div-10-acc2);
font-weight: 700;
margin-bottom: 10px;
}
.div-10__title {
font-size: clamp(38px,9vw,86px);
line-height: .9;
letter-spacing: -.045em;
font-weight: 900;
text-transform: uppercase;
}
.div-10__slab {
border: 0;
height: 9px;
background: var(--div-10-ink);
box-shadow: 7px 7px 0 0 var(--div-10-acc2);
}
.div-10__slab--thin {
height: 4px;
box-shadow: 5px 5px 0 0 var(--div-10-ink);
}
.div-10__hazard {
position: relative;
height: clamp(46px,7vw,62px);
border: 4px solid var(--div-10-ink);
background: repeating-linear-gradient(45deg,var(--div-10-ink) 0 calc(var(--div-10-tile)/2),var(--div-10-acc) calc(var(--div-10-tile)/2) var(--div-10-tile));
animation: div-10-march 1.15s linear infinite;
display: grid;
place-items: center;
box-shadow: 9px 9px 0 0 var(--div-10-ink);
}
@keyframes div-10-march {
to {
background-position: calc(var(--div-10-tile) * 1.414) 0;
}
}
.div-10__stamp {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: clamp(13px,2.2vw,17px);
font-weight: 800;
letter-spacing: .24em;
background: var(--div-10-bg);
border: 3px solid var(--div-10-ink);
padding: 7px 16px;
color: var(--div-10-ink);
}
.div-10__note {
font-size: clamp(14px,2vw,17px);
font-weight: 700;
line-height: 1.5;
text-transform: uppercase;
letter-spacing: .01em;
}
.div-10__chip {
justify-self: start;
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11px;
padding: 8px 14px;
border: 2.5px solid var(--div-10-ink);
background: var(--div-10-acc);
max-width: 100%;
overflow-wrap: anywhere;
}
@media (prefers-reduced-motion: reduce) {
.div-10__hazard {
animation: none;
}
}Here's a working CSS Divider 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: Neo-Brutalist Heavy Border Divider CSS
Source: https://codefronts.com/snippets/css-dividers/brutalist-dividers/
Brutalism's whole grammar in one divider: a 6px black slab, a hard unblurred offset shadow, zero border-radius, and a marching hazard-stripe rule built from a single repeating-linear-gradient. The trick that makes stripes scroll seamlessly is animating background-position by exactly one tile — get that number wrong and the pattern visibly stutters every loop.
## HTML
```html
<section class="div-10" aria-label="Neo-brutalist heavy border divider demo">
<div class="div-10__stage">
<div class="div-10__card">
<p class="div-10__eyebrow">SECTION 01 / SPECS</p>
<h2 class="div-10__title">HEAVY<br>BORDERS</h2>
</div>
<hr class="div-10__slab">
<div class="div-10__hazard" role="separator" aria-label="Hazard divider">
<span class="div-10__stamp">DIVIDER</span>
</div>
<hr class="div-10__slab div-10__slab--thin">
<p class="div-10__note">Unblurred offset shadows. Zero radius. √2 stripe travel.</p>
<p class="div-10__chip">repeating-linear-gradient(45deg) · background-position × 1.414</p>
</div>
</section>
```
## CSS
```css
.div-10 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--div-10-bg);
--div-10-bg: oklch(0.93 0.13 105);
--div-10-ink: oklch(0.18 0.012 265);
--div-10-acc: oklch(0.99 0 0);
--div-10-acc2: oklch(0.68 0.21 355);
--div-10-tile: 30px;
font-family: 'Segoe UI',system-ui,-apple-system,sans-serif;
color: var(--div-10-ink);
}
.div-10 *,
.div-10 *::before,
.div-10 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.div-10__stage {
min-height: 100svh;
display: grid;
place-content: center;
justify-items: stretch;
gap: clamp(18px,3.4vw,30px);
padding: clamp(28px,6vw,72px) clamp(20px,5vw,56px);
width: min(94vw,660px);
margin-inline: auto;
}
.div-10__card {
background: var(--div-10-acc);
border: 4px solid var(--div-10-ink);
box-shadow: 9px 9px 0 0 var(--div-10-ink);
padding: clamp(22px,4vw,34px);
}
.div-10__eyebrow {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
letter-spacing: .2em;
color: var(--div-10-acc2);
font-weight: 700;
margin-bottom: 10px;
}
.div-10__title {
font-size: clamp(38px,9vw,86px);
line-height: .9;
letter-spacing: -.045em;
font-weight: 900;
text-transform: uppercase;
}
.div-10__slab {
border: 0;
height: 9px;
background: var(--div-10-ink);
box-shadow: 7px 7px 0 0 var(--div-10-acc2);
}
.div-10__slab--thin {
height: 4px;
box-shadow: 5px 5px 0 0 var(--div-10-ink);
}
.div-10__hazard {
position: relative;
height: clamp(46px,7vw,62px);
border: 4px solid var(--div-10-ink);
background: repeating-linear-gradient(45deg,var(--div-10-ink) 0 calc(var(--div-10-tile)/2),var(--div-10-acc) calc(var(--div-10-tile)/2) var(--div-10-tile));
animation: div-10-march 1.15s linear infinite;
display: grid;
place-items: center;
box-shadow: 9px 9px 0 0 var(--div-10-ink);
}
@keyframes div-10-march {
to {
background-position: calc(var(--div-10-tile) * 1.414) 0;
}
}
.div-10__stamp {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: clamp(13px,2.2vw,17px);
font-weight: 800;
letter-spacing: .24em;
background: var(--div-10-bg);
border: 3px solid var(--div-10-ink);
padding: 7px 16px;
color: var(--div-10-ink);
}
.div-10__note {
font-size: clamp(14px,2vw,17px);
font-weight: 700;
line-height: 1.5;
text-transform: uppercase;
letter-spacing: .01em;
}
.div-10__chip {
justify-self: start;
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11px;
padding: 8px 14px;
border: 2.5px solid var(--div-10-ink);
background: var(--div-10-acc);
max-width: 100%;
overflow-wrap: anywhere;
}
@media (prefers-reduced-motion: reduce) {
.div-10__hazard {
animation: none;
}
}
```Here's a working CSS Divider 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: Neo-Brutalist Heavy Border Divider CSS
Source: https://codefronts.com/snippets/css-dividers/brutalist-dividers/
Brutalism's whole grammar in one divider: a 6px black slab, a hard unblurred offset shadow, zero border-radius, and a marching hazard-stripe rule built from a single repeating-linear-gradient. The trick that makes stripes scroll seamlessly is animating background-position by exactly one tile — get that number wrong and the pattern visibly stutters every loop.
## HTML
```html
<section class="div-10" aria-label="Neo-brutalist heavy border divider demo">
<div class="div-10__stage">
<div class="div-10__card">
<p class="div-10__eyebrow">SECTION 01 / SPECS</p>
<h2 class="div-10__title">HEAVY<br>BORDERS</h2>
</div>
<hr class="div-10__slab">
<div class="div-10__hazard" role="separator" aria-label="Hazard divider">
<span class="div-10__stamp">DIVIDER</span>
</div>
<hr class="div-10__slab div-10__slab--thin">
<p class="div-10__note">Unblurred offset shadows. Zero radius. √2 stripe travel.</p>
<p class="div-10__chip">repeating-linear-gradient(45deg) · background-position × 1.414</p>
</div>
</section>
```
## CSS
```css
.div-10 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--div-10-bg);
--div-10-bg: oklch(0.93 0.13 105);
--div-10-ink: oklch(0.18 0.012 265);
--div-10-acc: oklch(0.99 0 0);
--div-10-acc2: oklch(0.68 0.21 355);
--div-10-tile: 30px;
font-family: 'Segoe UI',system-ui,-apple-system,sans-serif;
color: var(--div-10-ink);
}
.div-10 *,
.div-10 *::before,
.div-10 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.div-10__stage {
min-height: 100svh;
display: grid;
place-content: center;
justify-items: stretch;
gap: clamp(18px,3.4vw,30px);
padding: clamp(28px,6vw,72px) clamp(20px,5vw,56px);
width: min(94vw,660px);
margin-inline: auto;
}
.div-10__card {
background: var(--div-10-acc);
border: 4px solid var(--div-10-ink);
box-shadow: 9px 9px 0 0 var(--div-10-ink);
padding: clamp(22px,4vw,34px);
}
.div-10__eyebrow {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
letter-spacing: .2em;
color: var(--div-10-acc2);
font-weight: 700;
margin-bottom: 10px;
}
.div-10__title {
font-size: clamp(38px,9vw,86px);
line-height: .9;
letter-spacing: -.045em;
font-weight: 900;
text-transform: uppercase;
}
.div-10__slab {
border: 0;
height: 9px;
background: var(--div-10-ink);
box-shadow: 7px 7px 0 0 var(--div-10-acc2);
}
.div-10__slab--thin {
height: 4px;
box-shadow: 5px 5px 0 0 var(--div-10-ink);
}
.div-10__hazard {
position: relative;
height: clamp(46px,7vw,62px);
border: 4px solid var(--div-10-ink);
background: repeating-linear-gradient(45deg,var(--div-10-ink) 0 calc(var(--div-10-tile)/2),var(--div-10-acc) calc(var(--div-10-tile)/2) var(--div-10-tile));
animation: div-10-march 1.15s linear infinite;
display: grid;
place-items: center;
box-shadow: 9px 9px 0 0 var(--div-10-ink);
}
@keyframes div-10-march {
to {
background-position: calc(var(--div-10-tile) * 1.414) 0;
}
}
.div-10__stamp {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: clamp(13px,2.2vw,17px);
font-weight: 800;
letter-spacing: .24em;
background: var(--div-10-bg);
border: 3px solid var(--div-10-ink);
padding: 7px 16px;
color: var(--div-10-ink);
}
.div-10__note {
font-size: clamp(14px,2vw,17px);
font-weight: 700;
line-height: 1.5;
text-transform: uppercase;
letter-spacing: .01em;
}
.div-10__chip {
justify-self: start;
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11px;
padding: 8px 14px;
border: 2.5px solid var(--div-10-ink);
background: var(--div-10-acc);
max-width: 100%;
overflow-wrap: anywhere;
}
@media (prefers-reduced-motion: reduce) {
.div-10__hazard {
animation: none;
}
}
```How this works
Brutalist dividers are loud on purpose, and the loudness is three properties:
.slab{ height:8px; background:var(--ink);
box-shadow:6px 6px 0 0 var(--acc); } /* no blur, no spread */An unblurred, un-spread box-shadow is the entire aesthetic. Real shadows have blur; brutalist ones don't, because they aren't pretending to be light — they're pretending to be misregistered print.
The hazard rule is a tiled diagonal gradient set in motion:
.hazard{ --tile:28px;
background:repeating-linear-gradient(45deg,
var(--ink) 0 calc(var(--tile)/2),
var(--acc) calc(var(--tile)/2) var(--tile));
animation:march 1.1s linear infinite; }
@keyframes march{ to{ background-position:calc(var(--tile)*1.414) 0 } }That 1.414 is √2, and it is the whole reason the loop is seamless: a 45° repeating gradient has a horizontal period of tile ÷ sin45°, not tile. Animate by the raw tile size and the stripes jump a fraction every cycle. Reduce the angle to 0° and the multiplier becomes 1.
The stamped label sits on the rule with a solid background and a 3px border, punching a hole in the stripes exactly like the ornamental divider punches a hole in a hairline — the same technique, opposite personality.
Make it yours
- Shadow direction:
-6px 6px,6px -6pxand so on. Keeping every shadow on a page in the same direction is what makes brutalism look designed rather than broken. - Colour: the style survives any hue as long as the contrast is brutal. Try acid green oklch(0.85 0.22 130) or hot pink oklch(0.7 0.24 350) against pure black.
- Stripe angle: 45° is hazard tape, 90° is a barcode, 0° is a caution bar. Remember to adjust the animation distance (√2 at 45°, 1 at 0°/90°).
- Static version: drop the animation and add
border:3px solid var(--ink)around the stripe block for a printed-warning feel.
Gotchas — read before shipping
- Animating background-position runs on the main thread and repaints the element every frame. Keep the striped area small, or move the stripes to a pseudo-element with a transform animation instead.
- Hard shadows are invisible if the divider sits on a same-coloured surface — brutalism needs the offset colour to differ from BOTH the slab and the page.
- Pure #000 on pure #fff at large areas causes halation for some readers; oklch(0.18 0.01 260) reads as black and is measurably easier on the eye.
- A striped, animated band can trigger discomfort — always calm it under prefers-reduced-motion, and never run stripes faster than ~1 tile per second.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 113+ | 111+ |
repeating-linear-gradient, box-shadow and background-position animation work back to IE10. Only the oklch() tokens set the modern floor.