<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.