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%
2.9 KB · 77 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-elastic-press.html7  Desc   : Springy press feedback using CSS linear() easing — no JS8  ============================================================9-->10<!--svgarden11title: Elastic press button12slug: btn-elastic-press13category: buttons14tags: [button, spring, easing, press]15difficulty: intermediate16techniques: ["linear()-easing", squash-and-stretch, transition, "@supports"]17how_it_works: >18  Real springs overshoot, rebound, and settle — motion a single cubic-bezier19  cannot describe because béziers only cross the final value once. CSS linear()20  fixes that by letting you plot the whole damped oscillation as a list of21  progress points (0, 1.28 at 35%, 0.92 at 60%, 1.04 at 80%, 1), which the22  browser connects into a piecewise curve. The press itself is a plain :active23  squash (scaleX up, scaleY down); the spring plays on release, when the24  transition back to scale(1) runs through the linear() curve. Inside the25  @supports guard we swap it in; older browsers keep a bouncy cubic-bezier that26  overshoots once — softer, but never broken.27support: "linear() easing needs Chrome 113+, Safari 17.2+ or Firefox 112+; older browsers fall back to a single-overshoot cubic-bezier."28customizable:29  - { var: "--sg-color",    label: "Color",     type: color, default: "#7F77DD" }30  - { var: "--sg-size",     label: "Font size", type: range, min: 12, max: 28, default: 17, unit: px }31  - { var: "--sg-duration", label: "Spring time", type: range, min: 0.3, max: 1.6, step: 0.05, default: 0.7, unit: s }32created: 2026-08-1033-->34<button class="sg-btn-elastic-press" type="button" style="--sg-color:#7F77DD; --sg-size:17px; --sg-duration:0.7s;">35  <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">36    <path d="M12 3 L14.6 8.6 L20.5 9.3 L16.2 13.4 L17.4 19.4 L12 16.4 L6.6 19.4 L7.8 13.4 L3.5 9.3 L9.4 8.6 Z" />37  </svg>38  Press &amp; release39</button>40<style>41  .sg-btn-elastic-press {42    appearance: none;43    border: 0;44    font: inherit;45    font-size: var(--sg-size);46    font-weight: 600;47    color: #ffffff;48    background: var(--sg-color);49    padding: 0.75em 1.6em;50    border-radius: 14px;51    cursor: pointer;52    display: inline-flex;53    align-items: center;54    gap: 0.5em;55    transform: scale(1);56    transition: transform var(--sg-duration) cubic-bezier(0.3, 1.75, 0.45, 1);57  }58  .sg-btn-elastic-press svg {59    width: 1.1em;60    height: 1.1em;61    fill: #ffffff;62    opacity: 0.9;63  }64  .sg-btn-elastic-press:active {65    transform: scale(1.08, 0.82);66    transition-duration: 0.08s;67    transition-timing-function: ease-out;68  }69  @supports (transition-timing-function: linear(0, 1)) {70    .sg-btn-elastic-press {71      transition-timing-function: linear(72        0, 0.62 18%, 1.28 35%, 0.92 60%, 1.04 80%, 0.99 92%, 173      );74    }75  }76</style>77