CSS Button Generator
Design a button visually — colors, padding, font, border, radius, shadow and a hover state — then copy ready-made .btn and .btn:hover rules. Hover the live preview to feel the transition. Everything runs in your browser.
↑ Hover (or focus) the button to see the hover state
Output uses the class .btn. Copy both rules below, or change .btn to your own class name after pasting. Built on your device — nothing you design is uploaded.
What the generated CSS actually contains
Every button here is described by two rules. The base .btn { … } rule sets the resting appearance — text color, background, padding, font-size, font-weight, an optional border, border-radius and box-shadow, plus cursor: pointer and a transition. The second rule, .btn:hover { … }, changes only the background. That single-property hover is deliberate: the fewer things a hover changes, the more predictable it is, and one background swap covers the vast majority of real buttons.
Why the transition lives on the base rule, not on :hover
This is the mistake that trips people up most, so the tool is opinionated about it. A transition only takes effect while it is in scope. Put transition: all 150ms ease inside .btn:hover and the pointer arriving triggers the animation — but the moment it leaves, the :hover rule (and its transition) no longer applies, so the button snaps back instantly instead of easing out. Declaring the transition on the base .btn rule keeps it in scope in both states, so the colour eases in and out symmetrically. That is why this generator always emits the transition on .btn.
Worked example: the default button
.btn {
color: #ffffff;
background: #5b6cff;
padding: 12px 24px;
font-size: 16px;
font-weight: 600;
border-radius: 8px;
cursor: pointer;
transition: all 150ms ease;
}
.btn:hover {
background: #4553d8;
}
Notice what is not there: no border line (the border width is 0, so it would draw nothing) and no box-shadow line (it is set to none). The generator drops any property whose value is a no-op, which keeps the block short and honest — you paste exactly what does something and nothing that doesn't.
The omitted-defaults rule
Three properties are conditional. border is emitted only when its width is above 0; a 0px border paints nothing, so the line is dropped. border-radius is dropped when it is 0 (square corners are the initial value anyway). box-shadow is dropped when set to none. Everything else is always written out so the rule is fully self-contained: paste it into a fresh stylesheet and the button looks exactly like the preview, with no reliance on inherited or default values you might not have.
Padding, and why it reads Y then X
The two-value padding shorthand is padding: <vertical> <horizontal>, so padding: 12px 24px means 12px top and bottom, 24px left and right — which is why the sliders are labelled Padding Y and Padding X in that order. Buttons almost always want more horizontal than vertical padding; a comfortable starting ratio is roughly 2:1 (the default 12/24 is exactly that). When you happen to set the two equal, the output collapses to a single value like padding: 16px, since CSS applies one value to all four sides.
Colours: hex when opaque, rgba() when not
Solid colours are written as six-digit hex (#5b6cff) because it is the shortest unambiguous form. Drop the background opacity below 100% — handy for translucent or "ghost" buttons that let a page's background show through — and the same colour is re-emitted as rgba(91, 108, 255, 0.5), since a hex code can't reliably carry an alpha channel across every target. If you need to convert a specific colour by hand, the Color Converter turns any HEX into rgb/rgba and back.
Honest limits
This is a v1 focused on the common styling properties plus one hover transition, and it is honest about the edges. The hover state changes only the background — if you want the text colour, border or shadow to shift on hover too, add those lines to the .btn:hover rule after copying. On a gradient button the hover background is still a single solid colour, so the button flattens on hover; swap in a second linear-gradient by hand if you need the gradient to move. There is no active/pressed state, no focus-visible ring (add :focus-visible yourself for accessibility), and no icon or animation-library output — nothing here depends on a framework. For richer effects, pair it with the Box-Shadow Generator for layered shadows, the Border-Radius Generator for per-corner rounding, and the Gradient Generator for multi-stop backgrounds.