How To Create A Beating Heart Using HTML And CSS

by kleamerkuri
beating heart css html project

Create an animated beating heart using only HTML and CSS for a fun little side project that will let you explore the CSS animation properties.

Objective: Make a heart shape that will scale to bigger and smaller sizes (mimicking a heartbeat) using the CSS @keyframes rule.

This post will show you how to take two <div>s and turn them into a heart which is then animated over time intervals.

There are various ways you can go about this. If you come up with something else don’t forget to share it in the comments below!

See the Pen Beating Heart by Klea Merkuri (@thehelpfultipper) on CodePen.

Start by creating a heart shape

Let’s begin with two squares representing the left and right sides of a heart. Give each a different color for now so we can see them individually when forming the heart shape. Also, determine the size you want the heart to be.

<div id="left"></div>

<div id="right"></div>
#right, #left {

    width: 200px;
    height: 200px;

}

#right {
    background-color: rgb(182, 0, 0);
}

#left {
    background-color: yellow;
}

Notice we use a CSS selector list to group similar styles for #right and #left. Then set unique styles using id selectors.

For more on CSS selectors, read Common CSS Selectors To Know And How To Use Them.

create the left and right parts of a heart 1
Two stacked squares in yellow and red.

Center the body content and rotate

Place the two squares side by side in the center of the window by setting a flex display for the body (the parent of the two <div>s).

body {

    display: flex;
    align-items: center;
    justify-content: center;
    margin-top: 10%;
}

Read: CSS Visual Formatting: Floating, Positioning, & Layout

Rotate both #right and #left the same amount in opposite directions using the CSS transform property’s rotate() function. Specify the degree of rotation inside rotate().

For #right use transform: rotate(-45deg) and for #left use transform: rotate(-135deg). The negative keeps us on the upper part of the trigonometric circle. If you don’t recall shit about geometry, that’s what we’ll leave it at because, quite frankly, it’s been years since my last geometry class (and DM failed his . . . ).

You should get something like this:

css transform rotate div 2
Each square is rotated by the same amount in opposite directions.

Bring the right half about 50px closer to the left by setting its position.

position: relative;
left: -50px;

Turn the top corners of both #right and #left into curved edges using border-radius.

border-top-right-radius: 50%;
border-bottom-right-radius: 50%;

Your “heart” is slowly taking shape:

css heart shape 3
Give the squares rounded edges at the top and overlap.

Fill in the “gaps” in your heart using ::before

Use the CSS pseudo selector ::before to insert another equal-sized square before the content of #left.

The ::before selector requires you to specify the content property. In this case, content should be just an empty string because there isn’t any “content” inside the div. Since this added square is considered the first child of #left, any styles applied to #left also apply to it unless overridden.

#left::before {

    content: '';
    width: 200px;
    height: 200px;
    background-color: yellow;
    position: absolute;
    left: -105px;

}
left side of css heart shape 4
Extending the left side of the heart using ::before.

Do the same thing for #right.

#right::before {

    content: '';
    width: 200px;
    height: 200px;
    background-color: rgb(182, 0, 0);
    position: absolute;
    left: -105px;

}

Also, go back and change the yellow color of #left so the heart can be a uniform color. We made our point here – no need to distinguish between the two sides (unless it suits your fancy).

Our completed heart looks something like this:

complete css heart shape 5
Complete heart shape using HTML and CSS.

Animate your heart so it has a heartbeat

Time for animation! Our heart so far is static and does nothing other than awe us with its brilliance.

Begin by declaring a name for the animation to reference later on using the @keyframes rule. We, also, set a duration of 2 seconds. This means whatever effects or actions we define in @keyframes will occur in the span of 2 seconds.

If we stop here, by default the animation will end once the 2 seconds are up. But we want the heart to keep on beating, so we define the CSS animation-iteration-count property as infinite.

The animation is declared on the body, the parent that holds the heart pieces. Everything we declare in the animation will affect all children of the parent container.

Add the following to your body:

animation-name: beat;
animation-duration: 2s;
animation-iteration-count: infinite;

Refresh the page and notice nothing happens – yet. This is where the @keyframes rule comes into play. Though we defined the parameters of the “beat” animation, we haven’t said what exactly is supposed to happen during those infinite-looped 2 seconds.

With @keyframes we define the steps in the sequence, mainly the scaling that creates the “pulsing” effect.

Add an effect in steps ranging from 0% to 100% where 0% is the starting point of the animation when the heart is made larger. Halfway through, at 50%, it becomes smaller than the starting size with a background of pink. Then it ends at 100% enlarged once again.

@keyframes beat {

    0% {

        transform: scale(1.2);

    }

    50% {

        transform: scale(0.8);
        background-color: lightpink;

    }

    100% {

        transform: scale(1.2);

    }

}

And that’s a wrap! Challenge yourself to add white rings around the heart once it shrinks at 50% for greater intrigue.

You can find the source code on GitHub and you can follow us on socials for more heart-rendering goodies 😉

More projects: How To Make An Animated Button With CSS

Related Posts