#212121
1.sparkle-button { 2 --active: 0; 3 --bg: radial-gradient( 4 40% 50% at center 100%, 5 hsl(270 calc(var(--active) * 97%) 72% / var(--active)), 6 transparent 7 ), 8 radial-gradient( 9 80% 100% at center 120%, 10 hsl(260 calc(var(--active) * 97%) 70% / var(--active)), 11 transparent 12 ), 13 hsl(260 calc(var(--active) * 97%) calc((var(--active) * 44%) + 12%)); 14 background: var(--bg); 15 font-size: 1.2rem; 16 font-weight: 500; 17 border: 0; 18 cursor: pointer; 19 padding: 1em 1em; 20 display: flex; 21 align-items: center; 22 gap: 0.25em; 23 white-space: nowrap; 24 border-radius: 100px; 25 position: relative; 26 box-shadow: 0 0 calc(var(--active) * 3em) calc(var(--active) * 1em) hsl(260 97% 61% / 0.75), 27 0 0em 0 0 hsl(260 calc(var(--active) * 97%) calc((var(--active) * 50%) + 30%)) inset, 28 0 -0.05em 0 0 hsl(260 calc(var(--active) * 97%) calc(var(--active) * 60%)) inset; 29 transition: box-shadow var(--transition), scale var(--transition), background var(--transition); 30 scale: calc(1 + (var(--active) * 0.1)); 31 transition: .3s; 32} 33 34.sparkle-button:active { 35 scale: 1; 36 transition: .3s; 37} 38 39.sparkle path { 40 color: hsl(0 0% calc((var(--active, 0) * 70%) + var(--base))); 41 transform-box: fill-box; 42 transform-origin: center; 43 fill: currentColor; 44 stroke: currentColor; 45 animation-delay: calc((var(--transition) * 1.5) + (var(--delay) * 1s)); 46 animation-duration: 0.6s; 47 transition: color var(--transition); 48} 49 50.sparkle-button:is(:hover, :focus-visible) path { 51 animation-name: bounce; 52} 53 54@keyframes bounce { 55 35%, 65% { 56 scale: var(--scale); 57 } 58} 59 60.sparkle path:nth-of-type(1) { 61 --scale: 0.5; 62 --delay: 0.1; 63 --base: 40%; 64} 65 66.sparkle path:nth-of-type(2) { 67 --scale: 1.5; 68 --delay: 0.2; 69 --base: 20%; 70} 71 72.sparkle path:nth-of-type(3) { 73 --scale: 2.5; 74 --delay: 0.35; 75 --base: 30%; 76} 77 78.sparkle-button:before { 79 content: ""; 80 position: absolute; 81 inset: -0.2em; 82 z-index: -1; 83 border: 0.25em solid hsl(260 97% 50% / 0.5); 84 border-radius: 100px; 85 opacity: var(--active, 0); 86 transition: opacity var(--transition); 87} 88 89.spark { 90 position: absolute; 91 inset: 0; 92 border-radius: 100px; 93 rotate: 0deg; 94 overflow: hidden; 95 mask: linear-gradient(white, transparent 50%); 96 animation: flip calc(var(--spark) * 2) infinite steps(2, end); 97} 98 99@keyframes flip { 100 to { 101 rotate: 360deg; 102 } 103} 104 105.spark:before { 106 content: ""; 107 position: absolute; 108 width: 200%; 109 aspect-ratio: 1; 110 top: 0%; 111 left: 50%; 112 z-index: -1; 113 translate: -50% -15%; 114 rotate: 0; 115 transform: rotate(-90deg); 116 opacity: calc((var(--active)) + 0.4); 117 background: conic-gradient( 118 from 0deg, 119 transparent 0 340deg, 120 white 360deg 121 ); 122 transition: opacity var(--transition); 123 animation: rotate var(--spark) linear infinite both; 124} 125 126.spark:after { 127 content: ""; 128 position: absolute; 129 inset: var(--cut); 130 border-radius: 100px; 131} 132 133.backdrop { 134 position: absolute; 135 inset: var(--cut); 136 background: var(--bg); 137 border-radius: 100px; 138 transition: background var(--transition); 139} 140 141@keyframes rotate { 142 to { 143 transform: rotate(90deg); 144 } 145} 146 147@supports(selector(:has(:is(+ *)))) { 148 body:has(button:is(:hover, :focus-visible)) { 149 --active: 1; 150 --play-state: running; 151 } 152 153 .bodydrop { 154 display: none; 155 } 156} 157 158.sparkle-button:is(:hover, :focus-visible) ~ :is(.bodydrop, .particle-pen) { 159 --active: 1; 160 --play-state: runnin; 161} 162 163.sparkle-button:is(:hover, :focus-visible) { 164 --active: 1; 165 --play-state: running; 166} 167 168.sp { 169 position: relative; 170} 171 172.particle-pen { 173 position: absolute; 174 width: 200%; 175 aspect-ratio: 1; 176 top: 50%; 177 left: 50%; 178 translate: -50% -50%; 179 -webkit-mask: radial-gradient(white, transparent 65%); 180 z-index: -1; 181 opacity: var(--active, 0); 182 transition: opacity var(--transition); 183} 184 185.particle { 186 fill: white; 187 width: calc(var(--size, 0.25) * 1rem); 188 aspect-ratio: 1; 189 position: absolute; 190 top: calc(var(--y) * 1%); 191 left: calc(var(--x) * 1%); 192 opacity: var(--alpha, 1); 193 animation: float-out calc(var(--duration, 1) * 1s) calc(var(--delay) * -1s) infinite linear; 194 transform-origin: var(--origin-x, 1000%) var(--origin-y, 1000%); 195 z-index: -1; 196 animation-play-state: var(--play-state, paused); 197} 198 199.particle path { 200 fill: hsl(0 0% 90%); 201 stroke: none; 202} 203 204.particle:nth-of-type(even) { 205 animation-direction: reverse; 206} 207 208@keyframes float-out { 209 to { 210 rotate: 360deg; 211 } 212} 213 214.text { 215 translate: 2% -6%; 216 letter-spacing: 0.01ch; 217 background: linear-gradient(90deg, hsl(0 0% calc((var(--active) * 100%) + 65%)), hsl(0 0% calc((var(--active) * 100%) + 26%))); 218 -webkit-background-clip: text; 219 color: transparent; 220 transition: background var(--transition); 221} 222 223.sparkle-button svg { 224 inline-size: 1.25em; 225 translate: -25% -5%; 226}
Comments
MIT License