How To Create An Animated Message With HTML, CSS, And JavaScript

by kleamerkuri
How To Create An Animated Message With HTML, CSS, And JavaScript.

In this post, we’ll create a simple animated message using HTML, CSS, and JavaScript that you can send out to wow people.

Though not too demanding in skillset, this project will be touching on various useful concepts like:

  • building a reusable flexbox container
  • embedding and customizing Lottie animations
  • creating dynamic typing using JavaScript

My animated message will be a holiday greeting since we just came out of the holiday season.

See the Pen Responsive Flex Layout by Klea Merkuri (@thehelpfultipper) on CodePen.

Fun fact: I actually sent out this message to family and friends which not only impressed but also brought lots of smiles 😊

You can easily share your personal animated message by hosting it on GitHub pages and sharing the URL.

Mind you this is a public URL that anyone can view so keep things public-oriented 😏

Without further ado, game on!

1) Setting up the page layout

We’ll be using Flexbox to create a responsive page layout because most of your recipients will open the link from a mobile device.

The page layout consists of three wrappers and two components:

  1. main flex parent container
  2. two flex-children wrappers for the text and animation
  3. the actual text and Lottie elements
<div id="wrapper">
  <div id="text">
    <div id="mssg"></div>
  </div>
  <div id="animation">
    <div id="lottie"></div>
  </div>
</div>

The page will have a vertical direction across screen sizes since the message will be at the top and the animation at the bottom.

It’s a stacked, mobile-first design from the get-go 💁‍♀️

body {
  height: 100vh;
  margin: 0; padding: 0;
  background-color: rgba(64, 69, 87, .9);
  color: #FEFEFE;
}

#wrapper {
  height: 100%;
  width: 100%;
  text-align: center;
  display: flex;
  flex-direction: column;
}

#wrapper > * {
  width: 100%;
  box-sizing: border-box; /* Account for border, padding, margins within given dimensions */
}
  • Give the body a definite height to distribute accordingly across the children wrappers
  • Set flex-direction to column to make the vertical axis the main axis
  • Make each child within the main wrapper full-width with contained dimensions

Next, I want to distribute the vertical space between my two main wrappers with #animation being the wrapper taking up the majority of space.

#text {
  background: yellow;
  height: calc(100vh/3);
  min-height: 200px; /* Absolute val to prevent shrinking */
  padding: 10px 5px;
  display: flex;
  justify-content: center;
  align-items: flex-end;
}

#animation {
  background: salmon;
  height: calc(100vh * 3/4);
  min-height: 300px;
  display: flex;
  align-items: flex-start;
}
Responsive flex layout.
Visual representation of vertical space distribution.
  • Setting a min-height prevents the containers from shrinking beyond a certain size.
  • Using vh units ensures the size will adjust based on the viewport dimensions.
  • Declaring a flex display allows the use of the align-items property to place the text message toward the end of the top container and the Lottie animation toward the top of the bottom container.

Notice that I use align-items to place the children components of the two wrappers when usually you’d see justify-content.

Since the main axis is not the default horizontal axis but the vertical axis (due to our flex-direction declaration on the main container), align-items becomes the property that will space items properly.

In this case, justify-content will space items on the cross-axis (aka the horizontal axis).

Tip 🔥
Giving colors to containers when creating layouts is a perfect way to visualize them so you’re aware how they look, how much space they’re taking on the page, etc. Remove the background colors when done!

2) Adding a dynamically typed message

The holiday greeting is going to go inside the #text wrapper.

JavaScript will handle the entire message to create the typed effect.

I’ll start by declaring three variables:

const mssg = document.querySelector('#mssg'),
      text = 'Happy Holidays! Best of health and happiness :) — Klea ❤ —',
      speed = 50;
  • mssg: Points to the #mssg component inside the #text wrapper
  • text: Holds the holiday greeting content
  • speed: Constant that stands for the typing speed (in milliseconds) of the message

The typing effect is created using the setTimeout() method which does something (in a callback function) for a duration of time (our speed).

Note: The setTimeout() method takes two parameters: (1) the callback specifying certain conditions or actions and (2) a time duration in milliseconds.

In this case, the action in the callback is going to be the rendering of a character from my message.

Each character rendering will occur with a 50-millisecond wait.

let i = 0; 
function write() {
  if ( i < text.length ) {
    let letter = text.charAt(i);

    mssg.innerHTML += letter;

    if ( letter === '!' || letter === ')' ) {
      mssg.innerHTML += '<br />';
    }

    i++;

    setTimeout(write, speed);
  }
}
  • i: Counter variable referencing the index of each character in the text string
  • charAt(): Method that returns the character at the specified index
  • setTimeout(): Executes write() function after 50 milliseconds

Give #mssg some styles so we can see what’s going on once executing the write() function.

#mssg {
  background: blue;
  font-family: Palatino, Helvetica, san-serif;
  line-height: 1.5em;
  letter-spacing: 0.05em;
  font-size: 1.868rem;
}

Note: With our current logic, the typed message doesn’t loop. Once all the characters of the text string are displayed, we end up with a static message.

Embedding a Lottie animation

Time to include our Lottie animation!

There are different sources online that offer free Lottie animations but I typically reach for those on LottieFiles.

You’ll need to sign up for an account to download or embed LottieFiles assets. Signing up is free 😁

Including a Lottie animation is easy enough using the “html” option since you only need to copy the provided code and include it where appropriate in your file.

HTML option Lottie animation.
Selecting the <html> embed option.
Generate embed code Lottie animation.
Generated HTML embed code.

But I want to customize the Lottie I chose because the colors don’t pan out very well with my holiday greeting color theme.

How to customize a Lottie animation

The generated code won’t be of much help in customizing the Lottie animation.

One way to make stylistic changes is by downloading the Lottie JSON file to modify it.

Or, we can make use of the provided Lottie Editor, which is exactly what I’ll do ‘cause have you looked at that JSON file? It doesn’t look too pretty. In fact, nothing on there looks human readable 😓

Despite DM’s conviction that I’m something other than human, I didn’t even know where to begin making changes.

So onto my smart workaround:

  1. Scroll down and click on “Edit Layer Colors” from your Lottie’s main page
  2. You’ll be redirected to the Lottie Editor where you can make stylistic changes like changing your Lottie’s colors
Customize Lottie animation with Lottie editor.
  1. Once done making modifications, hit “Save” and you’ll be redirected to the projects page that’ll display your current project.

From that page, you have various download options but I’ll focus on two:

  1. Download the Lottie JSON file

This is the option I went with for demo purposes. You can make use of the Lottie JSON in two ways.

One way might be to download the JSON file from “Download & export” on the navbar. Then upload the file on a server like GitHub pages where you can easily get the reference URL. (This is what I did because it won’t expire…see below 👇)

Download Lottie JSON file.
  1. Use the provided asset links

Another way would be to click on “Handoff & Embed” from the right-hand menu sidebar and toggle on “Enable Asset Link”.

Custom Lottie animation embed options.

From there, you can either get the link to the already hosted JSON file (from “Asset link” when the selected “Asset link format” is “Lottie JSON”) or embed using a generated code.

Custom Lottie embed scripts.

Note the asset link has an expiration date! You’ll have to upgrade to enable it permanently (the downside of this “easier” method).

Once you have your custom Lottie animation ready to go, then hop back onto the JavaScript.

Displaying the Lottie animation with a time delay

I want the Lottie animation to appear right after my message completes. To do this, we’ll need to wait until the typing ends.

Here goes another setTimeout(). This post should actually be called “JavaScript’s setTimeout() in action!”, huh?

Anyways, it does the job.

let animate = setTimeout( () => {
  document.querySelector('#lottie').innerHTML = '<lottie-player src="<https://thehelpfultipper.github.io/holiday_greetings/new_year_greet.json>"  background="transparent"  speed="1" loop  autoplay></lottie-player>';

}, text.length * 52);
  • The lottie-player src is pointing to the hosted GitHub page that contains the downloaded JSON file with the Lottie customizations we did earlier.
  • For the speed, it’s a simple calculation of the number of characters in the message (text.length) multiplied by the typing speed of each character (50 milliseconds) plus a 2-millisecond delay.

Let’s add some necessary styles to the Lottie component:

#lottie {
  background: purple;
  width: 100%;
  height: 100%; 
  position: relative;
}

lottie-player {
  position: absolute;
  top: -50px;
}

With the above code, I’m placing and sizing the Lottie animation appropriately within its container.

Wrapping up our responsive flex page layout

Have you noticed how we haven’t used any media queries up to this point?

Well, it’s time to include our one and only media query that’ll resize the message a bit on smaller devices.

@media (max-width: 460px) {
  #mssg {
    font-size: 1.65rem;
  }
}

But that’s all you really need – it’s the beauty of a responsive flex layout 😍

Tip: If you’re building a webpage for a portfolio or website, consider using CSS Grid to establish the overall page layout (i.e. navigation bar, main content area, sidebar, footer, etc.) and then Flexbox to place individual elements within those broad wrappers.

All source code references are available on GitHub!

Another project is done so bah bye 👋

See CSS Grid in Action: How To Install Font Awesome Icons In HTML

Related Posts