Opent in een nieuw tabblad

CSS-lab · Hero's

Mesh-gradient hero

Een hero op een bewegende mesh-gradient van violet, cobalt, lime en roze, met een frosted glas-paneel voor kop, intro en knoppen. Zonder afbeeldingen of JavaScript.

  • Gevorderd
  • Pure CSS
  • MIT-licentie
  • radial-gradient
  • background-position animatie
  • filter: blur
  • backdrop-filter
  • isolation
HTML
<section class="mgh-hero">
  <div class="mgh-panel">
    <p class="mgh-kicker"><span class="mgh-dot" aria-hidden="true"></span>Interactief webdesign</p>
    <h2 class="mgh-title">Kleur die beweegt, merken die blijven</h2>
    <p class="mgh-intro">Van eerste moodboard tot live website: wij combineren strategie, design en techniek tot een ervaring die bezoekers voelen.</p>
    <div class="mgh-actions">
      <a href="#" class="mgh-btn mgh-btn--primary">Vraag een voorstel aan</a>
      <a href="#" class="mgh-btn mgh-btn--glass">Bekijk cases</a>
    </div>
  </div>
</section>
CSS
/* Mesh-gradient hero met glas-paneel */
.mgh-hero {
  --bg: #0C0C0D;
  --ink: #F9F8F6;
  --c1: #9B5CFF;
  --c2: #2E5BFF;
  --c3: #C6FF3D;
  --c4: #FF5C8A;
  --speed: 16s;
  --blur: 18px;
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  min-height: 520px;
  padding: clamp(28px, 6vw, 72px) clamp(16px, 4vw, 48px);
  overflow: hidden;
  isolation: isolate;
  background: var(--bg);
  color: var(--ink);
  font-family: system-ui, sans-serif;
}

/* Mesh: vier radial-gradients die over elkaar schuiven */
.mgh-hero::before {
  content: "";
  position: absolute;
  inset: -20%;
  z-index: -1;
  background:
    radial-gradient(circle at 20% 30%, var(--c1) 0, transparent 38%),
    radial-gradient(circle at 80% 25%, var(--c2) 0, transparent 40%),
    radial-gradient(circle at 70% 80%, var(--c3) 0, transparent 32%),
    radial-gradient(circle at 15% 85%, var(--c4) 0, transparent 34%);
  background-size: 140% 140%;
  filter: blur(30px) saturate(130%);
  animation: mgh-mesh var(--speed) ease-in-out infinite alternate;
}

/* Fijn raster voor structuur */
.mgh-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image:
    linear-gradient(rgba(249, 248, 246, .06) 1px, transparent 1px),
    linear-gradient(90deg, rgba(249, 248, 246, .06) 1px, transparent 1px);
  background-size: 48px 48px;
}

@keyframes mgh-mesh {
  0% { background-position: 0% 0%, 100% 0%, 100% 100%, 0% 100%; }
  50% { background-position: 60% 30%, 20% 60%, 30% 20%, 90% 40%; }
  100% { background-position: 100% 100%, 0% 80%, 60% 0%, 40% 10%; }
}

/* Glas-paneel */
.mgh-panel {
  width: min(100%, 720px);
  padding: clamp(24px, 4vw, 48px);
  border: 1px solid rgba(249, 248, 246, .22);
  border-radius: 24px;
  background: rgba(12, 12, 13, .42);
  -webkit-backdrop-filter: blur(var(--blur)) saturate(140%);
  backdrop-filter: blur(var(--blur)) saturate(140%);
  box-shadow: inset 0 1px 0 rgba(249, 248, 246, .25), 0 30px 80px -30px rgba(0, 0, 0, .6);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .mgh-panel { background: rgba(12, 12, 13, .85); }
}

.mgh-kicker {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: 7px 14px;
  border: 1px solid rgba(249, 248, 246, .25);
  border-radius: 999px;
  font: 600 12px/1 ui-monospace, Menlo, Consolas, monospace;
  letter-spacing: .14em;
  text-transform: uppercase;
}

.mgh-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--c3);
  box-shadow: 0 0 0 4px rgba(198, 255, 61, .2);
}

.mgh-title {
  margin: 20px 0 0;
  font-family: "Arial Black", "Helvetica Neue", Impact, system-ui, sans-serif;
  font-size: clamp(34px, 5.6vw, 72px);
  font-weight: 900;
  line-height: 1;
  letter-spacing: -.03em;
  text-wrap: balance;
}

.mgh-intro {
  max-width: 48ch;
  margin: 18px 0 28px;
  font-size: clamp(16px, 1.5vw, 18px);
  line-height: 1.55;
  color: rgba(249, 248, 246, .85);
}

.mgh-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.mgh-btn {
  display: inline-flex;
  padding: 14px 24px;
  border: 1px solid transparent;
  border-radius: 999px;
  font: 700 15px/1 system-ui, sans-serif;
  color: var(--ink);
  text-decoration: none;
  transition: background-color .2s ease, color .2s ease;
}

.mgh-btn--primary {
  background: var(--ink);
  color: var(--bg);
}

.mgh-btn--primary:hover { background: var(--c3); }

.mgh-btn--glass {
  border-color: rgba(249, 248, 246, .35);
  background: rgba(249, 248, 246, .08);
}

.mgh-btn--glass:hover { background: rgba(249, 248, 246, .2); }

.mgh-btn:focus-visible {
  outline: 3px solid var(--c3);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .mgh-hero::before { animation: none; }
  .mgh-btn { transition: none; }
}

Wat het is en waar je het gebruikt

Mesh-gradients zie je overal in productlanceringen en SaaS-sites: zachte kleurvlekken die in elkaar overlopen en langzaam bewegen. Deze hero bouwt dat effect na met alleen CSS. Vier radial-gradients schuiven over elkaar heen, worden extra zacht door een blur en vormen samen een levende achtergrond. Daarop ligt een glas-paneel met kicker, kop, intro en twee knoppen.

Gebruik hem voor een landingspagina, een lancering of een sectie die warm en modern moet aanvoelen. Omdat er geen afbeelding of video nodig is, blijft de pagina licht en kun je de kleuren met een paar variabelen op je eigen huisstijl afstemmen.

Zo werkt het

  • De mesh: .mgh-hero::before stapelt vier radial-gradient()-lagen, elk met een kleur die naar transparent verloopt. Het pseudo-element is groter dan de hero (inset: -20%), zodat de randen van de blur nooit zichtbaar worden.
  • Beweging: elke laag krijgt background-size: 140% 140%. De keyframes mgh-mesh animeren de background-position van alle vier de lagen afzonderlijk, met alternate zodat de beweging heen en terug golft en nooit verspringt.
  • Zachtheid: filter: blur(30px) saturate(130%) laat de vlekken in elkaar overvloeien. Een tweede pseudo-element, ::after, legt er een fijn raster van 48 px overheen voor wat structuur.
  • Glas: het paneel gebruikt backdrop-filter: blur() met saturate(), een halfdoorzichtige donkere achtergrond, een lichte rand en een inset-schaduw als glimlijn aan de bovenkant.
  • Stapeling: isolation: isolate op de hero zorgt dat de pseudo-elementen met z-index: -1 netjes achter de inhoud blijven.

Aanpassen

  • --c1 tot en met --c4: de vier kleuren van de mesh.
  • --bg en --ink: basisachtergrond en tekstkleur.
  • --speed: de duur van één beweging. Lange waarden, zoals 20 tot 30 seconden, voelen het meest premium.
  • --blur: de sterkte van het matglas.

Wil je een rustiger beeld, verklein dan de stops in de gradients (bijvoorbeeld van 38% naar 28%). Zo worden de kleurvlekken kleiner en zie je meer van de donkere basis.

Toegankelijkheid en browsersupport

Het paneel heeft een donkere, halfdoorzichtige achtergrond, zodat de off-white tekst ook boven de felle lime-vlek leesbaar blijft. De knoppen hebben een duidelijke :focus-visible-ring. Met prefers-reduced-motion: reduce staat de mesh stil. backdrop-filter werkt in alle actuele browsers; voor Safari staat de -webkit--variant erbij. Ondersteunt een browser het niet, dan zorgt een @supports not-blok voor een vrijwel dichte achtergrond. Let op: blur op grote vlakken kost op oudere telefoons rekenkracht. Daarom animeert alleen de background-position en blijft de rest stil.

Verder lezen

Een mooie achtergrond is pas het begin. In ons artikel over hero-secties die converteren lees je hoe je kop, intro en call-to-action laat samenwerken. En wil je meer beweging op je site, bekijk dan onze aanpak voor interactief webdesign en animaties.