%div.notice Click on the screen to see the next animation

%input#pulse.dots{ :type => "radio", :name => "selection"}
%label.shower{:for => "shower"} Shower

%input#shower.dots{:type => "radio", :name => "selection"}
%label.spread{:for => "spread"} Spread

%input#spread.dots{:checked => "checked", :type => "radio", :name => "selection"}
%label.pulse{:for => "pulse"} Dots


%div.wrapper
  %div.container
    - (1..50).each do 
      %div.dot
View Compiled
html, body {
  height: 100%;
}

.notice {
  position: fixed;
  width: 100vw;
  height: 100vh;
  text-align: center;
  line-height: 50vw;
  font-size: 30px;
  color: #000;
  font-family: Helvetica, Arial, sans-serif;
}

body {
  margin: 0;
  padding: 0;
  background: #333;
  position: relative;
  
  input {
    opacity: 0;
  }
  
  label {
    position: fixed;
    width: 100vw;
    height: 100vh;
    z-index: 0;
    cursor: pointer;
    top: 0;
    left: 0;
    text-indent: -999px;
  }
  
  input:checked + label {
    z-index: 5;
  }
  
  .wrapper {
    .container {
      width: 100vw;
      height: 100vh;
      overflow: hidden;
      position: fixed;
      top: 0;
      left: 0;

      .dot {
        border-radius: 100%;
        position: absolute;
        opacity: 0;
        transition: top 2s ease-in-out, left 2s ease-in-out, opacity 2s ease-in-out;
      }
    }
  }
}


@keyframes pulse {
  0% {
    opacity: 1;
  }
  100% {
    width: 100vh;
    height: 100vh;
    opacity: 0;
  }
}

#pulse:checked ~ .wrapper {
  .container {
    background: rgba(81, 111, 199, 0.1);
  }
  
  .dot {
    @for $i from 1 to 50 {
      &:nth-child(#{$i}) {
        $size: 25;
        $r: random(256)-1; 
        $g: random(256)-1;
        $b: random(256)-1;
        $a: random(10) * 0.1;
        $border: random(10);
        $blur: random(20) + px;
        $color: rgba($r, $g, $b, $a);

        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);

        width: $size + px;
        height: $size + px;

        border: ($border + px) $color solid;
        animation: pulse 5s linear infinite;
        animation-delay: ($i * 0.1) + s;
      }
    }
  }
}

@keyframes shower {
  0% {
    top: 0;
    opacity: 1;
  }
  100% {
    top: 100%;
    opacity: 0;
  }
}

#shower:checked ~ .wrapper {
  .container {
    background: rgba(35, 43, 68, 0.7);
  }
  
  .dot {
    @for $i from 1 to 50 {
      &:nth-child(#{$i}) {
        $size: 20;
        $r: random(256)-1; 
        $g: random(256)-1;
        $b: random(256)-1;
        $a: random(10) * 0.1;
        $color: rgba($r, $g, $b, $a);
        $left: random(100) + vw;

        top: 0;

        width: $size + px;
        height: $size + px;
        background: $color;
        left: $left;

        animation: shower 5s linear infinite;
        animation-delay: ($i * 0.2) + s;
      }
    }
  }
}

@mixin spreadkeyframe($name, $top, $left) {
  @keyframes #{$name} {
    0% {
      opacity: 1;
    }
    100% {
      opacity: 0;
      top: $top;
      left: $left;
    }
  }
}

#spread:checked ~ .wrapper {
  .container {
    background: rgba(216, 60, 244, 0.2);
  }
  
  .dot {
    
    @for $i from 1 to 50 {
      $animationName: "spread" + $i;
      $left: random(200) + vw;
      $top: random(200) + vh;

      @if ($i % 4 == 0) {
        @include spreadkeyframe($animationName, -$top, -$left);
      }
      @else if ($i % 3 == 0) {
        @include spreadkeyframe($animationName, $top, $left);
      }
      @else if ($i % 2 == 0) {
        @include spreadkeyframe($animationName, -$top, $left);
      }
      @else {
        @include spreadkeyframe($animationName, $top, -$left);
      }

      &:nth-child(#{$i}) {
        $size: random(20, 50);
        $r: random(256)-1; 
        $g: random(256)-1;
        $b: random(256)-1;
        $a: random(10) * 0.1;
        $color: rgba($r, $g, $b, $a);

        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);

        background: $color;
        width: $size + px;
        height: $size + px;

        animation-delay: ($i * .1) + s;
        animation-name: #{$animationName};
        animation-duration: 5s;
        animation-iteration-count: infinite;

      }
    }
  }
}







External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.