<canvas></canvas>

<div class="wrapper">
  <h1>I am a Pen.</h1>
  <p>I am HTML, CSS, and JavaScript. I can be anything. I can demonstate a concept. I can serve documentation. I can be an interactive component of a blog post. Do with me what you will.</p>
  <p><strong>I can even be editable.</strong></p>
</div>
body {
  text-align: center;
  font-family: monospace;
  background: #fefefe;
}

p {
  font-size: 18px;
}

.wrapper, canvas {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%) scale(0.7);
  color: white;
}

.wrapper {
  width: 400px;
  padding: 80px 20px;
  background: rgba(black, 0.6);
}

canvas {
  width: 500px;
  height: 250px;
  background: black;
}
View Compiled
/*
  Background by Ana Tudor:
  https://codepen.io/thebabydino/pen/yeyYYd
*/

var N_BUBBLES = 128, 
		c = document.querySelector('canvas'), 
		ct = c.getContext('2d'), 
		w = c.width, h = c.height, 
		bubbles = [], 
		opts = ['fill', 'stroke'], no = opts.length;

var rand = function(max, min, is_int) {
	var max = (max || max === 0)?max:1, 
			min = min || 0, 
			gen = min + (max - min)*Math.random();
	
	return (is_int)?Math.round(gen):gen;
};

var rbit = function(k) { // return random bit 0/1
	return (Math.random() < (k || .5))?0: 1;
};

var Bubble = function() {
	this.init = function(oalpha) {
		this.i = rbit(.25);
		this.r = this.i*rand(16, 7, 1) + 
						 (1 - this.i)*rand(2, 1, 1);
		this.x = rand(w + this.r, -this.r, 1);
		this.ax = rand(Math.max(this.r, 13), 4, 1);
		this.fx = rand(.05, .005);
		this.y = rand(h + this.r, 2*this.r, 1);
		this.avy = rand(4, .25);
		this.fvy = this.falpha = rand(.005, .001);
		this.oalpha = oalpha || 0;
		this.aalpha = rand(.32, .25);
		this.type = this.i*rbit(.25);
	};
	
	this.update = function(t) {
		var x = this.x + this.ax*Math.sin(this.fx*t), 
				vy = .5*this.avy*(1 - Math.sin(this.fvy*t)), 
				alpha = this.aalpha*(1 - Math.cos(this.falpha*t + this.oalpha));
		
		this.y -= vy;
		
		if(this.y < -this.r) { this.init(0); }
		else {
			ct.globalAlpha = alpha;
			ct.shadowBlur = 4*this.type;
			ct.beginPath();
			ct.arc(x, this.y, this.r, 0, 2*Math.PI);
			ct.closePath();
			ct[opts[this.type]]();
		}
	}
};

(function init() {
	ct.lineWidth = 3;
	ct.shadowColor = '#fff';
	
	for(var i = 0; i < N_BUBBLES; i++) {
		bubbles.push(new Bubble);
		bubbles[i].init(rand(2*Math.PI));
	}
})();

(function ani(t) {
	var g = ct.createLinearGradient(0, 0, 0, h);
	
	g.addColorStop(0, 'hsl(' + 2*t%360 + ',100%,65%)');
	g.addColorStop(1, 'hsl(' + 2*(t + 50)%360 + ',100%,65%)');
	ct.strokeStyle = ct.fillStyle = g;
	ct.clearRect(0, 0, w, h);
	
	for(var i = 0; i < N_BUBBLES; i++)
		bubbles[i].update(t);
	
	requestAnimationFrame(ani.bind(this, ++t));
})(0);
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.