11 CSS Header Designs 08 / 11

Animated Link Hover Effects Header

A micro-interaction showcase where every nav link demonstrates a different hardware-accelerated hover effect: scaleX underline wipe, clip-up text fill, background-size gradient sweep, dual-layer label swap and a bracket reveal.

Pure CSS MIT licensed
Live Demo Open in tab
Open in playground

The code

<div class="csh-08">
  <div class="csh-08__glow"></div>
  <header class="csh-08__header">
    <a href="#" class="csh-08__logo">Hover<em>FX</em></a>
    <nav class="csh-08__nav">
      <a href="#" class="csh-08__fx-underline">Underline</a>
      <a href="#" class="csh-08__fx-fill"><span class="csh-08__mask"><span data-t="Fill">Fill</span></span></a>
      <a href="#" class="csh-08__fx-sweep">Sweep</a>
      <a href="#" class="csh-08__fx-swap"><span class="csh-08__mask"><span>Swap</span><span>Swap</span></span></a>
      <a href="#" class="csh-08__fx-bracket">Bracket</a>
      <a href="#" class="csh-08__cta">Get it →</a>
    </nav>
  </header>

  <section class="csh-08__hero">
    <div>
      <h1>Hover every<br><em>link.</em></h1>
      <p class="csh-08__hint">Five distinct micro-interactions — <b>scaleX</b>, clip-up fill, <b>background-size</b> sweep, layer swap, and bracket reveal. All GPU-accelerated.</p>
    </div>
  </section>
</div>
@import url('https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;700;800&family=Fragment+Mono&display=swap');

.csh-08, .csh-08 *, .csh-08 *::before, .csh-08 *::after { box-sizing: border-box; margin: 0; padding: 0; }
.csh-08 ::selection{background:var(--acid);color:var(--ink)}
.csh-08 ::-moz-selection{background:var(--acid);color:var(--ink)}

.csh-08{
  --ink:#0d0f0e;
  --paper:#ecebe4;
  --acid:#d6f034;
  --hot:#ff4d6d;
  --sky:#4cc9f0;
  font-family:'Hanken Grotesk',sans-serif;
  background:var(--ink);color:var(--paper);
  min-height:100vh;position:relative;overflow-x:hidden;
}
.csh-08__glow{position:absolute;inset:0;z-index:0;opacity:.4;pointer-events:none;
  background:radial-gradient(50% 50% at 50% 0%,rgba(214,240,52,.16),transparent 60%)}

.csh-08__header{position:sticky;top:0;z-index:50;display:flex;align-items:center;justify-content:space-between;
  padding:20px clamp(20px,5vw,52px);background:rgba(13,15,14,.7);backdrop-filter:blur(16px);border-bottom:1px solid rgba(236,235,228,.08)}
.csh-08__logo{font-weight:800;font-size:1.4rem;letter-spacing:-.03em;text-decoration:none;color:var(--paper)}
.csh-08__logo em{font-style:normal;color:var(--acid)}
.csh-08__nav{display:flex;gap:6px;align-items:center}

/* Each link demonstrates a DIFFERENT hardware-accelerated hover micro-interaction.
   All transform/opacity based — no layout thrash, 100/100 CWV friendly. */
.csh-08__nav a{position:relative;text-decoration:none;color:var(--paper);font-weight:500;font-size:.98rem;padding:8px 4px;margin:0 12px;display:inline-block;font-family:'Fragment Mono',monospace}

/* 1 — underline wipe via scaleX */
.csh-08__fx-underline::after{content:'';position:absolute;left:4px;right:4px;bottom:4px;height:2px;background:var(--acid);transform:scaleX(0);transform-origin:right;transition:transform .4s cubic-bezier(.7,0,.2,1)}
.csh-08__fx-underline:hover::after{transform:scaleX(1);transform-origin:left}

/* 2 — text fill: a colored duplicate clips up from below. The mask wrapper is
   sized exactly to the text (overflow:hidden, line-height:1) so the second
   layer is hidden at rest instead of peeking into the link's padding. */
.csh-08__mask{display:inline-block;position:relative;overflow:hidden;line-height:1;vertical-align:top}
.csh-08__fx-fill .csh-08__mask span{display:block;transition:transform .45s cubic-bezier(.7,0,.2,1)}
.csh-08__fx-fill .csh-08__mask span::before{content:attr(data-t);position:absolute;left:0;top:100%;color:var(--hot)}
.csh-08__fx-fill:hover .csh-08__mask span{transform:translateY(-100%)}

/* 3 — background gradient sweep via background-size */
.csh-08__fx-sweep{background-image:linear-gradient(var(--sky),var(--sky));background-repeat:no-repeat;background-position:0 82%;background-size:0% 30%;transition:background-size .4s cubic-bezier(.7,0,.2,1);border-radius:3px}
.csh-08__fx-sweep:hover{background-size:100% 30%}

/* 4 — label swap: two stacked labels inside the tight mask trade places */
.csh-08__fx-swap .csh-08__mask span{display:block;transition:transform .4s cubic-bezier(.7,0,.2,1)}
.csh-08__fx-swap .csh-08__mask span:nth-child(2){position:absolute;left:0;top:0;color:var(--acid);transform:translateY(110%)}
.csh-08__fx-swap:hover .csh-08__mask span:nth-child(1){transform:translateY(-110%)}
.csh-08__fx-swap:hover .csh-08__mask span:nth-child(2){transform:translateY(0)}

/* 5 — bracket reveal */
.csh-08__fx-bracket::before,.csh-08__fx-bracket::after{position:absolute;color:var(--hot);opacity:0;transition:opacity .3s,transform .3s}
.csh-08__fx-bracket::before{content:'[';left:-4px;transform:translateX(6px)}
.csh-08__fx-bracket::after{content:']';right:-4px;transform:translateX(-6px)}
.csh-08__fx-bracket:hover{color:var(--acid)}
.csh-08__fx-bracket:hover::before,.csh-08__fx-bracket:hover::after{opacity:1;transform:translateX(0)}

.csh-08__nav a.csh-08__cta{font-family:'Fragment Mono',monospace;font-size:.8rem;background:var(--acid);color:var(--ink);padding:11px 20px;border-radius:8px;text-decoration:none;font-weight:700;margin-left:10px;overflow:visible;transition:transform .3s cubic-bezier(.34,1.56,.64,1),color .3s}
.csh-08__nav a.csh-08__cta:hover{transform:translateY(-2px);color:var(--ink)}

.csh-08__hero{position:relative;z-index:1;min-height:calc(100vh - 80px);display:grid;place-items:center;text-align:center;padding:0 24px}
.csh-08__hero h1{font-size:clamp(2.4rem,9vw,5.5rem);font-weight:800;line-height:.94;letter-spacing:-.04em}
.csh-08__hero h1 em{font-style:normal;color:var(--acid)}
.csh-08__hint{font-family:'Fragment Mono',monospace;margin-top:24px;font-size:.74rem;letter-spacing:.15em;color:rgba(236,235,228,.5);max-width:52ch}
.csh-08__hint b{color:var(--sky)}

@media (max-width:860px){.csh-08__nav a:not(.csh-08__cta){display:none}}
@media (prefers-reduced-motion: reduce){.csh-08__nav a,.csh-08__nav a *,.csh-08__nav a::after,.csh-08__nav a::before{transition:none !important}}

Search CodeFronts

Loading…