SPB Git

spb/svgarden Public

SVGarden — searchable bank of 74 self-contained SVG+CSS animation snippets (svgarden.dev)

HTML 79.2% Astro 10.3% JavaScript 6% CSS 3.7% Shell 0.8%
3.5 KB · 92 lines html
Raw Blame History
1<!--2  ============================================================3  SVGarden — https://www.svgarden.dev4  Author : Simon-Pierre Boucher5  Contact: contact@spboucher.ai6  File   : snippets/buttons/btn-magnetic-fill.html7  Desc   : Radial fill expanding from the cursor's entry side — zero JS8  ============================================================9-->10<!--svgarden11title: Magnetic fill button12slug: btn-magnetic-fill13category: buttons14tags: [button, fill, hover-zones, no-js]15difficulty: advanced16techniques: [sibling-combinator, hover-zones, transition, scale]17how_it_works: >18  CSS cannot read cursor coordinates, so this button cheats honestly: three19  invisible strips cover its left, center and right thirds, and whichever strip20  the pointer touches first uses the sibling combinator (~) to reposition a21  shared ink circle before it scales up. Repositioning has no transition while22  the scale does, so the jump is invisible and the growth reads as "the fill23  started where I entered". It is a quantized approximation — three possible24  origins, not infinite — which is exactly the trade you make for needing zero25  JavaScript.26customizable:27  - { var: "--sg-color",    label: "Fill",      type: color, default: "#7F77DD" }28  - { var: "--sg-size",     label: "Font size", type: range, min: 12, max: 26, default: 16, unit: px }29  - { var: "--sg-duration", label: "Speed",     type: range, min: 0.2, max: 1.2, step: 0.05, default: 0.45, unit: s }30created: 2026-08-1031-->32<button class="sg-btn-magnetic-fill" type="button" style="--sg-color:#7F77DD; --sg-size:16px; --sg-duration:0.45s;">33  <span class="sg-btn-magnetic-fill-zone sg-btn-magnetic-fill-zone-l" aria-hidden="true"></span>34  <span class="sg-btn-magnetic-fill-zone sg-btn-magnetic-fill-zone-c" aria-hidden="true"></span>35  <span class="sg-btn-magnetic-fill-zone sg-btn-magnetic-fill-zone-r" aria-hidden="true"></span>36  <span class="sg-btn-magnetic-fill-ink" aria-hidden="true"></span>37  <span class="sg-btn-magnetic-fill-label">Magnetic fill</span>38</button>39<style>40  .sg-btn-magnetic-fill {41    position: relative;42    appearance: none;43    font: inherit;44    font-size: var(--sg-size);45    font-weight: 600;46    color: inherit;47    background: transparent;48    border: 1.5px solid var(--sg-color);49    border-radius: 999px;50    padding: 0.75em 1.8em;51    cursor: pointer;52    overflow: hidden;53  }54  .sg-btn-magnetic-fill-zone {55    position: absolute;56    top: 0;57    bottom: 0;58    width: 34%;59    z-index: 3;60  }61  .sg-btn-magnetic-fill-zone-l { left: 0; }62  .sg-btn-magnetic-fill-zone-c { left: 33%; }63  .sg-btn-magnetic-fill-zone-r { right: 0; }64  .sg-btn-magnetic-fill-ink {65    position: absolute;66    top: 50%;67    left: 50%;68    width: 1.5em;69    height: 1.5em;70    border-radius: 50%;71    background: var(--sg-color);72    transform: translate(-50%, -50%) scale(0);73    transition: transform var(--sg-duration) ease-out;74    z-index: 1;75  }76  .sg-btn-magnetic-fill-zone-l:hover ~ .sg-btn-magnetic-fill-ink { left: 12%; }77  .sg-btn-magnetic-fill-zone-r:hover ~ .sg-btn-magnetic-fill-ink { left: 88%; }78  .sg-btn-magnetic-fill:hover .sg-btn-magnetic-fill-ink,79  .sg-btn-magnetic-fill:focus-visible .sg-btn-magnetic-fill-ink {80    transform: translate(-50%, -50%) scale(10);81  }82  .sg-btn-magnetic-fill-label {83    position: relative;84    z-index: 2;85    transition: color var(--sg-duration) ease;86  }87  .sg-btn-magnetic-fill:hover .sg-btn-magnetic-fill-label,88  .sg-btn-magnetic-fill:focus-visible .sg-btn-magnetic-fill-label {89    color: #ffffff;90  }91</style>92