05 / 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 3D Press Effect Button
A tactile 3D button that physically sinks into its own raised platform on click, simulating a keycap-style press using CSS transforms and layered box-shadows.
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-05">
<p class="ab-05__label">Click or tap the buttons</p>
<div class="ab-05__row">
<button class="ab-05__btn ab-05__btn--indigo">Purchase Now</button>
<button class="ab-05__btn ab-05__btn--emerald">Download App</button>
<button class="ab-05__btn ab-05__btn--rose">Delete File</button>
</div>
</div><div class="ab-05">
<p class="ab-05__label">Click or tap the buttons</p>
<div class="ab-05__row">
<button class="ab-05__btn ab-05__btn--indigo">Purchase Now</button>
<button class="ab-05__btn ab-05__btn--emerald">Download App</button>
<button class="ab-05__btn ab-05__btn--rose">Delete File</button>
</div>
</div>.ab-05,
.ab-05 *,
.ab-05 *::before,
.ab-05 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.ab-05 ::selection {
background: #4338ca;
color: #fff;
}
.ab-05 {
font-family: system-ui,sans-serif;
background: #f8fafc;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 2.5rem;
padding: 2rem;
}
.ab-05__label {
font-size: .78rem;
letter-spacing: .12em;
text-transform: uppercase;
color: #64748b;
}
.ab-05__row {
display: flex;
gap: 1.25rem;
flex-wrap: wrap;
justify-content: center;
}
.ab-05__btn {
--face: #6366f1;
--depth: #3730a3;
position: relative;
padding: .85rem 2.2rem;
font-size: 1rem;
font-weight: 800;
color: #fff;
background: var(--face);
border: none;
border-radius: 10px;
cursor: pointer;
outline: none;
letter-spacing: .03em;
box-shadow: 0 6px 0 var(--depth),0 8px 12px rgba(0,0,0,.18);
transition: transform .08s,box-shadow .08s;
will-change: transform;
user-select: none;
}
.ab-05__btn--indigo {
--face: #6366f1;
--depth: #3730a3;
}
.ab-05__btn--emerald {
--face: #10b981;
--depth: #065f46;
}
.ab-05__btn--rose {
--face: #f43f5e;
--depth: #9f1239;
}
.ab-05__btn:hover {
filter: brightness(1.05);
}
.ab-05__btn:active {
transform: translateY(4px);
box-shadow: 0 2px 0 var(--depth),0 4px 6px rgba(0,0,0,.12);
}
@media (prefers-reduced-motion: reduce) {
.ab-05__btn {
transition: none;
}
}.ab-05,
.ab-05 *,
.ab-05 *::before,
.ab-05 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.ab-05 ::selection {
background: #4338ca;
color: #fff;
}
.ab-05 {
font-family: system-ui,sans-serif;
background: #f8fafc;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 2.5rem;
padding: 2rem;
}
.ab-05__label {
font-size: .78rem;
letter-spacing: .12em;
text-transform: uppercase;
color: #64748b;
}
.ab-05__row {
display: flex;
gap: 1.25rem;
flex-wrap: wrap;
justify-content: center;
}
.ab-05__btn {
--face: #6366f1;
--depth: #3730a3;
position: relative;
padding: .85rem 2.2rem;
font-size: 1rem;
font-weight: 800;
color: #fff;
background: var(--face);
border: none;
border-radius: 10px;
cursor: pointer;
outline: none;
letter-spacing: .03em;
box-shadow: 0 6px 0 var(--depth),0 8px 12px rgba(0,0,0,.18);
transition: transform .08s,box-shadow .08s;
will-change: transform;
user-select: none;
}
.ab-05__btn--indigo {
--face: #6366f1;
--depth: #3730a3;
}
.ab-05__btn--emerald {
--face: #10b981;
--depth: #065f46;
}
.ab-05__btn--rose {
--face: #f43f5e;
--depth: #9f1239;
}
.ab-05__btn:hover {
filter: brightness(1.05);
}
.ab-05__btn:active {
transform: translateY(4px);
box-shadow: 0 2px 0 var(--depth),0 4px 6px rgba(0,0,0,.12);
}
@media (prefers-reduced-motion: reduce) {
.ab-05__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 3D Press Effect Button
Source: https://codefronts.com/motion/css-animated-buttons/css-3d-press-effect-button/
A tactile 3D button that physically sinks into its own raised platform on click, simulating a keycap-style press using CSS transforms and layered box-shadows.
## HTML
```html
<div class="ab-05">
<p class="ab-05__label">Click or tap the buttons</p>
<div class="ab-05__row">
<button class="ab-05__btn ab-05__btn--indigo">Purchase Now</button>
<button class="ab-05__btn ab-05__btn--emerald">Download App</button>
<button class="ab-05__btn ab-05__btn--rose">Delete File</button>
</div>
</div>
```
## CSS
```css
.ab-05,
.ab-05 *,
.ab-05 *::before,
.ab-05 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.ab-05 ::selection {
background: #4338ca;
color: #fff;
}
.ab-05 {
font-family: system-ui,sans-serif;
background: #f8fafc;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 2.5rem;
padding: 2rem;
}
.ab-05__label {
font-size: .78rem;
letter-spacing: .12em;
text-transform: uppercase;
color: #64748b;
}
.ab-05__row {
display: flex;
gap: 1.25rem;
flex-wrap: wrap;
justify-content: center;
}
.ab-05__btn {
--face: #6366f1;
--depth: #3730a3;
position: relative;
padding: .85rem 2.2rem;
font-size: 1rem;
font-weight: 800;
color: #fff;
background: var(--face);
border: none;
border-radius: 10px;
cursor: pointer;
outline: none;
letter-spacing: .03em;
box-shadow: 0 6px 0 var(--depth),0 8px 12px rgba(0,0,0,.18);
transition: transform .08s,box-shadow .08s;
will-change: transform;
user-select: none;
}
.ab-05__btn--indigo {
--face: #6366f1;
--depth: #3730a3;
}
.ab-05__btn--emerald {
--face: #10b981;
--depth: #065f46;
}
.ab-05__btn--rose {
--face: #f43f5e;
--depth: #9f1239;
}
.ab-05__btn:hover {
filter: brightness(1.05);
}
.ab-05__btn:active {
transform: translateY(4px);
box-shadow: 0 2px 0 var(--depth),0 4px 6px rgba(0,0,0,.12);
}
@media (prefers-reduced-motion: reduce) {
.ab-05__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 3D Press Effect Button
Source: https://codefronts.com/motion/css-animated-buttons/css-3d-press-effect-button/
A tactile 3D button that physically sinks into its own raised platform on click, simulating a keycap-style press using CSS transforms and layered box-shadows.
## HTML
```html
<div class="ab-05">
<p class="ab-05__label">Click or tap the buttons</p>
<div class="ab-05__row">
<button class="ab-05__btn ab-05__btn--indigo">Purchase Now</button>
<button class="ab-05__btn ab-05__btn--emerald">Download App</button>
<button class="ab-05__btn ab-05__btn--rose">Delete File</button>
</div>
</div>
```
## CSS
```css
.ab-05,
.ab-05 *,
.ab-05 *::before,
.ab-05 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.ab-05 ::selection {
background: #4338ca;
color: #fff;
}
.ab-05 {
font-family: system-ui,sans-serif;
background: #f8fafc;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 2.5rem;
padding: 2rem;
}
.ab-05__label {
font-size: .78rem;
letter-spacing: .12em;
text-transform: uppercase;
color: #64748b;
}
.ab-05__row {
display: flex;
gap: 1.25rem;
flex-wrap: wrap;
justify-content: center;
}
.ab-05__btn {
--face: #6366f1;
--depth: #3730a3;
position: relative;
padding: .85rem 2.2rem;
font-size: 1rem;
font-weight: 800;
color: #fff;
background: var(--face);
border: none;
border-radius: 10px;
cursor: pointer;
outline: none;
letter-spacing: .03em;
box-shadow: 0 6px 0 var(--depth),0 8px 12px rgba(0,0,0,.18);
transition: transform .08s,box-shadow .08s;
will-change: transform;
user-select: none;
}
.ab-05__btn--indigo {
--face: #6366f1;
--depth: #3730a3;
}
.ab-05__btn--emerald {
--face: #10b981;
--depth: #065f46;
}
.ab-05__btn--rose {
--face: #f43f5e;
--depth: #9f1239;
}
.ab-05__btn:hover {
filter: brightness(1.05);
}
.ab-05__btn:active {
transform: translateY(4px);
box-shadow: 0 2px 0 var(--depth),0 4px 6px rgba(0,0,0,.12);
}
@media (prefers-reduced-motion: reduce) {
.ab-05__btn {
transition: none;
}
}
```How this works
The raised look is created by a large bottom-offset box-shadow that acts as a physical "depth" layer below the button face — e.g. 0 6px 0 #4338ca gives 6px of solid underhang. On :active, a transform: translateY(4px) moves the button face downward to visually close most of that gap, while the box-shadow shrinks to 0 2px 0 … so the remaining depth appears compressed. This two-property change is all that's needed to sell the physical press illusion.
A subtle transition: transform .08s, box-shadow .08s on very short duration mimics the instantaneous spring of a real mechanical key. On release, the button springs back to its elevated position. will-change: transform keeps the active state transition on the GPU compositor. The label shifts up 1px on active via the same transform to add realism to the sinking feel.
Make it yours
- Increase depth by raising the first
box-shadowy-offset from6pxto10pxand matching the:activetranslateYto8px. - Change the button colour by updating
--faceand setting--depthto a darker shade of the same hue (roughly 20% darker works well). - Round the button to a circle for icon-only press buttons by setting
border-radius: 50%and equalisingwidthandheight. - Add a subtle inner bevel by adding an
inset 0 1px 0 rgba(255,255,255,.25)shadow layer to the non-active state for a highlight on the top edge. - Pair with a click sound using the Web Audio API in JS — this CSS-only demo degrades to a purely visual effect without the audio layer.
Gotchas — read before shipping
- If the button is inside a
transform-ed container (e.g. a card withrotateY), thetranslateYon:activecompounds with the parent transform — test in context. - Very fast repeated clicks can cause the
transitionto stutter — adduser-select: noneto prevent text selection on rapid tapping which interrupts the active state. - On touch devices the
:activestate is triggered bytouchstartand released ontouchend— this mirrors the keyboard press naturally without extra JS.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 36+ | 9+ | 16+ | 36+ |
Uses only CSS transforms and box-shadows; universally supported.