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%
1<!--2 ============================================================3 SVGarden — https://www.svgarden.dev4 Author : Simon-Pierre Boucher5 Contact: contact@spboucher.ai6 File : snippets/buttons/btn-split-reveal.html7 Desc : Label splits into two clipped halves revealing a second label8 ============================================================9-->10<!--svgarden11title: Split-reveal button12slug: btn-split-reveal13category: buttons14tags: [button, clip-path, split, hover]15difficulty: intermediate16techniques: ["clip-path: inset()", layered-duplicates, transition, transform]17how_it_works: >18 The visible label is actually two identical copies stacked on top of each19 other: one clipped to its top half with clip-path: inset(0 0 50% 0), the20 other to its bottom half with inset(50% 0 0 0). On hover the halves translate21 in opposite vertical directions, so the word appears to tear apart along an22 invisible seam, while a third label scales up through the gap. Clipping is23 the load-bearing trick — both copies keep their full layout size, so nothing24 reflows during the animation and the split line always stays razor-straight.25customizable:26 - { var: "--sg-color", label: "Accent", type: color, default: "#7F77DD" }27 - { var: "--sg-size", label: "Font size", type: range, min: 12, max: 26, default: 16, unit: px }28 - { var: "--sg-duration", label: "Speed", type: range, min: 0.15, max: 1.2, step: 0.05, default: 0.4, unit: s }29created: 2026-08-1030-->31<button class="sg-btn-split-reveal" type="button" style="--sg-color:#7F77DD; --sg-size:16px; --sg-duration:0.4s;">32 <span class="sg-btn-split-reveal-base" aria-hidden="true">Hover me</span>33 <span class="sg-btn-split-reveal-half sg-btn-split-reveal-top" aria-hidden="true">Hover me</span>34 <span class="sg-btn-split-reveal-half sg-btn-split-reveal-bot" aria-hidden="true">Hover me</span>35 <span class="sg-btn-split-reveal-alt">Let's go →</span>36</button>37<style>38 .sg-btn-split-reveal {39 position: relative;40 appearance: none;41 font: inherit;42 font-size: var(--sg-size);43 font-weight: 600;44 color: inherit;45 background: transparent;46 border: 1.5px solid rgba(128, 128, 128, 0.45);47 border-radius: 10px;48 padding: 0.8em 1.9em;49 cursor: pointer;50 overflow: hidden;51 transition: border-color var(--sg-duration) ease;52 }53 .sg-btn-split-reveal-base {54 visibility: hidden;55 }56 .sg-btn-split-reveal-half {57 position: absolute;58 inset: 0;59 display: grid;60 place-items: center;61 transition: transform var(--sg-duration) cubic-bezier(0.5, 0, 0.2, 1);62 }63 .sg-btn-split-reveal-top { clip-path: inset(0 0 50% 0); }64 .sg-btn-split-reveal-bot { clip-path: inset(50% 0 0 0); }65 .sg-btn-split-reveal-alt {66 position: absolute;67 inset: 0;68 display: grid;69 place-items: center;70 color: var(--sg-color);71 transform: scale(0.6);72 opacity: 0;73 transition: transform var(--sg-duration) cubic-bezier(0.3, 1.5, 0.5, 1), opacity var(--sg-duration) ease;74 }75 .sg-btn-split-reveal:hover,76 .sg-btn-split-reveal:focus-visible {77 border-color: var(--sg-color);78 }79 .sg-btn-split-reveal:hover .sg-btn-split-reveal-top,80 .sg-btn-split-reveal:focus-visible .sg-btn-split-reveal-top {81 transform: translateY(-115%);82 }83 .sg-btn-split-reveal:hover .sg-btn-split-reveal-bot,84 .sg-btn-split-reveal:focus-visible .sg-btn-split-reveal-bot {85 transform: translateY(115%);86 }87 .sg-btn-split-reveal:hover .sg-btn-split-reveal-alt,88 .sg-btn-split-reveal:focus-visible .sg-btn-split-reveal-alt {89 transform: scale(1);90 opacity: 1;91 }92</style>93