Design · Bausteine-Dossier

Kategorie

Buttons

Buttons mit Charakter — je nach Anlass auffällig oder dezent. Akzentfarbe über --akzent in einer Zeile anpassbar.

Sweep: Glanz fährt durch

Pol 1 · Craft Anlass: Primary-CTA, Premium-Auftritt

Ein Lichtreflex fährt beim Hover/Fokus über den Button, dazu leichtes Anheben. Ein Primary-CTA pro Sektion — nicht überall.

<a href="#" class="fx-btn-sweep">Jetzt anfragen</a>

<style>
.fx-btn-sweep{position:relative;display:inline-block;overflow:hidden;padding:.8rem 1.6rem;border-radius:10px;
  background:var(--akzent, #7c87ff);color:#fff;font-weight:600;text-decoration:none;font-size:.95rem;
  transition:transform .25s ease,box-shadow .25s ease}
.fx-btn-sweep::before{content:"";position:absolute;top:0;left:-120%;width:60%;height:100%;
  background:linear-gradient(120deg,transparent,rgba(255,255,255,.45),transparent);transform:skewX(-20deg);
  transition:left .6s ease}
.fx-btn-sweep:hover,.fx-btn-sweep:focus-visible{transform:translateY(-2px);box-shadow:0 8px 24px -8px var(--akzent, #7c87ff)}
.fx-btn-sweep:hover::before,.fx-btn-sweep:focus-visible::before{left:130%}
@media (prefers-reduced-motion:reduce){.fx-btn-sweep,.fx-btn-sweep::before{transition:none}.fx-btn-sweep:hover{transform:none}}
</style>

Outline: füllt sich beim Hover

Pol 2 · Klarheit Anlass: Secondary-CTA, ruhige Seiten

Zurückhaltender Umriss-Button, der beim Hover/Fokus sauber durchfärbt. Ideal als zweite Option neben einem Primary-CTA.

<a href="#" class="fx-btn-outline">Mehr erfahren</a>

<style>
.fx-btn-outline{display:inline-block;padding:.75rem 1.5rem;border-radius:10px;border:1.5px solid #3a3a45;
  color:#e9e9ee;text-decoration:none;font-weight:600;font-size:.95rem;background:transparent;
  transition:background .25s ease,border-color .25s ease,color .25s ease,transform .25s ease}
.fx-btn-outline:hover,.fx-btn-outline:focus-visible{background:#e9e9ee;color:#101014;border-color:#e9e9ee;transform:translateY(-2px)}
@media (prefers-reduced-motion:reduce){.fx-btn-outline{transition:none}.fx-btn-outline:hover{transform:none}}
</style>

Pfeil rückt nach — indirekter CTA

Pol 2 · Klarheit Anlass: Text-Link, „weiterlesen"

Der Pfeil wandert beim Hover/Fokus nach rechts — genau die indirekte Handlungsaufforderung, die dir gefällt. Dezent, überall einsetzbar.

<a href="#" class="fx-btn-arrow">Leistungen ansehen <span aria-hidden="true">→</span></a>

<style>
.fx-btn-arrow{display:inline-flex;align-items:center;gap:.5rem;padding:.75rem 1.4rem;border-radius:10px;
  background:#17171b;border:1px solid #26262c;color:#e9e9ee;text-decoration:none;font-weight:600;font-size:.95rem;
  transition:background .25s ease,border-color .25s ease}
.fx-btn-arrow span{transition:transform .25s cubic-bezier(.4,0,.2,1)}
.fx-btn-arrow:hover,.fx-btn-arrow:focus-visible{background:#1f1f26;border-color:#3a3a45}
.fx-btn-arrow:hover span,.fx-btn-arrow:focus-visible span{transform:translateX(5px)}
@media (prefers-reduced-motion:reduce){.fx-btn-arrow span{transition:none}}
</style>

Button-System: Solid · Ghost · Glass

Pol 1 · Craft Anlass: CTA-Hierarchie, Hero-Buttonpaar

Eine .fx-bs-Basis, drei Stufen: Solid (Akzent, Lift + farbiger Schatten), Ghost (Border, füllt sich beim Hover mit Akzent), Glass (Backdrop-Blur + Inset-Highlight). Deckt die komplette Button-Hierarchie einer Seite ab. Vorbild: NDS, Silver Mountain, Hauszeit.

<div class="fx-btnsys">
  <a href="#" class="fx-bs fx-bs-solid">Jetzt anfragen</a>
  <a href="#" class="fx-bs fx-bs-ghost">Mehr erfahren</a>
  <a href="#" class="fx-bs fx-bs-glass">Beratung buchen</a>
</div>

<style>
.fx-btnsys{display:flex;flex-wrap:wrap;gap:14px;align-items:center;
  padding:22px;border-radius:14px;
  background:radial-gradient(120% 140% at 20% 0%,#1d1d23,#0f0f13)}
.fx-bs{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  padding:.8rem 1.5rem;border-radius:10px;border:1px solid transparent;
  font-weight:600;font-size:.95rem;text-decoration:none;cursor:pointer;
  transition:transform .25s ease,box-shadow .25s ease,background .25s ease,border-color .25s ease,color .25s ease}
.fx-bs:focus-visible{outline:2px solid var(--akzent, #7c87ff);outline-offset:3px}
/* Solid */
.fx-bs-solid{background:var(--akzent, #7c87ff);color:#fff;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 6px 18px -8px rgba(0,0,0,.5)}
.fx-bs-solid:hover,.fx-bs-solid:focus-visible{transform:translateY(-2px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.28),0 12px 28px -8px var(--akzent, #7c87ff)}
/* Ghost */
.fx-bs-ghost{background:transparent;color:#e9e9ee;border-color:#3a3a45}
.fx-bs-ghost:hover,.fx-bs-ghost:focus-visible{background:var(--akzent, #7c87ff);
  border-color:var(--akzent, #7c87ff);color:#fff;transform:translateY(-2px)}
/* Glass */
.fx-bs-glass{color:#f4f4f5;background:rgba(255,255,255,.08);
  border-color:rgba(255,255,255,.22);
  -webkit-backdrop-filter:blur(14px) saturate(1.4);backdrop-filter:blur(14px) saturate(1.4);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.12)}
.fx-bs-glass:hover,.fx-bs-glass:focus-visible{background:rgba(255,255,255,.16);
  border-color:rgba(255,255,255,.42);transform:translateY(-2px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 12px 30px -10px rgba(0,0,0,.5)}
@media (prefers-reduced-motion:reduce){
  .fx-bs{transition:none}
  .fx-bs:hover,.fx-bs:focus-visible{transform:none}}
</style>

Sektions-Invertierung — derselbe Button, anderer Grund

Pol 2 · Klarheit Anlass: CTA-Band, Footer-CTA auf Akzentfläche

Ein und derselbe Button (.fx-inv) passt sich per Kontext-Override an seinen Untergrund an — auf dunklem Grund bleibt er Akzent, auf akzentfarbenem Grund kippt er auf hell mit Akzent-Text. Keine neue Klasse, nur ein Eltern-Selektor. Vorbild: Hauszeit Hero- und CTA-Overrides.

Dunkler Grund

Termin vereinbaren

Akzentfarbener Grund

Termin vereinbaren
<div class="fx-bands">
  <div class="fx-band fx-band--dark">
    <p class="fx-band-label">Dunkler Grund</p>
    <a href="#" class="fx-inv">Termin vereinbaren</a>
  </div>
  <div class="fx-band fx-band--accent">
    <p class="fx-band-label">Akzentfarbener Grund</p>
    <a href="#" class="fx-inv">Termin vereinbaren</a>
  </div>
</div>

<style>
.fx-bands{display:grid;gap:14px}
.fx-band{padding:26px;border-radius:14px;display:flex;flex-wrap:wrap;gap:14px;align-items:center}
.fx-band--dark{background:#101014;border:1px solid #26262c}
.fx-band--accent{background:var(--akzent, #7c87ff)}
.fx-band-label{flex:1 0 100%;margin:0 0 2px;font-size:.8rem;letter-spacing:.06em;text-transform:uppercase}
.fx-band--dark .fx-band-label{color:#a1a1aa}
.fx-band--accent .fx-band-label{color:rgba(255,255,255,.85)}
/* Basis-Button (neutral) */
.fx-inv{display:inline-flex;align-items:center;gap:.5rem;padding:.8rem 1.5rem;border-radius:10px;
  border:1px solid var(--akzent, #7c87ff);background:var(--akzent, #7c87ff);color:#fff;
  font-weight:600;font-size:.95rem;text-decoration:none;cursor:pointer;
  transition:transform .25s ease,background .25s ease,border-color .25s ease,color .25s ease}
.fx-inv:focus-visible{outline:2px solid currentColor;outline-offset:3px}
.fx-inv:hover,.fx-inv:focus-visible{transform:translateY(-2px)}
/* Override auf akzentfarbenem Grund: Button wird hell, Text = Akzent */
.fx-band--accent .fx-inv{background:#f4f4f5;border-color:#f4f4f5;color:var(--akzent, #7c87ff)}
.fx-band--accent .fx-inv:hover,.fx-band--accent .fx-inv:focus-visible{background:#fff;border-color:#fff}
/* Auf dunklem Grund bleibt der Akzent-Button, hebt aber stärker */
.fx-band--dark .fx-inv:hover,.fx-band--dark .fx-inv:focus-visible{box-shadow:0 12px 28px -8px var(--akzent, #7c87ff)}
@media (prefers-reduced-motion:reduce){
  .fx-inv{transition:none}
  .fx-inv:hover,.fx-inv:focus-visible{transform:none}}
</style>

Neomorph: weiche Lichtkanten + Inset-Highlight

Pol 1 · Craft Anlass: dezenter CTA, Card-Button auf dunkler Fläche

Hellere border-top/left simulieren einfallendes Licht, ein doppelter Schatten (außen für Tiefe + inset für den Glanzrand) gibt plastisches Relief. Beim Hover hebt der Button leicht an. Vorbild: Nördlicht.

<div class="fx-neo-stage">
  <a href="#" class="fx-neo">Angebot anfordern</a>
</div>

<style>
.fx-neo-stage{padding:30px;border-radius:14px;background:#17171b}
.fx-neo{display:inline-flex;align-items:center;gap:.5rem;padding:.85rem 1.7rem;border-radius:12px;
  background:#1f1f26;color:#f4f4f5;font-weight:600;font-size:.95rem;text-decoration:none;cursor:pointer;
  border:1px solid #2a2a32;border-top-color:rgba(255,255,255,.14);border-left-color:rgba(255,255,255,.10);
  box-shadow:0 6px 16px rgba(0,0,0,.45),inset 0 1px 1px rgba(255,255,255,.10);
  transition:transform .25s ease,box-shadow .25s ease,background .25s ease}
.fx-neo:hover,.fx-neo:focus-visible{transform:translateY(-2px);background:#24242c;
  box-shadow:0 12px 26px rgba(0,0,0,.55),inset 0 1px 2px rgba(255,255,255,.16)}
.fx-neo:focus-visible{outline:2px solid var(--akzent, #7c87ff);outline-offset:3px}
@media (prefers-reduced-motion:reduce){
  .fx-neo{transition:none}
  .fx-neo:hover,.fx-neo:focus-visible{transform:none}}
</style>

Flip: Label kippt vertikal weg

Pol 1 · Craft Anlass: CTA mit Pfiff

Beim Hover/Fokus kippt der sichtbare Text um die X-Achse nach oben weg, ein zweiter Text kippt von unten nach. Zwei Ebenen in einem overflow:hidden-Button per rotateX. Vorbild: animate-ui.

<a href="#" class="fx-flip">
  <span class="fx-flip-in">
    <span>Jetzt anfragen</span>
    <span aria-hidden="true">Los geht's</span>
  </span>
</a>

<style>
.fx-flip{position:relative;display:inline-block;overflow:hidden;padding:.85rem 1.7rem;border-radius:10px;
  background:var(--akzent, #7c87ff);color:#fff;font-weight:600;font-size:.95rem;text-decoration:none;cursor:pointer;
  perspective:600px}
.fx-flip:focus-visible{outline:2px solid var(--akzent, #7c87ff);outline-offset:3px}
.fx-flip-in{position:relative;display:block;transform-style:preserve-3d;
  transition:transform .4s cubic-bezier(.4,0,.2,1)}
.fx-flip-in span{display:block;backface-visibility:hidden}
/* zweite Ebene sitzt unter dem Button, um X-Achse vorgedreht */
.fx-flip-in span:last-child{position:absolute;top:100%;left:0;width:100%;
  transform:rotateX(-90deg);transform-origin:top center}
.fx-flip:hover .fx-flip-in,.fx-flip:focus-visible .fx-flip-in{transform:rotateX(90deg)}
@media (prefers-reduced-motion:reduce){
  .fx-flip-in{transition:none}
  .fx-flip:hover .fx-flip-in,.fx-flip:focus-visible .fx-flip-in{transform:none}
  .fx-flip:hover .fx-flip-in span:first-child,
  .fx-flip:focus-visible .fx-flip-in span:first-child{visibility:hidden}
  .fx-flip:hover .fx-flip-in span:last-child,
  .fx-flip:focus-visible .fx-flip-in span:last-child{position:static;transform:none;visibility:visible}}
</style>

Liquid: Füllung schwappt hoch

Pol 1 · Craft Anlass: Primary-CTA

Beim Hover/Fokus schwappt eine flüssige Akzent-Füllung von unten hoch, der organische Rand glättet sich; der Text kippt auf Kontrast. Umsetzung über ein ::before mit animiertem translateY und border-radius. Vorbild: animate-ui.

<a href="#" class="fx-liquid"><span>Beratung buchen</span></a>

<style>
.fx-liquid{position:relative;display:inline-block;overflow:hidden;padding:.85rem 1.8rem;border-radius:10px;
  background:transparent;border:1.5px solid var(--akzent, #7c87ff);color:var(--akzent, #7c87ff);
  font-weight:600;font-size:.95rem;text-decoration:none;cursor:pointer;
  transition:color .35s ease}
.fx-liquid::before{content:"";position:absolute;left:-10%;bottom:0;width:120%;height:120%;
  background:var(--akzent, #7c87ff);border-radius:42% 42% 0 0;
  transform:translateY(100%);
  transition:transform .5s cubic-bezier(.4,0,.2,1),border-radius .5s ease}
.fx-liquid span{position:relative;z-index:1}
.fx-liquid:hover,.fx-liquid:focus-visible{color:#fff}
.fx-liquid:hover::before,.fx-liquid:focus-visible::before{transform:translateY(0);border-radius:0}
.fx-liquid:focus-visible{outline:2px solid var(--akzent, #7c87ff);outline-offset:3px}
@media (prefers-reduced-motion:reduce){
  .fx-liquid,.fx-liquid::before{transition:none}
  .fx-liquid:hover::before,.fx-liquid:focus-visible::before{transform:translateY(0);border-radius:0}}
</style>

Ripple: Welle vom Klickpunkt

Pol 1 · Craft Anlass: Aktions-Button

Material-artige Welle, die beim Klick vom Klickpunkt aus nach außen läuft. Minimal-JS setzt ein <span> an die Klickposition, die Animation entfernt es danach selbst. Echter <button>, bei prefers-reduced-motion unterdrückt. Vorbild: animate-ui.

<button type="button" class="fx-ripple">Speichern</button>

<style>
.fx-ripple{position:relative;overflow:hidden;display:inline-flex;align-items:center;justify-content:center;
  padding:.85rem 1.8rem;border-radius:10px;border:1px solid #26262c;
  background:#17171b;color:#f4f4f5;font-weight:600;font-size:.95rem;cursor:pointer;
  transition:background .25s ease,border-color .25s ease}
.fx-ripple:hover,.fx-ripple:focus-visible{background:#1f1f26;border-color:#3a3a45}
.fx-ripple:focus-visible{outline:2px solid var(--akzent, #7c87ff);outline-offset:3px}
.fx-ripple-wave{position:absolute;border-radius:50%;pointer-events:none;
  background:var(--akzent, #7c87ff);opacity:.45;transform:scale(0);
  animation:fx-ripple-anim .6s ease-out forwards}
@keyframes fx-ripple-anim{to{transform:scale(2.4);opacity:0}}
@media (prefers-reduced-motion:reduce){
  .fx-ripple{transition:none}
  .fx-ripple-wave{display:none;animation:none}}
</style>

<script>
document.addEventListener("click",function(e){
  var btn=e.target.closest(".fx-ripple");
  if(!btn) return;
  // Reduced-motion respektieren: keine Welle erzeugen
  if(window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
  var rect=btn.getBoundingClientRect();
  var size=Math.max(rect.width,rect.height);
  var wave=document.createElement("span");
  wave.className="fx-ripple-wave";
  wave.style.width=wave.style.height=size+"px";
  wave.style.left=(e.clientX-rect.left-size/2)+"px";
  wave.style.top=(e.clientY-rect.top-size/2)+"px";
  btn.appendChild(wave);
  wave.addEventListener("animationend",function(){wave.remove();});
});
</script>

Border-Beam — Lichtpunkt umläuft den Rahmen

Pol 1 · Craft Anlass: Premium-CTA, Tech-Auftritt

Ein Lichtpunkt wandert endlos um den Button-Rand — per rotierendem conic-gradient hinter einer inneren Füllung (reines CSS, kein Bild). Akzentfarbe über --akzent. Bei prefers-reduced-motion steht der Beam still.

<button class="fx-beam" type="button"><span>Jetzt starten</span></button>

<style>
.fx-beam{position:relative;display:inline-flex;padding:2px;border:0;border-radius:12px;background:#26262c;cursor:pointer;overflow:hidden;isolation:isolate}
.fx-beam::before{content:"";position:absolute;inset:-40%;z-index:-1;
  background:conic-gradient(from 0deg,transparent 0 68%,var(--akzent,#7c87ff) 84%,transparent 100%);
  animation:fx-beam-spin 3s linear infinite}
.fx-beam span{display:block;padding:.7rem 1.5rem;border-radius:10px;background:#101014;color:#f4f4f5;font-size:.92rem;font-weight:600}
.fx-beam:hover span,.fx-beam:focus-visible span{background:#17171b}
.fx-beam:focus-visible{outline:2px solid var(--akzent,#7c87ff);outline-offset:2px}
@keyframes fx-beam-spin{to{transform:rotate(1turn)}}
@media (prefers-reduced-motion:reduce){.fx-beam::before{animation:none}}
</style>

Cursor-Glow — Glanz folgt dem Zeiger

Pol 1 · Craft Anlass: interaktiver CTA, Dark-UI

Ein weicher Licht-Spot folgt der Maus über dem Button (JS setzt nur zwei CSS-Variablen --mx/--my, den Rest macht ein radial-gradient). Beim Verlassen blendet er aus, Tastatur-Fokus zeigt ihn zentriert.

<button class="fx-glow" type="button"><span>Mehr erfahren</span></button>

<style>
.fx-glow{position:relative;overflow:hidden;border:1px solid #33333d;border-radius:12px;padding:.75rem 1.5rem;
  background:#16161a;color:#f4f4f5;font-size:.92rem;font-weight:600;cursor:pointer;transition:border-color .2s ease}
.fx-glow::before{content:"";position:absolute;inset:0;opacity:0;pointer-events:none;transition:opacity .25s ease;
  background:radial-gradient(130px circle at var(--mx,50%) var(--my,50%),var(--akzent,#7c87ff),transparent 60%)}
.fx-glow:hover::before,.fx-glow:focus-visible::before{opacity:.4}
.fx-glow:hover,.fx-glow:focus-visible{border-color:var(--akzent,#7c87ff);outline:none}
.fx-glow span{position:relative;z-index:1}
</style>

<script>
document.querySelectorAll('.fx-glow').forEach(function(b){
  b.addEventListener('pointermove',function(e){
    var r=b.getBoundingClientRect();
    b.style.setProperty('--mx',(e.clientX-r.left)+'px');
    b.style.setProperty('--my',(e.clientY-r.top)+'px');
  });
});
</script>

Verlauf-Wander — animierter Farbverlauf

Pol 1 · Craft Anlass: auffälliger Primary-CTA

Der Farbverlauf wandert langsam quer über den Button — die helle Zwischenstufe kommt per color-mix aus der Akzentfarbe, passt sich also automatisch an. Hover hebt an; bei reduzierter Bewegung steht der Verlauf still.

<button class="fx-gradient" type="button">Angebot holen</button>

<style>
.fx-gradient{border:0;border-radius:12px;padding:.78rem 1.6rem;color:#0d0d10;font-size:.92rem;font-weight:700;cursor:pointer;
  background:linear-gradient(90deg,var(--akzent,#7c87ff),color-mix(in srgb,var(--akzent,#7c87ff) 55%,#fff),var(--akzent,#7c87ff));
  background-size:200% 100%;animation:fx-grad 4s linear infinite;transition:transform .2s ease,box-shadow .2s ease}
.fx-gradient:hover,.fx-gradient:focus-visible{transform:translateY(-2px);box-shadow:0 8px 22px rgba(124,135,255,.4);outline:none}
@keyframes fx-grad{to{background-position:200% 0}}
@media (prefers-reduced-motion:reduce){.fx-gradient{animation:none;background-position:0 0}}
</style>

3D-Push — taktiler Druck-Button

Pol 2 · Klarheit Anlass: Bestätigen, App-UI

Sichtbare Unterkante (dunklere Akzent-Schattierung per color-mix); beim Klick senkt sich der Button spürbar ab — haptisches Feedback ohne Bild. Hover hebt leicht an; bei reduzierter Bewegung bleibt der Druck aus.

<button class="fx-push" type="button">Bestätigen</button>

<style>
.fx-push{position:relative;border:0;border-radius:12px;padding:.75rem 1.6rem;color:#0d0d10;font-size:.92rem;font-weight:700;cursor:pointer;
  background:var(--akzent,#7c87ff);box-shadow:0 5px 0 color-mix(in srgb,var(--akzent,#7c87ff) 55%,#000);
  transition:transform .09s ease,box-shadow .09s ease}
.fx-push:hover,.fx-push:focus-visible{transform:translateY(-1px);box-shadow:0 6px 0 color-mix(in srgb,var(--akzent,#7c87ff) 55%,#000)}
.fx-push:active{transform:translateY(4px);box-shadow:0 1px 0 color-mix(in srgb,var(--akzent,#7c87ff) 55%,#000)}
.fx-push:focus-visible{outline:2px solid #fff;outline-offset:2px}
@media (prefers-reduced-motion:reduce){.fx-push{transition:none}.fx-push:active{transform:none}}
</style>

Icon-Pill — klappt bei Hover zum Text auf

Pol 2 · Klarheit Anlass: platzsparender Aktions-Button

Kompakter runder Icon-Button, der bei Hover/Fokus sanft aufklappt und das Label zeigt — spart Platz in Leisten. aria-label sorgt dafür, dass der Zweck auch eingeklappt vorgelesen wird. Bei reduzierter Bewegung ist das Label dauerhaft sichtbar.

<button class="fx-iconpill" type="button" aria-label="Hinzufügen">
  <span class="ic"><svg …Plus-Icon…></svg></span>
  <span class="lbl">Hinzufügen</span>
</button>

<style>
.fx-iconpill{display:inline-flex;align-items:center;height:46px;padding:0;overflow:hidden;cursor:pointer;
  border:1px solid #33333d;border-radius:99px;background:#16161a;color:#f4f4f5;transition:border-color .25s ease}
.fx-iconpill .ic{flex:0 0 46px;width:46px;height:46px;display:grid;place-items:center}
.fx-iconpill .ic svg{width:18px;height:18px;color:var(--akzent,#7c87ff)}
.fx-iconpill .lbl{max-width:0;opacity:0;padding:0;white-space:nowrap;font-size:.9rem;font-weight:600;
  transition:max-width .3s ease,opacity .25s ease,padding .3s ease}
.fx-iconpill:hover,.fx-iconpill:focus-visible{border-color:var(--akzent,#7c87ff);outline:none}
.fx-iconpill:hover .lbl,.fx-iconpill:focus-visible .lbl{max-width:170px;opacity:1;padding-right:1.2rem}
@media (prefers-reduced-motion:reduce){.fx-iconpill .lbl{transition:none;max-width:170px;opacity:1;padding-right:1.2rem}}
</style>