<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);
	}
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.