02 / 20
All 20 in 20 CSS Animated Buttons
- 01CSS Neon Glow Button
- 02CSS Background Slide Hover Button
- 03CSS Pure CSS Ripple Effect Button
- 04CSS Animated Border Draw Button
- 05CSS 3D Press Effect Button
- 06CSS Liquid Fill Button Animation
- 07CSS Moving Gradient CTA Button
- 08CSS Shine Sweep Hover Button
- 09CSS Jelly Bounce Button Animation
- 10CSS Text Flip Button Hover
- 11CSS Animated CTA Hero Button
- 12CSS Submit Button Success State
- 13CSS Animated Download Button
- 14CSS Hamburger To Close Button
- 15CSS Add To Cart Button Animation
- 16CSS Social Share Buttons Hover
- 17CSS Animated Toggle Switch Button
- 18CSS Loading Spinner Inside Button
- 19CSS Next Prev Arrow Button Hover
- 20CSS Ghost Button Background Reveal
CSS Background Slide Hover Button
Four directional background-slide hover buttons — left, right, top, and bottom — where a solid fill sweeps across the button face on hover using CSS pseudo-element transforms.
Build UI like this from scratch: Flexbox, Grid, animations & responsive CSS
ZTM · The CSS Bootcamp · 30‑day money-back guarantee · Affiliate link
The code
<div class="ab-02">
<p class="ab-02__title">Background Slide Directions</p>
<div class="ab-02__grid">
<button class="ab-02__btn ab-02__btn--left"><span>Slide Left</span></button>
<button class="ab-02__btn ab-02__btn--right"><span>Slide Right</span></button>
<button class="ab-02__btn ab-02__btn--top"><span>Slide Top</span></button>
<button class="ab-02__btn ab-02__btn--bottom"><span>Slide Bottom</span></button>
</div>
</div><div class="ab-02">
<p class="ab-02__title">Background Slide Directions</p>
<div class="ab-02__grid">
<button class="ab-02__btn ab-02__btn--left"><span>Slide Left</span></button>
<button class="ab-02__btn ab-02__btn--right"><span>Slide Right</span></button>
<button class="ab-02__btn ab-02__btn--top"><span>Slide Top</span></button>
<button class="ab-02__btn ab-02__btn--bottom"><span>Slide Bottom</span></button>
</div>
</div>.ab-02,
.ab-02 *,
.ab-02 *::before,
.ab-02 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.ab-02 ::selection {
background: #6c63ff;
color: #fff;
}
.ab-02 {
--fill: #6c63ff;
--text: #1a1a2e;
--border: #6c63ff;
font-family: system-ui,sans-serif;
background: #f0eeff;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 2rem;
padding: 2rem;
}
.ab-02__title {
font-size: .8rem;
font-weight: 600;
letter-spacing: .12em;
text-transform: uppercase;
color: #6c63ff;
opacity: .7;
}
.ab-02__grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
.ab-02__btn {
position: relative;
overflow: hidden;
padding: .8rem 2rem;
font-size: .95rem;
font-weight: 700;
color: var(--fill);
background: transparent;
border: 2px solid var(--border);
border-radius: 8px;
cursor: pointer;
outline: none;
transition: color .35s;
letter-spacing: .03em;
}
.ab-02__btn span {
position: relative;
z-index: 1;
}
.ab-02__btn::before {
content: '';
position: absolute;
inset: 0;
background: var(--fill);
transition: transform .35s cubic-bezier(.4,0,.2,1);
z-index: 0;
}
.ab-02__btn:hover {
color: #fff;
}
.ab-02__btn--left::before {
transform: translateX(-100%);
}
.ab-02__btn--left:hover::before {
transform: translateX(0);
}
.ab-02__btn--right::before {
transform: translateX(100%);
}
.ab-02__btn--right:hover::before {
transform: translateX(0);
}
.ab-02__btn--top::before {
transform: translateY(-100%);
}
.ab-02__btn--top:hover::before {
transform: translateY(0);
}
.ab-02__btn--bottom::before {
transform: translateY(100%);
}
.ab-02__btn--bottom:hover::before {
transform: translateY(0);
}
.ab-02__btn:active {
transform: scale(.97);
}
@media (prefers-reduced-motion: reduce) {
.ab-02__btn::before {
transition: none;
}
.ab-02__btn {
transition: none;
}
}.ab-02,
.ab-02 *,
.ab-02 *::before,
.ab-02 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.ab-02 ::selection {
background: #6c63ff;
color: #fff;
}
.ab-02 {
--fill: #6c63ff;
--text: #1a1a2e;
--border: #6c63ff;
font-family: system-ui,sans-serif;
background: #f0eeff;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 2rem;
padding: 2rem;
}
.ab-02__title {
font-size: .8rem;
font-weight: 600;
letter-spacing: .12em;
text-transform: uppercase;
color: #6c63ff;
opacity: .7;
}
.ab-02__grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
.ab-02__btn {
position: relative;
overflow: hidden;
padding: .8rem 2rem;
font-size: .95rem;
font-weight: 700;
color: var(--fill);
background: transparent;
border: 2px solid var(--border);
border-radius: 8px;
cursor: pointer;
outline: none;
transition: color .35s;
letter-spacing: .03em;
}
.ab-02__btn span {
position: relative;
z-index: 1;
}
.ab-02__btn::before {
content: '';
position: absolute;
inset: 0;
background: var(--fill);
transition: transform .35s cubic-bezier(.4,0,.2,1);
z-index: 0;
}
.ab-02__btn:hover {
color: #fff;
}
.ab-02__btn--left::before {
transform: translateX(-100%);
}
.ab-02__btn--left:hover::before {
transform: translateX(0);
}
.ab-02__btn--right::before {
transform: translateX(100%);
}
.ab-02__btn--right:hover::before {
transform: translateX(0);
}
.ab-02__btn--top::before {
transform: translateY(-100%);
}
.ab-02__btn--top:hover::before {
transform: translateY(0);
}
.ab-02__btn--bottom::before {
transform: translateY(100%);
}
.ab-02__btn--bottom:hover::before {
transform: translateY(0);
}
.ab-02__btn:active {
transform: scale(.97);
}
@media (prefers-reduced-motion: reduce) {
.ab-02__btn::before {
transition: none;
}
.ab-02__btn {
transition: none;
}
}Here's a working CSS Animated Button from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Background Slide Hover Button
Source: https://codefronts.com/motion/css-animated-buttons/css-background-slide-hover-button/
Four directional background-slide hover buttons — left, right, top, and bottom — where a solid fill sweeps across the button face on hover using CSS pseudo-element transforms.
## HTML
```html
<div class="ab-02">
<p class="ab-02__title">Background Slide Directions</p>
<div class="ab-02__grid">
<button class="ab-02__btn ab-02__btn--left"><span>Slide Left</span></button>
<button class="ab-02__btn ab-02__btn--right"><span>Slide Right</span></button>
<button class="ab-02__btn ab-02__btn--top"><span>Slide Top</span></button>
<button class="ab-02__btn ab-02__btn--bottom"><span>Slide Bottom</span></button>
</div>
</div>
```
## CSS
```css
.ab-02,
.ab-02 *,
.ab-02 *::before,
.ab-02 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.ab-02 ::selection {
background: #6c63ff;
color: #fff;
}
.ab-02 {
--fill: #6c63ff;
--text: #1a1a2e;
--border: #6c63ff;
font-family: system-ui,sans-serif;
background: #f0eeff;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 2rem;
padding: 2rem;
}
.ab-02__title {
font-size: .8rem;
font-weight: 600;
letter-spacing: .12em;
text-transform: uppercase;
color: #6c63ff;
opacity: .7;
}
.ab-02__grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
.ab-02__btn {
position: relative;
overflow: hidden;
padding: .8rem 2rem;
font-size: .95rem;
font-weight: 700;
color: var(--fill);
background: transparent;
border: 2px solid var(--border);
border-radius: 8px;
cursor: pointer;
outline: none;
transition: color .35s;
letter-spacing: .03em;
}
.ab-02__btn span {
position: relative;
z-index: 1;
}
.ab-02__btn::before {
content: '';
position: absolute;
inset: 0;
background: var(--fill);
transition: transform .35s cubic-bezier(.4,0,.2,1);
z-index: 0;
}
.ab-02__btn:hover {
color: #fff;
}
.ab-02__btn--left::before {
transform: translateX(-100%);
}
.ab-02__btn--left:hover::before {
transform: translateX(0);
}
.ab-02__btn--right::before {
transform: translateX(100%);
}
.ab-02__btn--right:hover::before {
transform: translateX(0);
}
.ab-02__btn--top::before {
transform: translateY(-100%);
}
.ab-02__btn--top:hover::before {
transform: translateY(0);
}
.ab-02__btn--bottom::before {
transform: translateY(100%);
}
.ab-02__btn--bottom:hover::before {
transform: translateY(0);
}
.ab-02__btn:active {
transform: scale(.97);
}
@media (prefers-reduced-motion: reduce) {
.ab-02__btn::before {
transition: none;
}
.ab-02__btn {
transition: none;
}
}
```Here's a working CSS Animated Button from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Background Slide Hover Button
Source: https://codefronts.com/motion/css-animated-buttons/css-background-slide-hover-button/
Four directional background-slide hover buttons — left, right, top, and bottom — where a solid fill sweeps across the button face on hover using CSS pseudo-element transforms.
## HTML
```html
<div class="ab-02">
<p class="ab-02__title">Background Slide Directions</p>
<div class="ab-02__grid">
<button class="ab-02__btn ab-02__btn--left"><span>Slide Left</span></button>
<button class="ab-02__btn ab-02__btn--right"><span>Slide Right</span></button>
<button class="ab-02__btn ab-02__btn--top"><span>Slide Top</span></button>
<button class="ab-02__btn ab-02__btn--bottom"><span>Slide Bottom</span></button>
</div>
</div>
```
## CSS
```css
.ab-02,
.ab-02 *,
.ab-02 *::before,
.ab-02 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.ab-02 ::selection {
background: #6c63ff;
color: #fff;
}
.ab-02 {
--fill: #6c63ff;
--text: #1a1a2e;
--border: #6c63ff;
font-family: system-ui,sans-serif;
background: #f0eeff;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 2rem;
padding: 2rem;
}
.ab-02__title {
font-size: .8rem;
font-weight: 600;
letter-spacing: .12em;
text-transform: uppercase;
color: #6c63ff;
opacity: .7;
}
.ab-02__grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
.ab-02__btn {
position: relative;
overflow: hidden;
padding: .8rem 2rem;
font-size: .95rem;
font-weight: 700;
color: var(--fill);
background: transparent;
border: 2px solid var(--border);
border-radius: 8px;
cursor: pointer;
outline: none;
transition: color .35s;
letter-spacing: .03em;
}
.ab-02__btn span {
position: relative;
z-index: 1;
}
.ab-02__btn::before {
content: '';
position: absolute;
inset: 0;
background: var(--fill);
transition: transform .35s cubic-bezier(.4,0,.2,1);
z-index: 0;
}
.ab-02__btn:hover {
color: #fff;
}
.ab-02__btn--left::before {
transform: translateX(-100%);
}
.ab-02__btn--left:hover::before {
transform: translateX(0);
}
.ab-02__btn--right::before {
transform: translateX(100%);
}
.ab-02__btn--right:hover::before {
transform: translateX(0);
}
.ab-02__btn--top::before {
transform: translateY(-100%);
}
.ab-02__btn--top:hover::before {
transform: translateY(0);
}
.ab-02__btn--bottom::before {
transform: translateY(100%);
}
.ab-02__btn--bottom:hover::before {
transform: translateY(0);
}
.ab-02__btn:active {
transform: scale(.97);
}
@media (prefers-reduced-motion: reduce) {
.ab-02__btn::before {
transition: none;
}
.ab-02__btn {
transition: none;
}
}
```How this works
Each button contains a ::before pseudo-element that covers the full button area and holds the hover fill colour. By default the pseudo-element is pushed out of view using transform: translateX(-100%) (left variant), translateX(100%) (right), translateY(-100%) (top), or translateY(100%) (bottom). On :hover the transform resets to translate(0) which slides the fill into place over a transition of 0.35 s with a smooth ease curve.
The button text sits in a position: relative; z-index: 1 span so it always renders above the sliding fill layer. overflow: hidden on the button itself clips the pseudo-element as it enters from its starting edge, making the slide feel contained and intentional. Only transform is animated, so the browser compositor handles all motion without repaints.
Make it yours
- Change the slide direction by swapping the initial
transformon::before— usetranslateY(-100%)for a top-down sweep. - Adjust slide speed by editing the
transitionduration on.ab-02__btn::before(default.35s; try.2sfor snappier feel). - Use a gradient fill instead of a solid by replacing the
backgroundon::beforewithlinear-gradient(135deg, #6c63ff, #c471ed). - Change text colour on hover by adding a
transition: color .35sto the button and setting.ab-02__btn:hover { color: #fff }. - Stack two pseudo-elements (
::beforeand::after) with offset delays to create a two-tone layered slide effect.
Gotchas — read before shipping
- The
overflow: hiddenon the button clipsbox-shadow— move the shadow to a wrapper element if you need both an outer glow and the slide effect. - If the button has
border-radius, the pseudo-element corners are correctly clipped, but verify on Safari < 15 where overflow clipping with transforms occasionally mis-clips. - Avoid
width: autoon::before— always use100%explicitly, as percentage widths in absolutely-positioned pseudo-elements can calculate incorrectly inside flex or grid containers.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 49+ | 9.1+ | 44+ | 49+ |
Universally supported; relies only on CSS transforms and pseudo-elements.