Effet de lueur au curseur avec setProperty

Démos

Effet de lueur au curseur avec setProperty

Aperçu seul
01

HTML

index.html
<form> <label for="sat">Saturation</label> <input id="sat" type="range" min="0" max="100" value="30" step="0.1"/> <label for="alp">Alpha</label> <input id="alp" type="range" min="0" max="100" value="100" step="0.1"/> <label for="lig">Lightning</label> <input id="lig" type="range" min="0" max="100" value="30" step="0.1"/> </form> <div class="features"> <div class="feature" style="--hue:0"><a class="feature-content" href="#"><strong>Title card</strong><span>Description of my card</span></a></div> <div class="feature" style="--hue:60"><a class="feature-content" href="#"><strong>Title card</strong><span>Description of my card</span></a></div> <div class="feature" style="--hue:120"><a class="feature-content" href="#"><strong>Title card</strong><span>Description of my card</span></a></div> <div class="feature" style="--hue:180"><a class="feature-content" href="#"><strong>Title card</strong><span>Description of my card</span></a></div> <div class="feature" style="--hue:240"><a class="feature-content" href="#"><strong>Title card</strong><span>Description of my card</span></a></div> <div class="feature" style="--hue:300"><a class="feature-content" href="#"><strong>Title card</strong><span>Description of my card</span></a></div> </div>
02

CSS

style.css
@layer demo { .features { width: 75vw; height: 50vh; display: grid; gap: 1rem; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(2, 1fr); .feature { --x-px: calc(var(--x) * 1px); --y-px: calc(var(--y) * 1px); --border: 1px; --color: var(--hue, 0deg) var(--sat, 28%) var(--lig, 46%); --hsla-color: hsla(var(--color) / var(--alp, 100%)); background: rgba(255, 255, 255, 0.125); border-radius: 0.5rem; overflow: hidden; box-shadow: 0 0 10px 5px rgba(0 0 0 / 100%); &:before, &:after { content: ""; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; inset: 0px; border-radius: inherit; background: radial-gradient( 200px circle at var(--x-px) var(--y-px), var(--hsla-color), transparent 100% ); mix-blend-mode: hard-light; } &:before { z-index: 1; } &:after { opacity: 1; z-index: 2; transition: opacity 0.4s ease; } &:hover:after { opacity: 1; } .feature-content { background: hsla(0deg 0% 0% / 100%); border-radius: inherit; color: white; text-decoration: none; z-index: 1; position: absolute; inset: var(--border); display: grid; grid-template-rows: 1fr 1fr; grid-row-gap: 0.5rem; padding: 0 1rem 0 2rem; > strong { align-self: self-end; font-size: 125%; } > span { opacity: 0.8; } } } } } @layer demoStyles { * { position: relative; } form { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; } label { color: white; } }
03

JavaScript

script.js
const featuresEl = document.querySelector(".features"); document.querySelector("#sat").addEventListener("input", () => { featuresEl.style.setProperty("--sat", sat.value + "%"); }); document.querySelector("#alp").addEventListener("input", () => { featuresEl.style.setProperty("--alp", alp.value + "%"); }); document.querySelector("#lig").addEventListener("input", () => { featuresEl.style.setProperty("--lig", lig.value + "%"); }); featuresEl.addEventListener("pointermove", ({ clientX, clientY }) => { document.querySelectorAll(".feature").forEach((featureEl) => { const { left, top } = featureEl.getBoundingClientRect(); featureEl.style.setProperty("--x", clientX - left); featureEl.style.setProperty("--y", clientY - top); }); });