How to create a slick CSS animation from Cocktail
Tags: css, animation
Published: 2024-04-24 13:56:37


Let's jump to the 80's and create an animation with a retro feel. Cocktail!

[Cocktail](https://en.wikipedia.org/wiki/Cocktail_(1988_film)) is a romantic comedy-drama made in 1988. If you have not heard of it, the most notably thing is that it stars a young Tom Cruise. He plays a New York City business student, who takes up bartending in order to make ends meet. Hijinks and bad fashion ensue.

## TLDR

Here is the [finished animation](https://codepen.io/robjoeol/pen/WNWZBKx).

{% codepen https://codepen.io/robjoeol/pen/WNWZBKx %}

## About the title sequence

The opening title sequence features neon text. Each title flickers on and off reminsicent of a neon sign. The text is ebullient with bright, saturated colours. The palette is blue, pink, and turquoise that was so prominent in the 80's. It is backed a trendy rock track by Starship.

You can watch the [full title sequence on YouTube](https://www.youtube.com/watch?v=yNYA6DyDUk8).

<figure>
![The title card for the film Cocktail. It is a bright neon sign with blue writing saying Cocktail surrounded by a pink ring](https://www.roboleary.net/assets/img/blog/2024-04-24-cocktail-title-animation/title-reference.webp)
<figcaption>The title card for Cocktail</figcaption>
</figure>

The title card looks like the sign for a bar. The text is in blue and it is surrounded by a pink ring. Looking at it through today's lens, it looks like a subpar design! I will resist reworking anything!

The font used is hard to pinpoint. The closest I could find is [Gillies Gothic Light](https://fontsgeek.com/gillies-gothic-light-font). The cursive style is similar. However, it does not have many of the serifs that join adjacent letters and the flourishes that give a more nuanced perception of a neon sign. I will stick with this font and not edit the gylphs to mirror the original.

<figure>
![This is my recreation of the title card for the film Cocktail using the Gillies Gothic Light font. It is a bright neon sign with blue writing saying Cocktail surrounded by a pink ring](https://www.roboleary.net/assets/img/blog/2024-04-24-cocktail-title-animation/result.webp)
<figcaption>My recreation of the title card for Cocktail using the Gillies Gothic Light font.</figcaption>
</figure>

## The animation

A neon effect is created with a shadow with a blur radius. For the text, we use the `text-shadow` property. When I was a CSS grasshopper, I thought that a single shadow with a large blur radius would suffice:

```css
h1 {
  text-shadow: 0 0 30px blue;

  /* other styles */
}
```

Alas, it looks quite faint..

![a single text shadow with a blur radius of 30px](https://www.roboleary.net/assets/img/blog/2024-04-24-cocktail-title-animation/single-text-shadow.png)

What you need to do is stack multiple shadows with larger and larger blur radii as below:

```css
h1 {
  text-shadow: 0 0 5px blue, 0 0 10px blue, 
	0 0 15px blue, 0 0 20px blue, 
	0 0 25px blue, 0 0 30px blue;

  /* other styles */
}
```

![mutliple text shadows with increasing blur radii](https://www.roboleary.net/assets/img/blog/2024-04-24-cocktail-title-animation/multiple-text-shadow.png)

To animate a `text-shadow`, we can set the aforementioned `text-shadow` in the `to` block of a `@keyframes`. We do not set any initial state. The browser does the work to interpolate the values for each of the shadows.

```css
h1 {
  animation: flicker 2s infinite ease-in-out;
}

@keyframes flicker{
  to {
    text-shadow: 0 0 5px blue, 0 0 10px blue, 0 0 15px blue, 0 0 20px blue, 0 0 25px blue, 0 0 30px blue;
  }
}
```

{% codepen https://codepen.io/robatronbobby/pen/VwNgeXj %}

I created the pink ring using the `::before` pseudo-element. We cannot use `text-shadow` on it because there is no text!

```css
h1::before {
  content: "";

  border-radius: 50%;
  width: 70%;
}
```

To create a shadow for the pink ring, we use the `filter` property with the `drop-shadow()` function. We do not use `box-shadow` because it will apply the shadow to the element's box which is a rectangle, thus ignores the shape of the element.

```css
h1::before {
  filter: drop-shadow(0 0 0 hsla(300, 97%, 60%))
    drop-shadow(0 0 0 hsla(300, 97%, 60%))
    drop-shadow(0 0 0 hsla(300, 97%, 60%));
}
```

To animate the filter, we can do similar to what we did with `text-shadow`. This is what it looks like:

```css
h1::before {
  animation: flicker-ring 2s infinite ease-in-out;
}

@keyframes flicker-ring {
  to {
    filter: drop-shadow(0 0 10px hsla(300, 97%, 60%))
      drop-shadow(0 0 20px hsla(300, 97%, 60%))
      drop-shadow(0 0 30px hsla(300, 97%, 60%));
  }
}
```

{% codepen https://codepen.io/robatronbobby/pen/abxXNLp %}

That is the core of the neon effect of the title card animation. I also animated `opacity` in the final animation to create a staged reveal before lighting up the title.

The final part of the animation is that the title card fades out. I think it is better to use 2 separate animations to get the desired result rather than to squash everything into a single `keyframes`. Since the title remains in its "lit" state for a couple of seconds, we can use an `animation-delay` to control this duration in the second animation.

To recap, the first animation reveals and lights up the title, the second animation leaves the "lit" state linger before it unlights and fades out the title. Here is the CSS for the animations for the ring:

```css
h1::before {
  animation-name: on-ring, off-ring;
  animation-duration: var(--animation-duration), var(--animation-duration);
  animation-delay: 0s, var(--delay-duration);
  animation-timing-function: ease-in, ease-out;
  animation-fill-mode: forwards, forwards;
  animation-iteration-count: 1, 1;
}

@keyframes on-ring {
  to {
    filter: drop-shadow(0 0 10px var(--ring-glow-color))
      drop-shadow(0 0 20px var(--ring-glow-color))
      drop-shadow(0 0 30px var(--ring-glow-color))
      drop-shadow(0 0 30px var(--ring-glow-color-outer));
  }
}

@keyframes off-ring {
  to {
    filter: none;
  }
}
```

Notice that we use `filter: none;` to animate out the shadows for the ring!

That's it!

--- 
Written by [Rob O'Leary](https://www.roboleary.net)<br>
[Subscribe to web feed](https://www.roboleary.net/feed.xml) for the latest articles.

<small>© Rob OLeary 2024</small>