Reanimating the CSS Day Buttons
Reanimating the CSS Day Buttons ź“ė Ø
Are you as excited aboutĀ CSS DayĀ as I am? While browsing the conference website, I couldnāt help but notice their big firebrick-red buttons. A website isnāt just about displaying content, itās about creating excitement. Every interaction should feel polished and engaging, especially buttons, which are the primary way users navigate the site.
A well-animated button can capture attention, reinforce branding, and make the experience more enjoyable. In this article, weāll take a closer look at the existing buttons and explore ways to enhance them with modern CSS techniques.
First, here is a version of the button that is currently on the website. Hover over the button to see its shape change.
TheĀ a
Ā element is wrapped with aĀ div
Ā that has a solid background color, and theĀ hover
Ā effect sets theĀ div
ās background toĀ transparent
, revealing theĀ a
ās arrow shape, created using aĀ clip-path
. The transition between the states (the āfadeā of the background) creates weird looking triangles.
I think that we can improve on that by using some movement and dynamics.
Approach 1: Background Image Animations
One simple-yet-effective way to add flair to buttons is by animating aĀ background-image
. Well, weāre not really animating the image, but we can achieve a smooth transition effect that feels dynamic by animating theĀ background-position
Ā property.
Here is a button that uses a linear transition on theĀ background-position
:
button {
border: 2px solid firebrick;
background: linear-gradient(120deg, white 50%, firebrick 0) 0 0/ 250% 100%;
color: firebrick;
padding: 0.6em 1em 0.7em;
cursor: pointer;
transition: all 0.5s;
&:hover {
background-position-x: 100%;
color: white;
}
}
In this example the background stretches the gradient horizontally to 2.5 times the width of the button, and the backgroundās position changes fromĀ 0%
Ā toĀ 100%
. to better understand this effect, you can use the āVisualize backgroundā checkbox.
So how do you useĀ background-position
Ā to create the arrow-shaped hover effect? Weāll actually need to layer two backgrounds and control both positions. Hereās how:
The pointed shape is created using two simpleĀ conic-gradients
, and again, the background stretches each gradient to 2.5 times the width of the button, so we can set theĀ background-position
Ā to bring the center of these conics in and out of view.
This method can actually be quite powerful and is great for many applications. And while I love using (and animating) background gradients, maybe for this specific use case itās not the best option. So letās try something elseā¦
Approach 2: Clip-Path Transition
Another way to animate shapes in CSS is by using clipping, allowing us to create unique shapes and transitions. In our case, the buttons already have aĀ clip-path
Ā property, so letās use it. Weāll set it to theĀ hover
Ā state, and āresetā theĀ polygon
Ā on idle.
button {
display: block;
border: none;
background: var(--yearColour);
color: white;
padding: 0.6em 1em 0.7em;
clip-path: polygon(0% 0%, 100% 0%, 100% 50%, 100% 100%, 0% 100%, 0% 50%);
cursor: pointer;
transition: clip-path 0.5s;
&:hover {
clip-path: polygon(0% 0%, 95% 0%, 100% 50%, 95% 100%, 0% 100%, 5% 50%);
}
}
Note
Note that in order to transition the movement, the number of nodes in theĀ polygon
Ā shapes must be the same.
This approach already looks nice, but I think we can do better.
When working withĀ clip-path
Ā (and clipping in general) you need to remember that the clipping is inwards, removing parts of your elements, and you canāt overflow anything outside the clipped area. If we do want to expand outward from our element, we need to first expend the element itself, and then adjust the clipping.
.button-v2 {
display: block;
border: none;
background: var(--yearColour);
color: white;
padding: 0.6em 1.3em 0.7em;
clip-path: polygon(2.5% 0%, 97.5% 0%, 97.5% 50%, 97.5% 100%, 2.5% 100%, 2.5% 50%);
cursor: pointer;
transition: clip-path 0.5s;
&:hover {
clip-path: polygon(0% 0%, 95% 0%, 100% 50%, 95% 100%, 0% 100%, 5% 50%);
}
}
In the above example Iāve increased the inlineĀ padding
, making the element wider, then adjusted the idle state of theĀ polygon
Ā to remove the added width. Now the clipping is not just inward, but also expands out, which not only creates a more dynamic effect but also reduces the risk of cutting into the buttonās content.
Here is a live demo of the two versions, In my opinion, this second shape looks slightly better overall. Which one do you like?
Solving the Challenge of the Dotted Button
While the previous techniques work well for solid buttons, the CSS Day website also has a dotted-style button. These require a different approach, sinceĀ background-image
Ā andĀ clip-path
Ā alone donāt handle dotted outlines effectively.
Approach 3: Pseudo-Elements and Transforms
Somehow, whenever thereās an animation or interaction that feels tricky to implement, it often turns out that pseudo-elements (e.g. ::before
and ::after
) are the solution. Theyāre like the hidden superpower of every element, allowing us to do some really cool things.
In this case, we can achieve a clean and elegant solution using pseudo-elements. The idea is pretty straightforward: ensure each pseudo-element spans the full width of the button and half the height. We place one element at the top of the button and the second at the bottom. Then, on hover, we apply a skew transformation to the elements. Simple enough? Hereās a live demo:
Letās break down what we added:
- We appliedĀ
position: relative;
Ā to the button as weāre going to position the pseudo-elements usingĀposition: absolute
. - For the pseudo-elements, we started with shared styling: positioning, size, color,Ā
z-index
, and of course, aĀtransition
Ā so everything moves smoothly. - TheĀ
::before
Ā pseudo-element is placed atĀtop: 0;
Ā to serve as the background for the top half of the button, and theĀ::after
Ā pseudo-element is positioned atĀbottom: 0;
Ā to cover the bottom half. - We added aĀ
transform
Ā with a simpleĀskew
Ā function along the X-axis, and usedĀcalc
Ā to adjust the direction of the skew in theĀ::after
Ā element so the skew effects are applied in two different directions. - The last thing we added is aĀ
hover
Ā state that defines the desired skew angle, transforming the button into an arrow shape.
So how do pseudo-elements help us solve the dotted button challenge? Itās simple: all we need to do is change the text color of the button and the background color of the pseudo-elements, then apply a dotted border. The key is to ensure that theĀ ::before
Ā has a border on the sides and top, while theĀ ::after
Ā gets a border on the sides and bottom.
.button.dotted {
color: firebrick;
&::before, &::after {
background-color: white;
border: dotted firebrick;
}
&::before {
border-width: 2px 2px 0;
}
&::after {
border-width: 0 2px 2px;
}
}
Thatās it. Iāve also added a version that changes the button color after the shape shifts on hover. Here are live examples of both versions:
Wrapping Up
Weāve reanimated the CSS Day 2025 buttons by experimenting with different CSS techniques:
- Background-image animationsĀ for smooth gradient transitions.
- Clip-path effectsĀ for unique button shapes.
- Pseudo-elementsĀ to create a dynamic dotted button effect.
Each approach offers distinct advantages (and some drawbacks), and itās important to familiarize ourselves with various animation options so that we can choose the most suitable one for each case based on the design needs, the desired effect, and the buttonās context
Want to take this further? Try incorporating CSS Variables for more flexibility or mixing inĀ @keyframes
Ā for even more animation control. Happy coding!