Build production-ready buttons with full state lifecycle: default, hover, active, focus-visible, and disabled.
Focus styles are included for accessibility (WCAG).
Preview of focus-visible ring when Show focus ring is on
.btn {
background-color: #3b82f6;
border: none;
border-radius: 8px;
padding: 12px 24px;
color: #ffffff;
font-weight: 600;
cursor: pointer;
box-shadow: 0px 4px 12px rgba(0,0,0,0.20);
transition: box-shadow 0.2s, transform 0.2s, opacity 0.2s;
}
.btn:hover:not(:disabled) {
box-shadow: 0px 6px 20px rgba(0,0,0,0.25);
transform: translateY(-1px);
background-color: #2563eb;
}
.btn:active:not(:disabled) {
box-shadow: 0px 2px 8px rgba(0,0,0,0.20);
transform: translateY(0);
background-color: #1d4ed8;
}
.btn:focus { outline: none; }
.btn:focus-visible {
box-shadow: 0px 4px 12px rgba(0,0,0,0.20), 0 0 0 2px #3b82f6;
}
.btn:hover:focus-visible:not(:disabled), .btn:active:focus-visible:not(:disabled) {
box-shadow: 0px 6px 20px rgba(0,0,0,0.25), 0 0 0 2px #3b82f6;
}
.btn:disabled {
opacity: 0.6;
cursor: not-allowed;
pointer-events: none;
}Buttons use a base style plus pseudo-classes for interaction: :hover, :active, and :focus-visible. Primary buttons often use a solid background and shadow; secondary and outline buttons reduce emphasis. Disabled state should use reduced opacity and pointer-events: none.
Hover applies when the pointer is over the button. Active applies while the mouse button (or key) is pressed. Focus-visible shows when the button is focused by keyboard (or programmatically) and should always be visible for accessibility—prefer :focus-visible over :focus so mouse users don’t see a focus ring on click. Use .btn:hover:focus-visible to combine hover and focus styles without removing the ring.
Use semantic <button> (or role="button" with keyboard support). Never remove focus outline without providing a visible alternative (e.g. box-shadow ring). Ensure disabled buttons have sufficient contrast (WCAG 2.1 allows 3:1 for disabled). Avoid using only color to indicate state.
With plain CSS you define .btn and pseudo-class rules. With Tailwind you use utility classes or @apply in a component; for one-off buttons, arbitrary values like [box-shadow:0_4px_12px_rgba(0,0,0,0.2)] work. This generator outputs both so you can paste into a stylesheet or Tailwind config.
Copy the CSS and add it to your stylesheet. Apply the .btn class to your button. The output includes :hover, :active, :focus-visible, and :disabled for a full lifecycle.
Yes. For any state (default, hover, active) choose Gradient and enter a linear-gradient or radial-gradient value. Presets like CTA use gradients by default.
The generator uses :focus-visible and adds a visible focus ring for accessibility (WCAG). Hover styles do not remove the focus ring when the button is focused.
Explore these related free tools to enhance your productivity and workflow.
Generate CSS box shadows with custom offsets, blur, spread, color, and opacity
Create beautiful linear and radial CSS gradients with custom colors, angles, and stops
Create custom border radius values for all corners with individual or locked controls
Text effects with multi-layer shadows and CSS output