31 CSS Hero Sections16 / 31

Pure CSSMIT licensed

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

Live Demo
Try it

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>
.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;
  }
}
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 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 #ff5e1a on .hs-16__num / .hs-16__mark, and lime #c4f048 on 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 the letter-spacing: -0.04em and line-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, add border-radius: 999px to .hs-16__cta and swap the border: 2px solid for border: 1px solid.
  • For light-mode inversion: flip to #f5f5f0 paper, #0a0a0a ink, keep #ff5e1a and #c4f048 as-is — both accents hit AA contrast on cream. The .hs-16__mark rotation 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__mark as a <Mark> component so the -1deg rotate stays consistent.

Gotchas — read before shipping

  • The letter-spacing: -0.04em plus line-height: 0.92 combo 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 where g touches T.
  • The rotated .hs-16__mark uses transform: 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, add will-change: transform or accept it; do NOT try to fix it with backface-visibility, which regresses INP.
  • Contrast check: #a8a8a8 body copy on #0a0a0a is roughly 8.6:1 — passes WCAG AA and AAA. But lime #c4f048 on black is ~14:1 while orange #ff5e1a on 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: uppercase on .hs-16__h disables 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 to text-transform at 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__cta get 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: 900 is 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 include weight: ['400','700','900'] in the font config.

Techniques used in this demo

Search CodeFronts

Loading…