精致按钮预览=>https://codepen.io/jh3y/pen/QWZyxdg
html:
<button class=control> <span class="backdrop"> </span> <span class="text"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"> <path fill-rule="evenodd" d="M9 4.5a.75.75 0 01.721.544l.813 2.846a3.75 3.75 0 002.576 2.576l2.846.813a.75.75 0 010 1.442l-2.846.813a3.75 3.75 0 00-2.576 2.576l-.813 2.846a.75.75 0 01-1.442 0l-.813-2.846a3.75 3.75 0 00-2.576-2.576l-2.846-.813a.75.75 0 010-1.442l2.846-.813A3.75 3.75 0 007.466 7.89l.813-2.846A.75.75 0 019 4.5zM18 1.5a.75.75 0 01.728.568l.258 1.036c.236.94.97 1.674 1.91 1.91l1.036.258a.75.75 0 010 1.456l-1.036.258c-.94.236-1.674.97-1.91 1.91l-.258 1.036a.75.75 0 01-1.456 0l-.258-1.036a2.625 2.625 0 00-1.91-1.91l-1.036-.258a.75.75 0 010-1.456l1.036-.258a2.625 2.625 0 001.91-1.91l.258-1.036A.75.75 0 0118 1.5zM16.5 15a.75.75 0 01.712.513l.394 1.183c.15.447.5.799.948.948l1.183.395a.75.75 0 010 1.422l-1.183.395c-.447.15-.799.5-.948.948l-.395 1.183a.75.75 0 01-1.422 0l-.395-1.183a1.5 1.5 0 00-.948-.948l-1.183-.395a.75.75 0 010-1.422l1.183-.395c.447-.15.799-.5.948-.948l.395-1.183A.75.75 0 0116.5 15z" clip-rule="evenodd" /> </svg> Light </span> </button> <button class="dark control"> <span class="backdrop"> </span> <span class="text"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"> <path fill-rule="evenodd" d="M9 4.5a.75.75 0 01.721.544l.813 2.846a3.75 3.75 0 002.576 2.576l2.846.813a.75.75 0 010 1.442l-2.846.813a3.75 3.75 0 00-2.576 2.576l-.813 2.846a.75.75 0 01-1.442 0l-.813-2.846a3.75 3.75 0 00-2.576-2.576l-2.846-.813a.75.75 0 010-1.442l2.846-.813A3.75 3.75 0 007.466 7.89l.813-2.846A.75.75 0 019 4.5zM18 1.5a.75.75 0 01.728.568l.258 1.036c.236.94.97 1.674 1.91 1.91l1.036.258a.75.75 0 010 1.456l-1.036.258c-.94.236-1.674.97-1.91 1.91l-.258 1.036a.75.75 0 01-1.456 0l-.258-1.036a2.625 2.625 0 00-1.91-1.91l-1.036-.258a.75.75 0 010-1.456l1.036-.258a2.625 2.625 0 001.91-1.91l.258-1.036A.75.75 0 0118 1.5zM16.5 15a.75.75 0 01.712.513l.394 1.183c.15.447.5.799.948.948l1.183.395a.75.75 0 010 1.422l-1.183.395c-.447.15-.799.5-.948.948l-.395 1.183a.75.75 0 01-1.422 0l-.395-1.183a1.5 1.5 0 00-.948-.948l-1.183-.395a.75.75 0 010-1.422l1.183-.395c.447-.15.799-.5.948-.948l.395-1.183A.75.75 0 0116.5 15z" clip-rule="evenodd" /> </svg> Dark </span> </button>
CSS:
* { box-sizing: border-box; } body { min-height: 100vh; display: grid; place-items: center; align-content: center; gap: 1rem; } button { --radius: 8px; --text-padding: 8px 16px; --border: 1px; --padding: 1px; border-radius: var(--radius); border: 0; background: hsl(0 0% 90%); box-shadow: inset 0 1px 0px 0px hsl(0 0% 100% / 0.5), inset 0 -1px 0px 0px hsl(0 0% 0% / 0.5); /* background: conic-gradient(from calc(var(--rx) * 360deg) at calc(var(--x) * 1px) calc(var(--y) * 1px), hsl(10 90% 50%), hsl(140 70% 50%), hsl(320 70% 50%), hsl(210 70% 50%), hsl(10 70% 50%)); background-attachment: fixed; */ font-family: sans-serif, system-ui; font-size: 1.25rem; position: relative; display: grid; place-items: center; padding: var(--padding); border: var(--border) solid hsl(0 0% 80%); transform: translate(calc(var(--active, 0) * -2px), calc(var(--active, 0) * 2px)); transition: transform 0.1s; color: hsl(0 0% 20%); } button:is(:hover, :focus-visible) { --hover: 1; /* border-color: transparent !important; */ } button:active { --active: 1; } button:before{ content: ""; position: absolute; inset: 0px; /* width: 100%; aspect-ratio: 1; top: 50%; left: 50%; translate: -50% -50%; */ border-radius: calc(var(--radius) - var(--border)); /* transition: background 0.2s; */ background: hsl(0 0% 100% / calc(1 - var(--hover, 0) * 0.25)); background: grey; background: conic-gradient( from calc(var(--rx, 0) * 180deg) at calc(var(--x, 0) * 100%) calc(var(--y, 0) * 100%), hsl(10 90% 70%), hsl(140 80% 70%), hsl(320 80% 70%), hsl(210 80% 70%), hsl(10 80% 70%) ); filter: saturate(0.7); opacity: var(--hover, 0); transition: opacity 0.2s; } .backdrop { position: relative; width: 100%; height: 100%; background: hsl(0 0% 98% / 0.6); border-radius: calc(var(--radius) - var(--padding)); display: block; grid-column: 1; grid-row: 1; backdrop-filter: blur(20px) brightness(1.5); } .text { padding: var(--text-padding); grid-row: 1; grid-column: 1; z-index: 2; display: flex; align-items: center; gap: 0.5rem; } svg { width: 24px; } .dark { border-color: hsl(0 0% 20%); } .dark .backdrop { background: hsl(0 0% 10% / 0.4); backdrop-filter: blur(20px) brightness(1.2) saturate(1); } .dark:after { background: hsl(0 0% 10% / calc(1 - var(--hover, 0) * 0.25)); } .dark { color: hsl(0 0% 98%); background: hsl(0 0% 10%); }
JS
const CONTROLS = document.querySelectorAll("button"); const UPDATE = ({ x, y }) => { const ELEMENT = document.elementFromPoint(x, y); const CONTROL = ELEMENT.closest(".control"); if (CONTROL) { console.info('doing it') const BOUNDS = CONTROL.getBoundingClientRect() CONTROL.style.setProperty("--rx", (x - BOUNDS.x) / BOUNDS.width); CONTROL.style.setProperty("--x", (x - BOUNDS.x) / BOUNDS.width); CONTROL.style.setProperty("--y", (y - BOUNDS.y) / BOUNDS.height); } }; document.body.addEventListener("pointermove", UPDATE);