How to make a slick CSS animation from Arrested Development

The title card for the TV Series Arrested Development. The title is broken up on 2 lines. The first word is in red in lower case. The second word is in black and is in uppercase. The title is encircled by a red marked line.

Arrested Development is a satirical sitcom. The title sequence complements the kooky nature of the show well. Let’s see how we can recreate it in CSS.

TLDR

You can see the title sequence (15s timestamp) on YouTube. Here is the finished animation:

About the title sequence

The text of the title card is broken up over two lines. The first word has a reddish gradient and is in lower case. The second word is in black and is in uppercase, and it has a smaller font size than the first word.

The title uses a font that is blotchy. The font is probably FF Blur, which has a commercial license. I used a free font called Distro Bold instead.

The animation is slightly chaotic and kooky. The title zooms into focus from an offset position, it is circled roughly in red marker, and then glitches. I skipped the fade out part of the sequence.

Implementation tidbits

We always want each word of the title to be on separate lines. To do this we need to have each word as a separate element. Here is the outline of the HTML:

HTML
<h1>
<span class="word">arrested</span>
<span class="word">development</span>
</h1>

<svg id="circular-mark">...</svg>

I created the red circular mark as a SVG. I drew the line in Inkscape illustrator. The line should be a single path element in the final SVG. I applied the “roughen” filter to the line to give it more of hand-drawn feel. You can find this filter in the main menu item Filters, and it is inside the Distorts category.

Circular line drawn in Inkscape illustrator with the roughen filter dialog open

I played with the values in the filter dialog until I got the result I wanted. The line should vary in width and have a little bit of irregularity in the stroke. The outcome is a bit different that the original but I think that it captures the feeling.

Circular line drawn in Inkscape illustrator

The layout of the title requires it to be centered in the page, and have the circular mark on top of the h1. The easiest way to achieve this is to use CSS Grid to center all items on a page that covers the full screen. I place the h1 and svg in the same row and column.

CSS
/* body covers full screen and centers all items */
body {
height: 100dvh;
margin: 0;

display: grid;
place-items: center;

overflow: hidden;
}

h1 {
grid-row: 1;
grid-column: 1;

font-size: clamp(4rem, 1.6522rem + 10.4348vw, 10rem);
}

/* overlay svg on h1 */
svg {
grid-row: 1;
grid-column: 1;
}

/* ensures words on separate lines */
.word {
display: block;
}

I set display:block on each word to ensure each word occupies its own line. I used clamp() to create a fluid font size to adjust to the screen width.

You can peruse the rest of the code at your own leisure.

The animation

Let’s look at each part of the animation. It can be seen as 3 discrete animations.

The entry animation

The entry animation has the title zoom in from a oblique, offset position and come into sharp focus.

Source Code
h1 {
  grid-row: 1;
  grid-column: 1;

  font-size: clamp(4rem, 1.6522rem + 10.4348vw, 10rem);

  margin: 0;
  opacity: 0;

  animation-name: entry;
  animation-delay: 300ms;
  animation-duration: 500ms;
  animation-iteration-count: 1;
  animation-fill-mode:forwards;
}

@keyframes entry {
  0% {
    opacity: 1;

    translate: 100%;
    scale: 4;
    filter: blur(8px);
  }

  to {
    opacity: 1;

    translate: 0;
    scale: 1;
    filter: blur(0);
  }
}

/* general */

body {
  height: 100dvh;
  margin: 0;

  display: grid;
  place-items: center;

  overflow: hidden;
}

Result

Therefore the initial state of the title is: positioned to the right of its final position, is closer to the viewer (bigger in scale), and is blurry. We can encapsulate this state as:

CSS
h1 {
translate: 100%;
scale: 4;

filter: blur(8px);
}

I am using scale to kind of fake perspective here. Using a translation on the Z axis would be more accurate, however I find that it is easier to play with scale to get the desired result when animating.

The animation requires initially hiding the title by setting opacity: 0, and then returning the values of the aforementioned properties to their defaults. For example, we want the scale to be returned to 1. This is what the keyframes looks like:

CSS
@keyframes entry {
0% {
opacity: 1;

translate: 100%;
scale: 4;
filter: blur(8px);
}

to {
opacity: 1;

translate: 0;
scale: 1;
filter: blur(0);
}
}

The line drawing animation

You can animate the drawing of a line using a CSS trick that involves the properties stroke-dasharray and stroke-dashoffset.

/* Use the same value as pathLength attribute. */
path {
  --length: 1;

  stroke-dasharray: var(--length);
  stroke-dashoffset: var(--length);

  animation: draw 2s;
  animation-iteration-count:infinite;
}

@keyframes draw {
  to {
    stroke-dashoffset: 0;
  }
}

svg {
  width: 70%;
}

body {
  height: 100dvh;
  margin: 0;

  display: grid;
  place-items: center;
}

Result

The trick is to set the stroke-dasharray and stroke-dashoffset to the same length of the path we want to draw. This leds to a blank space as there is a large gap between the stroke dashes. If we animate the stroke-dashoffset to a value of 0, the gap will shrink to draw the line.

The nice thing is that we dont have to measure the length of the path! We can set the pathLength attribute on the path to 1, and then use then use that value in our CSS! However in this case I found that a little bit of the line was exposed initially, so I used a slightly bigger value of 1.1 in the CSS. This may be due to the filter being used on the path.

The glitch animation

The glitch animation requires moving the text vertically very quickly. This can be done as translation on the Y axis, and adding a blur filter to the text. It is a matter of finding the right values for translate and filter: blur().

To simplify the animation, we can alternate the direction and repeat the animation multiple times in order for the text to go up and down. Here is a simplified version:

CSS
@keyframes glitch {
to {
filter: blur(8px);
translate: 0 -30%;
}
}

h1{
animation-name: glitch;
animation-duration: 200ms;
animation-iteration-count: 3;
animation-direction: alternate;
animation-fill-mode: none;
}

Finally, we want to bring these 3 animations into sequence and coordinate their timing. You can check out the code to see explore more on that.

Final word

I was pleased that I could pull this animtion off in CSS. It is an intricate sequence. The CSS trick to animate drawing a line got me over the line!

Animating the blur() filter is an interesting effect that you don’t see often. I will add it to my arsenal. Although, it should be wielded carefully as animating filters is taxing for the browser.

Tagged