Opent in een nieuw tabblad

CSS-lab · Hero's

Marquee-hero met oneindige band

Een stevige hero met grote kop, intro en twee knoppen, met daaronder twee gekantelde banden die eindeloos tegen elkaar in scrollen. Pure CSS, geen JavaScript.

  • Gemiddeld
  • Pure CSS
  • MIT-licentie
  • @keyframes
  • transform: translateX
  • rotate
  • width: max-content
  • animation-play-state
HTML
<section class="mqh-hero">
  <div class="mqh-inner">
    <p class="mqh-kicker">Webdesign & branding</p>
    <h2 class="mqh-title">Websites die <span class="mqh-mark">blijven</span> hangen</h2>
    <p class="mqh-intro">Strategie, design en code onder één dak. Wij bouwen merken en sites die opvallen, snel laden en bezoekers in beweging zetten.</p>
    <div class="mqh-actions">
      <a href="#" class="mqh-btn mqh-btn--primary">Start een project <span aria-hidden="true">→</span></a>
      <a href="#" class="mqh-btn mqh-btn--ghost">Bekijk ons werk</a>
    </div>
  </div>
  <div class="mqh-bands" aria-hidden="true">
    <div class="mqh-band mqh-band--back">
      <div class="mqh-track">
        <div class="mqh-group"><span>Strategie</span><span>Design</span><span>Development</span><span>SEO</span><span>Motion</span><span>Branding</span></div>
        <div class="mqh-group"><span>Strategie</span><span>Design</span><span>Development</span><span>SEO</span><span>Motion</span><span>Branding</span></div>
      </div>
    </div>
    <div class="mqh-band">
      <div class="mqh-track">
        <div class="mqh-group"><span>Webdesign</span><span>Animatie</span><span>Conversie</span><span>Identiteit</span><span>Content</span><span>Performance</span></div>
        <div class="mqh-group"><span>Webdesign</span><span>Animatie</span><span>Conversie</span><span>Identiteit</span><span>Content</span><span>Performance</span></div>
      </div>
    </div>
  </div>
</section>
CSS
/* Marquee-hero: kop + twee gekantelde, oneindige banden */
.mqh-hero {
  --bg: #0C0C0D;
  --ink: #F9F8F6;
  --accent: #C6FF3D;
  --accent-2: #2E5BFF;
  --speed: 22s;
  --tilt: -3deg;
  position: relative;
  display: grid;
  grid-template-rows: 1fr auto;
  width: 100%;
  min-height: 520px;
  overflow: hidden;
  background: var(--bg);
  color: var(--ink);
  font-family: system-ui, sans-serif;
}

.mqh-inner {
  align-self: center;
  max-width: 960px;
  padding: clamp(32px, 6vw, 72px) clamp(20px, 5vw, 64px) 8px;
}

.mqh-kicker {
  margin: 0 0 18px;
  font: 600 12px/1 ui-monospace, Menlo, Consolas, monospace;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--accent);
}

.mqh-title {
  margin: 0;
  font-family: "Arial Black", "Helvetica Neue", Impact, system-ui, sans-serif;
  font-size: clamp(40px, 7.5vw, 96px);
  font-weight: 900;
  line-height: .92;
  letter-spacing: -.03em;
  text-transform: uppercase;
}

.mqh-mark {
  color: var(--accent);
}

.mqh-intro {
  max-width: 46ch;
  margin: 20px 0 28px;
  font-size: clamp(16px, 1.6vw, 19px);
  line-height: 1.55;
  color: rgba(249, 248, 246, .78);
}

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

/* Brutalistische knoppen met harde schaduw bij hover */
.mqh-btn {
  display: inline-flex;
  align-items: center;
  gap: .5em;
  padding: 14px 22px;
  border: 2px solid var(--ink);
  font: 700 15px/1 system-ui, sans-serif;
  color: var(--ink);
  text-decoration: none;
  transition: transform .2s ease, box-shadow .2s ease, background-color .2s ease, color .2s ease;
}

.mqh-btn--primary {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--bg);
}

.mqh-btn:hover {
  transform: translate(-3px, -3px);
  box-shadow: 3px 3px 0 var(--ink);
}

.mqh-btn--ghost:hover {
  background: var(--ink);
  color: var(--bg);
}

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

/* Banden: twee lagen die elkaar kruisen */
.mqh-bands {
  position: relative;
  height: clamp(120px, 16vw, 170px);
}

.mqh-band {
  position: absolute;
  top: 50%;
  left: -5%;
  right: -5%;
  padding: 14px 0;
  overflow: hidden;
  background: var(--accent);
  color: var(--bg);
  transform: translateY(-50%) rotate(var(--tilt));
}

.mqh-band--back {
  background: var(--accent-2);
  color: var(--ink);
  transform: translateY(-50%) rotate(calc(var(--tilt) * -1));
}

/* Track = twee identieke groepen naast elkaar */
.mqh-track {
  display: flex;
  width: max-content;
  animation: mqh-scroll var(--speed) linear infinite;
}

.mqh-band--back .mqh-track {
  animation-duration: calc(var(--speed) * 1.5);
  animation-direction: reverse;
}

.mqh-group {
  display: flex;
  flex-shrink: 0;
}

.mqh-group span {
  padding-right: .6em;
  font-family: "Arial Black", "Helvetica Neue", Impact, system-ui, sans-serif;
  font-size: clamp(22px, 3.4vw, 40px);
  font-weight: 900;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
}

.mqh-group span::after {
  content: "\2726";
  padding-left: .6em;
}

.mqh-bands:hover .mqh-track {
  animation-play-state: paused;
}

/* Precies één groep opschuiven = naadloze loop */
@keyframes mqh-scroll {
  to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .mqh-track { animation: none; }
  .mqh-btn { transition: none; }
}

Wat het is en waar je het gebruikt

Deze marquee-hero combineert een klassieke opbouw (kicker, kop, intro en twee knoppen) met twee gekantelde banden die eindeloos langs elkaar heen scrollen. De voorste band is acid lime en loopt naar links, de achterste is cobalt en loopt langzamer de andere kant op. Zo ontstaat een kruis van beweging dat direct energie geeft, zonder dat de kop zelf hoeft te bewegen.

Je gebruikt hem op de homepage van een studio, een eventpagina of een campagne waarin je in één oogopslag wilt laten zien wat je doet. De banden zijn een plek voor diensten, kernwaarden of een slogan. Ze zijn decoratief: de echte boodschap staat in de kop en de intro.

Zo werkt het

  • Naadloze loop: elke band bevat een .mqh-track met twee identieke .mqh-group-blokken. De track krijgt width: max-content en schuift met translateX(-50%) precies één groep op. Op dat moment staat groep twee waar groep één begon, dus de herstart is onzichtbaar.
  • Kantelen: de banden staan absoluut in .mqh-bands en krijgen rotate(var(--tilt)). De achterste band gebruikt calc(var(--tilt) * -1), zodat ze elkaar kruisen. Met left: -5% en right: -5% vallen de schuine hoeken buiten beeld.
  • Tegen elkaar in: de achterste track krijgt animation-direction: reverse en een duur van calc(var(--speed) * 1.5), wat diepte geeft.
  • Scheidingstekens: het sterretje tussen de woorden komt uit span::after, zodat je HTML schoon blijft.
  • Pauze: met .mqh-bands:hover .mqh-track en animation-play-state: paused staat de band stil als je eroverheen beweegt.

Aanpassen

Alle knoppen zitten als variabelen op .mqh-hero:

  • --bg en --ink: achtergrond- en tekstkleur.
  • --accent: kleur van de voorste band, de kicker en het gemarkeerde woord.
  • --accent-2: kleur van de achterste band.
  • --speed: duur van één loop; hoger is rustiger.
  • --tilt: de kanteling, bijvoorbeeld -6deg voor een wildere hoek.

Zet je meer of langere woorden in de groepen, dan verandert er niets aan de loop. Zorg wel dat één groep breder is dan het scherm, anders zie je een gat. Bij weinig woorden kopieer je ze een paar keer binnen dezelfde groep.

Toegankelijkheid en browsersupport

De banden hebben aria-hidden="true": screenreaders lezen de herhalende tekst dus niet voor. De knoppen zijn echte links met een duidelijke :focus-visible-ring. In het prefers-reduced-motion-blok staan de banden stil en vallen de overgangen weg. De techniek gebruikt alleen transforms en keyframes en werkt in alle actuele browsers, inclusief Safari en Firefox. De kop is een <h2> omdat de demo binnen een pagina staat; op je eigen homepage maak je er een <h1> van.

Verder lezen

Wil je weten welke onderdelen een hero echt laten converteren? Lees dan ons artikel over hero-secties die converteren. Zoek je beweging die verder gaat dan een losse snippet, bekijk dan wat we doen met interactief webdesign en animaties.