6 button hover effects in pure CSS
Six small hover effects, each a few lines of CSS with no JavaScript. Hover or tab to them to try, then copy the one you like.
UI loop
6 button hover effects
Everything in the preview is live. Try it.
The code, one by one
Fill slide
The colour sweeps in from the left and the text flips to stay readable.
<button class="hb-fill" type="button">Fill slide</button>
.hb-fill {
position: relative;
isolation: isolate;
overflow: hidden;
padding: 14px 24px;
border: 2px solid #17202C;
border-radius: 12px;
background: transparent;
color: #17202C;
font: inherit;
font-weight: 700;
cursor: pointer;
transition: color .35s;
}
.hb-fill::before {
content: "";
position: absolute;
inset: 0;
z-index: -1;
background: #17202C;
transform: scaleX(0);
transform-origin: left;
transition: transform .35s cubic-bezier(.65, 0, .35, 1);
}
.hb-fill:hover, .hb-fill:focus-visible { color: #FDF9F1; }
.hb-fill:hover::before, .hb-fill:focus-visible::before { transform: scaleX(1); }
Lift
Rises on hover with a warm shadow, and presses down when clicked.
<button class="hb-lift" type="button">Lift</button>
.hb-lift {
padding: 14px 24px;
border: 0;
border-radius: 12px;
background: #FF7A2F;
color: #17202C;
font: inherit;
font-weight: 700;
cursor: pointer;
box-shadow: 0 4px 10px rgba(168, 67, 11, .18);
transition: transform .25s cubic-bezier(.05, .7, .1, 1), box-shadow .25s cubic-bezier(.05, .7, .1, 1);
}
.hb-lift:hover, .hb-lift:focus-visible {
transform: translateY(-6px);
box-shadow: 0 20px 36px rgba(168, 67, 11, .38);
}
.hb-lift:active { transform: translateY(-2px) scale(.97); }
Border draw
A line runs around the edge, top and right first, then bottom and left.
<button class="hb-draw" type="button">Border draw</button>
.hb-draw {
position: relative;
padding: 14px 24px;
border: 0;
background: transparent;
color: #17202C;
font: inherit;
font-weight: 700;
cursor: pointer;
box-shadow: inset 0 0 0 2px rgba(23, 32, 44, .18);
}
.hb-draw::before, .hb-draw::after {
content: "";
position: absolute;
width: 0;
height: 0;
box-sizing: border-box;
border: 2px solid transparent;
}
.hb-draw::before { top: 0; left: 0; }
.hb-draw::after { right: 0; bottom: 0; }
.hb-draw:hover::before, .hb-draw:focus-visible::before {
width: 100%;
height: 100%;
border-top-color: #FF7A2F;
border-right-color: #FF7A2F;
transition: width .2s ease-out, height .2s ease-out .2s;
}
.hb-draw:hover::after, .hb-draw:focus-visible::after {
width: 100%;
height: 100%;
border-bottom-color: #FF7A2F;
border-left-color: #FF7A2F;
transition: border-color 0s .4s, width .2s ease-out .4s, height .2s ease-out .6s;
}
Arrow nudge
The arrow nudges forward and the blue settles into ink. A hint that something comes next.
<button class="hb-arrow" type="button">Get started <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></button>
.hb-arrow {
display: inline-flex;
align-items: center;
gap: 10px;
padding: 14px 22px;
border: 0;
border-radius: 999px;
background: #2F6BE0;
color: #FFFFFF;
font: inherit;
font-weight: 700;
cursor: pointer;
transition: background-color .3s;
}
.hb-arrow svg {
width: 18px;
height: 18px;
fill: none;
stroke: currentColor;
stroke-width: 2.4;
stroke-linecap: round;
stroke-linejoin: round;
transition: transform .3s cubic-bezier(.05, .7, .1, 1);
}
.hb-arrow:hover, .hb-arrow:focus-visible { background: #17202C; }
.hb-arrow:hover svg, .hb-arrow:focus-visible svg { transform: translateX(6px); }
Shine sweep
A streak of light passes over the button once on hover.
<button class="hb-shine" type="button">Shine</button>
.hb-shine {
position: relative;
overflow: hidden;
padding: 14px 24px;
border: 0;
border-radius: 12px;
background: #2F55D4;
color: #FFFFFF;
font: inherit;
font-weight: 700;
cursor: pointer;
}
.hb-shine::after {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: -60%;
width: 40%;
background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .55), transparent);
transform: skewX(-20deg);
transition: left .6s cubic-bezier(.65, 0, .35, 1);
}
.hb-shine:hover::after, .hb-shine:focus-visible::after { left: 120%; }
Warm glow
A dark button that warms up: an amber ring and a soft orange glow.
<button class="hb-glow" type="button">Glow</button>
.hb-glow {
padding: 14px 26px;
border: 0;
border-radius: 999px;
background: #17202C;
color: #FFDD9B;
font: inherit;
font-weight: 700;
cursor: pointer;
box-shadow: 0 0 0 0 rgba(255, 178, 63, 0), 0 0 0 0 rgba(255, 122, 47, 0);
transition: box-shadow .35s ease, color .35s;
}
.hb-glow:hover, .hb-glow:focus-visible {
color: #FFB23F;
box-shadow: 0 0 0 8px rgba(255, 178, 63, .35), 0 0 60px 12px rgba(255, 122, 47, .45);
}
How to use it
- Each effect also runs on :focus-visible, so keyboard users see it too. Keep that when you adapt them.
- Pick one effect per site and use it on every button. Mixing three styles makes a page feel unsure of itself.
- The colours are plain hex values. Swap them for your own, or for a palette from this library.
Showing an interaction like this to a client or in a tutorial? Framok records your screen and zooms in on every click for you.
Free to use in personal and commercial work. No credit needed, though a link back is always nice.