How To Make An Animated Button With CSS

by kleamerkuri
How To Make An Animated Button With CSS

Make a simple animated button using only HTML and CSS to add a little charm to your projects.

As a reference, we’ll be using Shawn Rossouw’s awesome-looking Futuristic Button design. The animation will all happen using the handy CSS transition property.

Follow along or give it a try by yourself – the end product shall look something like this:

See the Pen Animated Button by Klea Merkuri (@thehelpfultipper) on CodePen.

1. Set up and center the button

Start by creating a button element and use a display of flex to center it on the screen.

<button>Hover & See</button>

body {

    margin: 0;
    padding: 0;
    background-color: #18191C;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;

}

Override default browser margins and paddings for the body and set a height of 100vh to make use of the entire available window. Setting a height is necessary to center the button vertically using align-items. Then use justify-content to center the button horizontally.

Read more on flexbox and how to place items on screen here.

centered html button 1

2. Add styles to the animated button

Let’s begin by adjusting the size of the button. Define paddings to create space within the button and use the CSS transform property to increase the button’s size by setting a scale() value.

increase button size transform css 2

Set a transparent background and add a border with slightly (very slightly) rounded edges using border-radius.

button {

    padding: 20px 30px;
    transform: scale(2.4);
    letter-spacing: 0.2em;
    background: transparent;
    color: #295F6B;
    border: 1px solid #21424D;
    border-radius: 2px;

}

This is what we have so far:

transparent background and rounded edges css 3

Define the hover state effects


On hover, two things other than the animation occur:

  1. the text color changes to a lighter blue
  2. a muted blur surrounds the button giving it a “glow”

To mimic the “glow” of the button on hover like in our reference design, we’ll use the CSS box-shadow property with a blur of 5px.

button:hover {

    color: #50C8ED;
    box-shadow: 0 0 5px #1C3A42;

}

For box-shadow, the first two values define the x and y offsets respectively which we don’t need here. Think of them as the coordinates on an axis. So two positive values will move the shadow towards the upper right corner of a coordinate plane whereas two negative values will move the shadow to the bottom left corner.

Learn more about the CSS box-shadow property here.

Tip: Need help generating a box-shadow? Check out this box-shadow generator!

3. Include the animated lines

If you’re following along, we’re about to do some adjustments to account for the animated lines.

There are different ways to “do” the lines, so after scratching our heads for a hot minute we ended up going with 4 individual <div>s representing the left/right and top/bottom lines respectively.

Our HTML looks like this now:

<div id="container">

    <div id="left-border"></div>
    <div id="top-border"></div>

    <button>Hover & See</button>

    <div id="bottom-border"></div>
    <div id="right-border"></div>

</div>

The lines and the button are wrapped in #container so it can act as the parent relative to which we can place the lines.

Style #container in two ways:

  • take the transform property that scales the button from <button> and place in #container. When scale() is applied to a parent, the effect will also impact the children. Everything in #container will, therefore, be scaled appropriately which is what we want.
  • set position as relative because the “lines” will be placed according to their position relative to the parent.
#container {

    transform: scale(2.4);
    position:relative;

}

Create the side lines (left & right)


To get the side lines use border-left and border-right. Set a height to specify the vertical length and a position of absolute to position the lines absolutely relative to their parent, #container.

Then use top and left as well as bottom and right to place the vertical side lines along the button’s border.

#left-border {

    height: 16px;
    border-left: 1px solid #3D7D96;
    position: absolute;
    top: 15px;
    left: 0px;

}

#right-border {

    height: 16px;
    border-left: 1px solid #3D7D96;
    position: absolute;
    bottom: 15px;
    right: 0px;

}

Note: You don’t need to use bottom and right – you can use top and left. Challenge yourself and give it a try! (Hint: negative values…)

Create the top & bottom lines


Similar to the side lines, we can build the top and bottom horizontal lines. The main difference here is that we’re setting the width (instead of height) and we’re moving horizontally using left and right (instead of vertically using top and bottom).

#top-border {

    width: 50px;
    border-top: 1px solid #3D7D96;
    position: absolute;
    top: 0;
    left: 15px;

}

#bottom-border {

    width: 50px;
    border-top: 1px solid #3D7D96;
    position: absolute;
    bottom: 0;
    right: 15px;

}

This is what we have so far:

side border lines on button

Pretty much static as the only interaction so far occurs on hover when the “glow” happens. Next, let’s add the animation part of the button on hover as well.

4. Make the button animated on hover

Observing our reference, notice that:

  1. on hover, each side and its adjacent top line coalesce in equal-widths towards the top and bottom corners of the button
  2. when not hovering, the lines bounce back to their static locations and sizes

We’ll animate the button using the CSS transition property assigned to each of the four border lines. All four transition statements will have the same time-lapse (0.2 seconds) and effect (ease-in-out). The only value that changes is the first value that determines the property to transition.

In the case of the left border, transition: top 0.2s ease-in-out, where “top” refers to the top property which, on hover, will go from 15px to 0px, moving the line up at a speed of “0.2s” at a rate that starts out slowly then picks up.

Go ahead and add the appropriate transitions to each of the four border lines.

#left-border {
    ... 
    transition: top 0.2s ease-in-out;
}

#top-border {
    ... 
    transition: left 0.2s ease-in-out;
}

#right-border {
    ... 
    transition: bottom 0.2s ease-in-out;
}

#bottom-border {
    ... 
    transition: right 0.2s ease-in-out;
}

Hover over the button and you’ll see nothing is actually animated yet. That’s because we have identified how the animation should play out, but we haven’t specified what those first value properties will change into on hover.

Just telling the browser to “transition the top property at 0.2 seconds starting out slowly” without actually saying what we’re transitioning the top into isn’t going to get us very far (if anywhere at all).

The next step is to state the to what part. For instance, on hover, we want to transition the left border’s top property from 15px to 0px. That “0px” value is a new top value for the left border which occurs once the user hovers over the button.

Make the button “do” the animation


To transition an element based on our actions over another element, we’ll need to establish the shared relationship between the elements affected. Since the button and the border lines are separate elements wrapped within the parent #container, we can easily set the animation hover effects by using a CSS child combinator.

#container:hover > #left-border {

    top: 0px;
    border-top-left-radius: 2px;

}

#container:hover > #right-border {

    bottom: 0px;
    border-bottom-right-radius: 2px;

}

#container:hover > #top-border {

    left: 0px;
    width: 16px;
    border-top-left-radius: 2px;

}

#container:hover > #bottom-border {

    right: 0px;
    width: 16px;
    border-top-left-radius: 2px;

}

Note: You can be less strict and opt for a descendant combinator instead!

And that’s a wrap – the futuristic button design is now an interactive animated button using only HTML and CSS. Stay tuned for more projects to come!

Grab the completed code on GitHub and leave a comment if you tried it below.

Related Posts