<h1>Press <kbd>Opt/Alt</kbd> or touch for a spotlight effect</h1>
<focus-zoom></focus-zoom>
@use postcss-nested;
@property --focal-size {
syntax: '<length-percentage>';
initial-value: 100%;
inherits: false;
}
focus-zoom {
--mouse-x: center;
--mouse-y: center;
--backdrop-color: hsl(200 50% 0% / 50%); /* can't be opaque */
--backdrop-blur-strength: 10px;
position: fixed;
touch-action: none;
inset: 0;
background-color: var(--backdrop-color);
backdrop-filter: blur(var(--backdrop-blur-strength));
mask-image: radial-gradient(
circle at var(--mouse-x) var(--mouse-y),
transparent var(--focal-size),
black 0%
);
transition: --focal-size .3s ease;
/* debug/grok the gradient mask image here */
/* background-image: radial-gradient(
circle,
transparent 100px,
black 0%
); */
}
* {
box-sizing: border-box;
margin: 0;
}
html {
block-size: 100%;
background: conic-gradient(from -.5turn at bottom right, deeppink, cyan, rebeccapurple);
}
body {
min-block-size: 100%;
font-family: system-ui, sans-serif;
display: grid;
align-content: center;
justify-items: center;
}
h1 {
max-inline-size: 20ch;
}
View Compiled
const zoom = document.querySelector('focus-zoom')
const toggleSpotlight = bool =>
zoom.style.setProperty('--focal-size',
bool
? '15vmax'
: '100%')
window.addEventListener('pointermove', e => {
zoom.style.setProperty('--mouse-x', e.clientX + 'px')
zoom.style.setProperty('--mouse-y', e.clientY + 'px')
})
window.addEventListener('keydown', e =>
toggleSpotlight(e.altKey))
window.addEventListener('keyup', e =>
toggleSpotlight(e.altKey))
window.addEventListener('touchstart', e =>
toggleSpotlight(true))
window.addEventListener('touchend', e =>
toggleSpotlight(false))
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.