<div data-lit-hue='20' data-lit-count='100' class='lit-container'>
<div class='minimal element-1'> </div>
</div>
<div data-lit-hue='60' data-lit-count='100' class='lit-container'>
<div class='minimal element-2'> </div>
</div>
<div data-lit-hue='100' data-lit-count='100' class='lit-container'>
<div class='minimal element-1'> </div>
</div>
<div data-lit-hue='140' data-lit-count='100' class='lit-container'>
<div class='minimal element-2'> </div>
</div>
<div data-lit-hue='180' data-lit-count='100' class='lit-container'>
<div class='minimal element-1'> </div>
</div>
<div data-lit-hue='220' data-lit-count='100' class='lit-container'>
<div class='minimal element-2'> </div>
</div>
<div data-lit-hue='260' data-lit-count='100' class='lit-container'>
<div class='minimal element-1'> </div>
</div>
<div data-lit-hue='300' data-lit-count='100' class='lit-container'>
<div class='minimal element-2'> </div>
</div>
View Compiled
* {
margin: 0;
padding: 0;
}
body {
background: #ddd;
display: grid;
justify-content: center;
grid-auto-rows: 70vh;
place-items: center;
padding: 100px 20px;
}
.minimal {
box-shadow: 2px 2px 5px rgba(0, 0 0, 0.15);
background: white;
display: grid;
align-content: center;
justify-content: center;
border-radius: 5px;
}
.element-1 {
width: 300px;
height: 80px;
}
.element-2 {
width: 300px;
height: 300px;
}
.lit-container:hover .lit,
.lit-container:focus-within .lit {
background: hsla(0deg, 0%, 60%, 20%) !important;
}
/* lit --------------------------- */
[data-lit-hue] {
position: relative;
}
span.lit {
border-radius: 50%;
position: absolute;
pointer-events: none;
transform: translate(-50%, -50%);
animation: blow 2s ease-in infinite;
transition: all 400ms ease;
}
@keyframes blow {
0% {
transform: translate(-50%, -50%) scale(0.1);
opacity: 0;
}
10% {
transform: translate(-50%, -50%);
opacity: 1;
}
100% {
transform: translate(-50%, -40vh);
opacity: 0;
}
}
View Compiled
// you can change the hue and amount lit-ness via data attributes on html
// clips the value to given range
const clip = (v, min, max = Infinity) => {
if (v < min) return min;
else if (v > max) return max;
else return v;
};
// generated random value from given range
const randRange = (min, max) => Math.random() * max + min;
// create bubble on x and y position inside target with given hue theme
function bubble(x, y, rect, hue, target) {
// variables
const size = randRange(20, rect.width / 5);
const circleHue = hue + randRange(-20, 20);
const animDuration = randRange(clip(size ** 2/1000, 1), 6)
const zIndex = Math.random() < 0.1 ? 2 : -1;
// apply to DOM
const circle = document.createElement("span");
circle.className = "lit";
circle.style.left = x + "px";
circle.style.top = y + "px";
circle.style.width = size + "px";
circle.style.height = size + "px";
circle.style.background = `hsl(${circleHue}deg, 100%, 60%)`;
circle.style.zIndex = zIndex
circle.style.animationDuration = animDuration + "s";
target.appendChild(circle);
}
document.querySelectorAll("[data-lit-hue]").forEach((target) => {
const rect = target.getBoundingClientRect();
const hue = Number(target.getAttribute("data-lit-hue"));
const count = Number(target.getAttribute("data-lit-count") || 50);
for (let i = 0; i < count; i++) {
const x = randRange(0, rect.width);
const y = randRange(0, rect.height);
bubble(x, y, rect, hue, target);
}
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.