CSS Tips
Button Hover Animation with Sliding Background
Combine pseudo-elements and transform to create an impressive button hover effect.
Introduction
Button hover effects are an important element for visually communicating user interaction.
This article introduces how to create an animation where the background color appears from left to right on hover and disappears to the right when unhovered, using only CSS.
Completed Demo
Hover over the button. The background slides in from the left, and slides out to the right when you move away.
<button class="demo-hover-btn">Hover me!</button>
.demo-hover-btn {
padding: 1rem 2rem;
font-size: 1rem;
font-weight: 600;
border: 2px solid #667eea;
background: transparent;
color: #667eea;
cursor: pointer;
position: relative;
overflow: hidden;
border-radius: 8px;
transition: color 0.3s ease;
isolation: isolate;
}
.demo-hover-btn::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.4s ease;
z-index: -1;
}
.demo-hover-btn:hover {
color: #fff;
}
.demo-hover-btn:hover::before {
transform: scaleX(1);
transform-origin: left;
}
How It Works
This animation is achieved by combining the ::before pseudo-element and transform: scaleX().
Here are the three key points:
1. **Create a background layer with pseudo-element**
Use ::before to create a background color layer that covers the entire button.
2. **Hide initially with scaleX(0)**
Setting the horizontal scale to 0 makes it invisible at first.
3. **Control direction with transform-origin**
By setting left (expands from left) on hover and right (shrinks to right) when not hovered, you create a unidirectional flowing animation.
HTML Code
<button class="hover-btn">Hover me!</button>
CSS Code
.hover-btn {
padding: 1rem 2rem;
font-size: 1rem;
font-weight: 600;
border: 2px solid #667eea;
background: transparent;
color: #667eea;
cursor: pointer;
position: relative;
overflow: hidden;
border-radius: 8px;
transition: color 0.3s ease;
isolation: isolate; /* Create new stacking context */
}
.hover-btn::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.4s ease;
z-index: -1;
}
.hover-btn:hover {
color: #fff;
}
.hover-btn:hover::before {
transform: scaleX(1);
transform-origin: left;
}
Role of Each Property
position: relative
Sets the button as a reference point so the pseudo-element with position: absolute is positioned correctly within the button.
overflow: hidden
Clips the pseudo-element so it doesn't overflow the button's boundaries.
inset: 0
Shorthand for setting top, right, bottom, and left all to 0. The pseudo-element covers the entire button.
transform: scaleX(0)
Scales the element's width to 0 (invisible). scaleX(1) returns it to original size.
transform-origin
Specifies the transformation's origin point. 'right' scales from the right edge, 'left' from the left edge.
z-index: -1
Places the pseudo-element behind the button text so the text remains visible.
isolation: isolate
Creates a new stacking context. This ensures the z-index: -1 pseudo-element stays within the button.
The Key: Switching transform-origin
The most important aspect of this animation is switching transform-origin between hover and non-hover states.
**Non-hover state**: transform-origin: right;
→ With scaleX(0) from the right edge, it shrinks and disappears to the right
**Hover state**: transform-origin: left;
→ With scaleX(1) from the left edge, it expands and appears from the left
This switch creates a unidirectional animation: appearing from left on hover, disappearing to right on unhover.
Color Variations
By simply changing the background color, you can create buttons with various moods.
<div style="display: flex; gap: 1rem; flex-wrap: wrap;">
<button class="demo-hover-btn demo-hover-btn--green">Green</button>
<button class="demo-hover-btn demo-hover-btn--orange">Orange</button>
<button class="demo-hover-btn demo-hover-btn--pink">Pink</button>
</div>
.demo-hover-btn {
padding: 1rem 2rem;
font-size: 1rem;
font-weight: 600;
border: 2px solid #667eea;
background: transparent;
color: #667eea;
cursor: pointer;
position: relative;
overflow: hidden;
border-radius: 8px;
transition: color 0.3s ease;
isolation: isolate;
}
.demo-hover-btn::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.4s ease;
z-index: -1;
}
.demo-hover-btn:hover {
color: #fff;
}
.demo-hover-btn:hover::before {
transform: scaleX(1);
transform-origin: left;
}
.demo-hover-btn--green {
border-color: #00b894;
color: #00b894;
}
.demo-hover-btn--green::before {
background: linear-gradient(135deg, #00b894 0%, #00a885 100%);
}
.demo-hover-btn--orange {
border-color: #fdcb6e;
color: #e17055;
}
.demo-hover-btn--orange::before {
background: linear-gradient(135deg, #fdcb6e 0%, #e17055 100%);
}
.demo-hover-btn--pink {
border-color: #fd79a8;
color: #fd79a8;
}
.demo-hover-btn--pink::before {
background: linear-gradient(135deg, #fd79a8 0%, #e84393 100%);
}
Application Examples
This technique can be applied to various elements beyond buttons.
**Link Hover Effects**
You can animate text link underlines using this method.
**Card Hover**
Apply this effect to entire cards for background color changes on hover.
**Navigation Menus**
Create sliding background effects for menu items on hover.
Summary
By combining pseudo-elements, transform: scaleX(), and switching transform-origin, you can create impressive button hover effects.
Since it's achieved with CSS only without JavaScript, it's also excellent for performance. Customize colors and animation speeds to incorporate this into your projects.