<div class="title" data-splitting="lines">
  SPACE<br/>
  INVADERS
</div>
@import url('https://fonts.googleapis.com/css?family=Coda+Caption:800');

html, body { background: hsl(220, 70%, 30%); }
html { height: 100%; display: flex; }
body { margin: auto; }

/*
  You can adjust the
    * rotation (rotateX),
    * vertical stretch (scaleY),
    * projection (perspective) and
    * layer depth (--layer-depth)
*/
.title {
  text-align: center;
  font-family: 'Coda Caption', sans-serif;
  font-weight: 800;
  font-size: calc(20vw / var(--word-total) ); /* Overriden below for fluid typography test */
  line-height: 1.0;
  letter-spacing: -0.03em;
  transform: perspective(300px) scaleY(1.5) rotateX(-40deg);
  transform-style: preserve-3d; /* Important for establishing a shared 3D space for all the layers */
  --layer-depth: 0.32em;
}


/* The front layer are yellow words with a thick black stroke outline */
.title .word {
  position: relative;
  display: inline-block;
  color: yellow;
  font-size: calc(((var(--line-index) + 1) * 25%) + 50%); /* We skew font-sizes to avoid emphasize on the top, due to perspective rotation */
  text-shadow: 0.06em 0 black, 0.06em 0.06em black, 0 0.06em black, -0.06em 0.06em black, -0.06em 0 black, -0.06em -0.06em black, 0 -0.06em black, 0.06em -0.06em black;
  transform-style: preserve-3d; /* Important as above, we need to make sure the pseudos share the same 3D space */
}


/* The back layers are two pseudos, we pull content through via Splitting.js! */
.title .word::before,
.title .word::after {
  content: attr(data-word);
  position: absolute;
  top: auto;
  left: 0;
  bottom: 0;
  display: block;
  pointer-events: none;
}

/* Red layer immediately behind the yellow, thinner stroke outline */
.title .word::before {
  color: red;
  text-shadow: 0.02em 0 black, 0.02em 0.02em black, 0 0.02em black, -0.02em 0.02em black, -0.02em 0 black, -0.02em -0.02em black, 0 -0.02em black, 0.02em -0.02em black;
  transform: translateZ(calc(var(--layer-depth) * -0.5));
}

/* Furthest layer, just simple black lettering with no outline */
.title .word::after {
  color: black;
  text-shadow: none;
  transform: translateZ(calc(var(--layer-depth) * -1));
}


/* Testing Fluid Typography with CSS Variables – Broke on Safari though? */
.title {
  --min-font-size: 64;
  --max-font-size: 128;
  font-size: calc(var(--min-font-size) * 1px);
}

@media screen and (min-width: 320px) {
  .title {
    font-size: calc(var(--min-font-size) * 1px + (var(--max-font-size) - var(--min-font-size)) * ((100vw - 320px) / 680));
  }
}

@media screen and (min-width: 1000px) {
  .title {
    font-size: calc(var(--max-font-size) * 1px);
  }
}
Splitting();

External CSS

  1. https://unpkg.com/splitting@0.11.3/splitting.css

External JavaScript

  1. https://unpkg.com/splitting/dist/splitting.js
  2. https://codepen.io/shshaw/pen/5eb6d4e9bfd78e3911ed9d0d0dfce69b.js