CSS Button Hover Effects: Examples You Can Copy
Copy CSS for color, lift, outline, and glow effects, with keyboard focus, touch, and reduced-motion support built in.
Use the CSS :hover pseudo-class to change a button’s appearance while a pointing device is over it. Keep the action available through the native button, show keyboard focus separately with :focus-visible, and treat hover as an enhancement: touch devices may not have a sustained hover state.
Here is a complete starting point you can copy. It includes color feedback, a small lift, a visible keyboard focus indicator, a pressed state, and reduced-motion support.
<button class="button" type="button">Save changes</button>
<style>
.button {
border: 0;
border-radius: 0.4rem;
padding: 0.7rem 1rem;
color: white;
background: #3157c8;
cursor: pointer;
transition: background-color 160ms ease, transform 160ms ease;
}
.button:hover {
background: #2444a8;
transform: translateY(-2px);
}
.button:focus-visible {
outline: 3px solid #172554;
outline-offset: 3px;
}
.button:active {
transform: translateY(1px);
}
@media (prefers-reduced-motion: reduce) {
.button {
transition: none;
}
}
</style>
Change the colors to fit your design and check that both the button label and focus outline remain easy to see against their surroundings. The example is a starting point, not a guarantee that every color pairing has sufficient contrast.
1. Choose the right element and states
Use a real <button> for an action such as saving, submitting, opening a dialog, or toggling a setting. Native buttons work with mouse, keyboard, touch, voice commands, and assistive technology. Use an <a> for navigation to another location. Avoid styling a decorative element such as a <div> to imitate a control.
These states have different jobs:
:hoverresponds when a pointing device is over the button.:focus-visibleindicates keyboard focus when the browser determines that focus feedback is appropriate.:activegives feedback while the control is being activated.
Do not remove the browser’s focus indicator unless you replace it with a visible one. Hover and focus may share some styling, but keyboard users still need a clear way to identify the focused control. MDN documents button behavior and focus considerations in its HTML button reference.
2. Copyable hover effect examples
Color change
A color change is a clear, low-motion cue. Keep the label legible in both states and provide focus feedback independently.
.button-color {
color: #fff;
background: #3157c8;
border: 1px solid #3157c8;
}
.button-color:hover {
color: #fff;
background: #2444a8;
border-color: #2444a8;
}
.button-color:focus-visible {
outline: 3px solid #172554;
outline-offset: 3px;
}
Lift on hover and press on activation
A small transform can make a button feel raised under a pointer and pressed during activation. The :active state is separate from hover, so a press remains meaningful even where hover is unavailable.
.button-lift {
border: 0;
border-radius: 0.5rem;
padding: 0.75rem 1rem;
color: #fff;
background: #176b58;
box-shadow: 0 2px 5px rgb(0 0 0 / 18%);
transition: transform 150ms ease, box-shadow 150ms ease;
}
.button-lift:hover {
transform: translateY(-2px);
box-shadow: 0 6px 12px rgb(0 0 0 / 20%);
}
.button-lift:active {
transform: translateY(0);
}
.button-lift:focus-visible {
outline: 3px solid #102d26;
outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
.button-lift {
transition: none;
}
.button-lift:hover,
.button-lift:active {
transform: none;
}
}
Outline and border change
An outline-style button can fill on hover. Ensure that the focus treatment does not disappear into the hover styling; the example uses an offset outline that remains distinct.
.button-outline {
border: 2px solid #3157c8;
border-radius: 0.4rem;
padding: 0.65rem 0.95rem;
color: #2444a8;
background: transparent;
transition: color 150ms ease, background-color 150ms ease;
}
.button-outline:hover {
color: #fff;
background: #3157c8;
}
.button-outline:focus-visible {
outline: 3px solid #172554;
outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
.button-outline {
transition: none;
}
}
Shadow or glow
A glow can decorate the pointer state, but it should not be the only way to tell that the button is interactive. Retain a legible color or border state and a separate focus indicator.
.button-glow {
border: 1px solid #74a7ff;
border-radius: 0.5rem;
padding: 0.75rem 1rem;
color: #fff;
background: #173b7a;
transition: box-shadow 160ms ease, background-color 160ms ease;
}
.button-glow:hover {
background: #204b91;
box-shadow: 0 0 0.8rem rgb(116 167 255 / 65%);
}
.button-glow:focus-visible {
outline: 3px solid #b9d4ff;
outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
.button-glow {
transition: none;
}
}
3. Make hover work alongside keyboard and touch
Hover is a pointer state. Touch behavior differs by browser, and a touch interaction may not produce a lasting hover state. Keep the button’s label and operation available without hover. MDN describes the touch caveat in its :hover reference.
- Test the action with a keyboard. Tab to the button and confirm its focus indicator is visible.
- Test the action on a touch device. The button should still communicate its purpose and respond when tapped.
- Keep hover and focus feedback distinguishable enough that the active keyboard target is clear.
- Respect reduced-motion preferences when effects move or animate. W3C shows how to disable hover and focus motion with
prefers-reduced-motionin its reduced-motion example.
Focus and hover highlighting can help communicate that an element is interactive; W3C’s Technique C15 provides an example of focus presentation. W3C techniques are examples of ways to meet accessibility criteria, rather than a required coding method.
Links styled as buttons
If the control navigates, use a link and account for link states in the cascade. For links, MDN documents the common LVHA order: :link, :visited, :hover, then :active. Later rules can otherwise override earlier states unexpectedly.
.action-link:link {
color: #2444a8;
}
.action-link:visited {
color: #5a3a91;
}
.action-link:hover {
color: #17306f;
}
.action-link:focus-visible {
outline: 3px solid currentColor;
outline-offset: 3px;
}
.action-link:active {
color: #10204b;
}
When hover reveals extra content
A color change is not the same as revealing a tooltip, menu, or other content. If hover or focus exposes meaningful additional content, follow the applicable hover and focus guidance: the content should be hoverable, dismissible, and persistent. W3C explains these expectations in its guidance for content on hover or focus. Do not put essential button instructions or functionality behind hover alone.
4. Apply the effect to a real page
- Choose a semantic button for an action or a link for navigation.
- Start with a visible default style and a label that explains the control.
- Add one pointer treatment, such as a color shift, a small lift, or a shadow.
- Add a distinct
:focus-visibleindicator and an optional:activepressed state. - Use a reduced-motion media query for transitions or movement.
- Check text and focus visibility against the actual page colors, then try keyboard and touch input.
For a quick browser check, place each example beside the starter button, load the page, and move a mouse pointer over it. Then tab to the button and activate it with the keyboard; finally, check the same action by touch. These checks help reveal state and input problems, but they do not replace evaluating contrast in the actual design.
5. Troubleshooting common problems
| Symptom | Likely cause | Fix |
|---|---|---|
| The hover style does not appear. | The selector does not match the element, another rule wins in the cascade, or the test device does not provide a sustained hover state. | Confirm the button has the class used by the CSS, inspect the computed styles, and test with a mouse or trackpad. Keep the action usable on touch without hover. |
| The label changes but becomes hard to read. | The hover foreground and background do not work together. | Choose a legible color pairing for both default and hover states and evaluate it in the page design. |
| Keyboard users cannot tell which button is focused. | The focus outline was removed or is hidden against adjacent colors. | Add a visible :focus-visible outline with enough offset and check it against the page background. |
| The focus ring disappears when the button is hovered. | Hover styling overrides or visually blends with focus styling. | Keep a dedicated focus rule and use an outline or other clear treatment that remains visible in both states. |
| The button moves when reduced motion is enabled. | The transform or transition was not covered by the reduced-motion rule. | Inside @media (prefers-reduced-motion: reduce), remove the transition and disable or reduce movement. |
| A tooltip or label vanishes while the pointer moves toward it. | The revealed content is not reachable by pointer or does not persist. | Design the hover/focus content so it can be reached and remains available as applicable; provide a way to dismiss it. See W3C’s SCR39 technique. |
| A link’s pressed or hover color never appears. | Another link-state rule later in the stylesheet overrides it. | Review selector specificity and keep link state rules in a clear LVHA order. |
6. Performance, reliability, and maintenance
For a small hover effect, keep the CSS direct: change a color, border, shadow, or modest transform, and avoid adding elaborate motion without a clear purpose. Use transitions only on the properties you intend to animate rather than applying them indiscriminately. Keep the core action and label independent of the hover state, so the interface still communicates and works where hover is unavailable.
When maintaining a component library, define shared default, hover, focus, and active states in one place. Test the states after changing theme colors, since an outline or glow that was visible on one background may blend into another. A reduced-motion rule should cover every transition and movement introduced by the component.
7. Or skip the browser setup
If you are documenting or reviewing the button in a rendered page, ScreenshotNeo can capture a webpage through one API request. Its cookie and consent handling accepts the banner like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the shot. Each step can be turned off. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing; the response identifies the page verdict and billing status in headers.
Use this cURL request to capture a page as WebP:
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://stripe.com \
-o shot.webp
The same endpoint works with Python and Node.js:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://stripe.com'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);
Replace https://stripe.com with the page you want to capture. The ScreenshotNeo API documentation covers the request options and response details. ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for AI agents and MCP clients. It includes 1,000 screenshots each month on the free plan with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo to get 1,000 free screenshots a month with no card.
8. Frequently asked questions
Should every button have a hover effect?
No. Add one when it helps communicate interactivity and fits the interface. The default appearance, label, and operation should already make sense.
Can I use :hover to show a button’s only label?
Keep the button’s purpose visible without hover. Some users do not have a pointer that can sustain that state.
Is a glow enough to show keyboard focus?
Use a dedicated focus indicator that keyboard users can identify clearly. A decorative hover glow can be part of the design, but should not replace visible focus feedback.
Do W3C examples require a specific CSS implementation?
No. W3C techniques describe examples of ways to meet accessibility criteria; they are not the only acceptable coding approach.


