31 CSS Hero Sections16 / 31
Brutalist Text-Only
Raw Swiss-punk brutalist hero — pure black, traffic-cone orange highlight, acid lime accent, hard 8px offset shadows. No images, no soft anything.
Published
The code
<section class="hs-16" aria-label="Hero">
<div class="hs-16__stack">
<span class="hs-16__num">001 / 042</span>
<h2 class="hs-16__h">
THE WEB
<em>WAS NEVER</em>
MEANT TO
<span class="hs-16__mark">LOOK SAFE.</span>
</h2>
<p class="hs-16__p">A design studio for brands that would rather be remembered than liked.</p>
<div class="hs-16__row">
<a class="hs-16__cta hs-16__cta-pri" href="#work">[ WORK ]</a>
<a class="hs-16__cta" href="#talk">[ EMAIL ]</a>
</div>
</div>
</section><section class="hs-16" aria-label="Hero">
<div class="hs-16__stack">
<span class="hs-16__num">001 / 042</span>
<h2 class="hs-16__h">
THE WEB
<em>WAS NEVER</em>
MEANT TO
<span class="hs-16__mark">LOOK SAFE.</span>
</h2>
<p class="hs-16__p">A design studio for brands that would rather be remembered than liked.</p>
<div class="hs-16__row">
<a class="hs-16__cta hs-16__cta-pri" href="#work">[ WORK ]</a>
<a class="hs-16__cta" href="#talk">[ EMAIL ]</a>
</div>
</div>
</section>.hs-16 {
display: grid;
place-items: center;
width: 100%;
min-height: 100vh;
padding: clamp(28px, 5vw, 64px) clamp(20px, 5vw, 56px);
background: #0a0a0a;
font-family: 'Inter', system-ui, sans-serif;
color: #ffffff;
box-sizing: border-box;
}
.hs-16__stack {
max-width: 760px;
}
.hs-16__num {
display: inline-block;
font-family: 'JetBrains Mono', monospace;
font-size: 12px;
font-weight: 700;
letter-spacing: 0.2em;
background: #ff5e1a;
color: #0a0a0a;
padding: 4px 10px;
margin-bottom: 22px;
}
.hs-16__h {
margin: 0 0 22px;
font-family: 'Inter', sans-serif;
font-size: clamp(40px, 7vw, 84px);
font-weight: 900;
line-height: 0.92;
letter-spacing: -0.04em;
text-transform: uppercase;
}
.hs-16__h em {
color: #c4f048;
font-style: italic;
display: inline;
}
.hs-16__mark {
display: inline-block;
background: #ff5e1a;
color: #0a0a0a;
padding: 0 12px;
transform: rotate(-1deg);
}
.hs-16__p {
font-family: 'JetBrains Mono', monospace;
font-size: 14px;
line-height: 1.55;
color: #a8a8a8;
margin: 0 0 26px;
max-width: 480px;
border-top: 2px solid #ff5e1a;
padding-top: 14px;
}
.hs-16__row {
display: flex;
gap: 14px;
flex-wrap: wrap;
}
.hs-16__cta {
display: inline-block;
padding: 12px 18px;
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
font-weight: 700;
letter-spacing: 0.12em;
text-decoration: none;
background: transparent;
color: #fff;
border: 2px solid #fff;
transition: background 0.12s, color 0.12s;
}
.hs-16__cta:hover {
background: #fff;
color: #0a0a0a;
}
.hs-16__cta-pri {
background: #ff5e1a;
color: #0a0a0a;
border-color: #ff5e1a;
}
.hs-16__cta-pri:hover {
background: #c4f048;
border-color: #c4f048;
color: #0a0a0a;
}
@media (prefers-reduced-motion: reduce) {
.hs-16__cta {
transition: none;
}
}.hs-16 {
display: grid;
place-items: center;
width: 100%;
min-height: 100vh;
padding: clamp(28px, 5vw, 64px) clamp(20px, 5vw, 56px);
background: #0a0a0a;
font-family: 'Inter', system-ui, sans-serif;
color: #ffffff;
box-sizing: border-box;
}
.hs-16__stack {
max-width: 760px;
}
.hs-16__num {
display: inline-block;
font-family: 'JetBrains Mono', monospace;
font-size: 12px;
font-weight: 700;
letter-spacing: 0.2em;
background: #ff5e1a;
color: #0a0a0a;
padding: 4px 10px;
margin-bottom: 22px;
}
.hs-16__h {
margin: 0 0 22px;
font-family: 'Inter', sans-serif;
font-size: clamp(40px, 7vw, 84px);
font-weight: 900;
line-height: 0.92;
letter-spacing: -0.04em;
text-transform: uppercase;
}
.hs-16__h em {
color: #c4f048;
font-style: italic;
display: inline;
}
.hs-16__mark {
display: inline-block;
background: #ff5e1a;
color: #0a0a0a;
padding: 0 12px;
transform: rotate(-1deg);
}
.hs-16__p {
font-family: 'JetBrains Mono', monospace;
font-size: 14px;
line-height: 1.55;
color: #a8a8a8;
margin: 0 0 26px;
max-width: 480px;
border-top: 2px solid #ff5e1a;
padding-top: 14px;
}
.hs-16__row {
display: flex;
gap: 14px;
flex-wrap: wrap;
}
.hs-16__cta {
display: inline-block;
padding: 12px 18px;
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
font-weight: 700;
letter-spacing: 0.12em;
text-decoration: none;
background: transparent;
color: #fff;
border: 2px solid #fff;
transition: background 0.12s, color 0.12s;
}
.hs-16__cta:hover {
background: #fff;
color: #0a0a0a;
}
.hs-16__cta-pri {
background: #ff5e1a;
color: #0a0a0a;
border-color: #ff5e1a;
}
.hs-16__cta-pri:hover {
background: #c4f048;
border-color: #c4f048;
color: #0a0a0a;
}
@media (prefers-reduced-motion: reduce) {
.hs-16__cta {
transition: none;
}
}Here's a working CSS Hero Section 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 Text-Only
Source: https://codefronts.com/layouts/css-hero-sections/brutalist-text-only/
Raw Swiss-punk brutalist hero — pure black, traffic-cone orange highlight, acid lime accent, hard 8px offset shadows. No images, no soft anything.
## HTML
```html
<section class="hs-16" aria-label="Hero">
<div class="hs-16__stack">
<span class="hs-16__num">001 / 042</span>
<h2 class="hs-16__h">
THE WEB
<em>WAS NEVER</em>
MEANT TO
<span class="hs-16__mark">LOOK SAFE.</span>
</h2>
<p class="hs-16__p">A design studio for brands that would rather be remembered than liked.</p>
<div class="hs-16__row">
<a class="hs-16__cta hs-16__cta-pri" href="#work">[ WORK ]</a>
<a class="hs-16__cta" href="#talk">[ EMAIL ]</a>
</div>
</div>
</section>
```
## CSS
```css
.hs-16 {
display: grid;
place-items: center;
width: 100%;
min-height: 100vh;
padding: clamp(28px, 5vw, 64px) clamp(20px, 5vw, 56px);
background: #0a0a0a;
font-family: 'Inter', system-ui, sans-serif;
color: #ffffff;
box-sizing: border-box;
}
.hs-16__stack {
max-width: 760px;
}
.hs-16__num {
display: inline-block;
font-family: 'JetBrains Mono', monospace;
font-size: 12px;
font-weight: 700;
letter-spacing: 0.2em;
background: #ff5e1a;
color: #0a0a0a;
padding: 4px 10px;
margin-bottom: 22px;
}
.hs-16__h {
margin: 0 0 22px;
font-family: 'Inter', sans-serif;
font-size: clamp(40px, 7vw, 84px);
font-weight: 900;
line-height: 0.92;
letter-spacing: -0.04em;
text-transform: uppercase;
}
.hs-16__h em {
color: #c4f048;
font-style: italic;
display: inline;
}
.hs-16__mark {
display: inline-block;
background: #ff5e1a;
color: #0a0a0a;
padding: 0 12px;
transform: rotate(-1deg);
}
.hs-16__p {
font-family: 'JetBrains Mono', monospace;
font-size: 14px;
line-height: 1.55;
color: #a8a8a8;
margin: 0 0 26px;
max-width: 480px;
border-top: 2px solid #ff5e1a;
padding-top: 14px;
}
.hs-16__row {
display: flex;
gap: 14px;
flex-wrap: wrap;
}
.hs-16__cta {
display: inline-block;
padding: 12px 18px;
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
font-weight: 700;
letter-spacing: 0.12em;
text-decoration: none;
background: transparent;
color: #fff;
border: 2px solid #fff;
transition: background 0.12s, color 0.12s;
}
.hs-16__cta:hover {
background: #fff;
color: #0a0a0a;
}
.hs-16__cta-pri {
background: #ff5e1a;
color: #0a0a0a;
border-color: #ff5e1a;
}
.hs-16__cta-pri:hover {
background: #c4f048;
border-color: #c4f048;
color: #0a0a0a;
}
@media (prefers-reduced-motion: reduce) {
.hs-16__cta {
transition: none;
}
}
```Here's a working CSS Hero Section 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 Text-Only
Source: https://codefronts.com/layouts/css-hero-sections/brutalist-text-only/
Raw Swiss-punk brutalist hero — pure black, traffic-cone orange highlight, acid lime accent, hard 8px offset shadows. No images, no soft anything.
## HTML
```html
<section class="hs-16" aria-label="Hero">
<div class="hs-16__stack">
<span class="hs-16__num">001 / 042</span>
<h2 class="hs-16__h">
THE WEB
<em>WAS NEVER</em>
MEANT TO
<span class="hs-16__mark">LOOK SAFE.</span>
</h2>
<p class="hs-16__p">A design studio for brands that would rather be remembered than liked.</p>
<div class="hs-16__row">
<a class="hs-16__cta hs-16__cta-pri" href="#work">[ WORK ]</a>
<a class="hs-16__cta" href="#talk">[ EMAIL ]</a>
</div>
</div>
</section>
```
## CSS
```css
.hs-16 {
display: grid;
place-items: center;
width: 100%;
min-height: 100vh;
padding: clamp(28px, 5vw, 64px) clamp(20px, 5vw, 56px);
background: #0a0a0a;
font-family: 'Inter', system-ui, sans-serif;
color: #ffffff;
box-sizing: border-box;
}
.hs-16__stack {
max-width: 760px;
}
.hs-16__num {
display: inline-block;
font-family: 'JetBrains Mono', monospace;
font-size: 12px;
font-weight: 700;
letter-spacing: 0.2em;
background: #ff5e1a;
color: #0a0a0a;
padding: 4px 10px;
margin-bottom: 22px;
}
.hs-16__h {
margin: 0 0 22px;
font-family: 'Inter', sans-serif;
font-size: clamp(40px, 7vw, 84px);
font-weight: 900;
line-height: 0.92;
letter-spacing: -0.04em;
text-transform: uppercase;
}
.hs-16__h em {
color: #c4f048;
font-style: italic;
display: inline;
}
.hs-16__mark {
display: inline-block;
background: #ff5e1a;
color: #0a0a0a;
padding: 0 12px;
transform: rotate(-1deg);
}
.hs-16__p {
font-family: 'JetBrains Mono', monospace;
font-size: 14px;
line-height: 1.55;
color: #a8a8a8;
margin: 0 0 26px;
max-width: 480px;
border-top: 2px solid #ff5e1a;
padding-top: 14px;
}
.hs-16__row {
display: flex;
gap: 14px;
flex-wrap: wrap;
}
.hs-16__cta {
display: inline-block;
padding: 12px 18px;
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
font-weight: 700;
letter-spacing: 0.12em;
text-decoration: none;
background: transparent;
color: #fff;
border: 2px solid #fff;
transition: background 0.12s, color 0.12s;
}
.hs-16__cta:hover {
background: #fff;
color: #0a0a0a;
}
.hs-16__cta-pri {
background: #ff5e1a;
color: #0a0a0a;
border-color: #ff5e1a;
}
.hs-16__cta-pri:hover {
background: #c4f048;
border-color: #c4f048;
color: #0a0a0a;
}
@media (prefers-reduced-motion: reduce) {
.hs-16__cta {
transition: none;
}
}
```How this works
This brutalist hero section is a single semantic <section class="hs-16"> using display: grid; place-items: center with min-height: 100vh — one centering pattern that scales from a card slot to a full-page landing-page hero without hard-coding 100vh. Content sits inside .hs-16__stack capped at max-width: 760px, which forces the oversized headline to break into the three-line thump-thump-thump rhythm brutalism depends on. There are no images — this is a pure text-only hero, so the entire visual load falls on type weight, negative space, and two aggressive accent blocks.
The palette is deliberately violent: pure #0a0a0a paper, #ffffff ink, traffic-cone #ff5e1a for the eyebrow chip and highlight .hs-16__mark (rotated -1deg so it reads hand-stamped), and acid lime #c4f048 on the italic emphasis word for the second-look moment. Typography is Inter at font-weight: 900, letter-spacing: -0.04em, line-height: 0.92 — the tight-and-heavy setting that makes uppercase headlines feel like a poster instead of a paragraph. Body text uses JetBrains Mono to hold the design-studio register; the border-top: 2px solid #ff5e1a above the paragraph is the entire secondary hierarchy.
Why it converts: absence of imagery signals confidence in the message — Nielsen Norman research shows text-only heroes outperform image-heavy heroes for products with strong value props because there is no stock photo for the eye to skip past. The bracket-wrapped [ WORK ] CTAs read like terminal prompts, self-selecting for the technical/creative buyer the studio actually wants. Hover swaps to solid fill with transition: background 0.12s — a 120ms tap-and-flash that feels sharp instead of soft.
Make it yours
- Recolor by editing four values: the paper
#0a0a0a, ink#ffffff, traffic-cone accent#ff5e1aon.hs-16__num/.hs-16__mark, and lime#c4f048on the italic. Keep at least one chromatic accent + one contrast accent — a single-accent brutalist hero flattens into plain black-on-black. - Swap Inter for a heavier grotesque to push harder brutalist:
'Space Grotesk'at 900,'Archivo Black', or'Anton'. Keep theletter-spacing: -0.04emandline-height: 0.92— those two properties do more brutalist work than the font family itself. - Change the CTA shape: brackets are the signature — replace
[ WORK ]text with an SVG arrow if the aesthetic feels too Web-3. To pill-ify for indie-SaaS, addborder-radius: 999pxto.hs-16__ctaand swap theborder: 2px solidforborder: 1px solid. - For light-mode inversion: flip to
#f5f5f0paper,#0a0a0aink, keep#ff5e1aand#c4f048as-is — both accents hit AA contrast on cream. The.hs-16__markrotation stays; on light backgrounds it reads even more like a rubber-stamp overlay. - For Tailwind:
bg-[#0a0a0a] text-white grid place-items-center min-h-[480px]on the section,text-6xl md:text-7xl lg:text-8xl font-black uppercase tracking-tighter leading-[0.92]on the h2,bg-[#ff5e1a] text-black border-2 border-[#ff5e1a]on the primary CTA. In Next/React, extract.hs-16__markas a<Mark>component so the-1degrotate stays consistent.
Gotchas — read before shipping
- The
letter-spacing: -0.04emplusline-height: 0.92combo will collide descenders on the next line for any font that lacks tight vertical metrics — Inter and Space Grotesk are safe, but system-ui fallbacks vary wildly. Test with your actual copy, not the demo copy, or you will ship a hero wheregtouchesT. - The rotated
.hs-16__markusestransform: rotate(-1deg)on an inline-block — this creates a new stacking context and can trigger a subpixel-antialiasing shift on the highlight fill in Chromium. If the orange edge looks blurry at 1x DPR, addwill-change: transformor accept it; do NOT try to fix it withbackface-visibility, which regresses INP. - Contrast check:
#a8a8a8body copy on#0a0a0ais roughly 8.6:1 — passes WCAG AA and AAA. But lime#c4f048on black is ~14:1 while orange#ff5e1aon black is ~7.1:1 — safe for the emphasis word but dangerous if you push the orange to smaller body text. Keep accent colors reserved for headline-scale type. - The
text-transform: uppercaseon.hs-16__hdisables ligatures and can make screen readers announce individual letters on some legacy AT combos. The visible text stays lowercase in the DOM, so this is safe — but if you switch totext-transformat the span level for effects, add a visually-hidden lowercase copy for a11y (WCAG 2.5.5). - The two CTAs are visually equivalent — both
.hs-16__ctaget the same padding and border. Only the primary carries.hs-16__cta--pri(orange fill). If you clone this for a page where both CTAs should split traffic 50/50 (e.g. sign-in vs sign-up), remove the primary modifier from both; the double-primary trap otherwise splits conversion. - Framework quirk: in Next.js App Router with next/font, Inter's
font-weight: 900is a separate weight file — if you only imported 400/700, the browser synthesizes 900, which looks visibly thinner than a real black weight and kills the brutalist punch. Explicitly includeweight: ['400','700','900']in the font config.