CSS Button Generator
Style a button and all its states, check it against WCAG 2.2, then copy the code.
Preview
Accessibility checks (WCAG 2.2)
Start from a style
Label and icon
Text
Colours and shadow
Size and shape
Hover, press and motion
Keyboard focus ring
Press Tab in the preview to see the ring as keyboard users do, or choose the Focus state.
Code
HTML
CSS
About the CSS Button Generator
Design a button visually: the label, a font from your system or the self-hosted library, size and weight, padding, corner radius, a solid colour or a gradient, border, shadow and an optional icon before or after the text — or an icon-only button with an accessible name. Then shape its states: the hover colour and lift, the pressed colour and squeeze, the keyboard focus ring and the transition, with a reduced-motion fallback written for you.
While you work, the tool checks the button against WCAG 2.2: label contrast in every state (gradients at their weakest point), focus-ring contrast against what surrounds it, and the target size measured in the browser. Copy the HTML and CSS, Tailwind CSS v4 or v3 classes, or a matching primary, secondary and ghost set whose labels are adjusted to stay readable.
How to use it
- Pick a style to start from, or keep the default and change it.
- Set the label and icon, then the text, colours, size and shape.
- Under Hover, press and motion, keep the automatic hover and pressed colours or choose your own; set the lift, the pressed size and the transition.
- Use the State buttons (or hover, click and Tab in the preview) and read the accessibility checks underneath; fix anything marked Fail.
- Under Code, choose HTML + CSS, Tailwind v4 or Tailwind v3, and copy — or switch the preview to Set of three for primary, secondary and ghost buttons.
Examples
White text, background #2563eb, 16px semibold, padding 12px 22px
Label contrast 5.16:1 — passes 4.5:1 (WCAG 1.4.3, AA) Focus ring #1d4ed8 on white: 6.70:1 — passes 3:1 Height 45px — passes 24 × 24 (2.5.8) and 44 × 44 (2.5.5)
Set of three · main colour #93c5fd on a white page
The outline and ghost labels use a darker #3b699c, so they keep at least 4.5:1 on the page and on their hover tint.
On a white page, #93c5fd text would only reach 1.80:1.
Default button · Tailwind v4
inline-flex items-center justify-center gap-[0.5em] min-h-[44px] px-[22px] py-[12px] … enabled:hover:bg-[#124fd6] motion-safe:enabled:hover:-translate-y-[1px] focus-visible:outline-[3px] focus-visible:outline-offset-[2px] focus-visible:outline-[#1d4ed8] disabled:opacity-55
enabled: keeps a disabled button from reacting, and motion-safe: leaves out movement for people who ask their system to reduce motion.
Common uses
- Creating call-to-action buttons for a landing page that pass accessibility audits.
- Turning a brand colour into a consistent primary, secondary and ghost button set.
- Getting a Tailwind class list for a button without looking up every utility.
- Teaching or reviewing how hover, active, focus-visible and disabled styles fit together.
What the checks mean
- Label contrast — WCAG 2.2 SC 1.4.3 Contrast (Minimum): text needs 4.5:1 against its background, or 3:1 when it is large (at least 24px, or 18.66px bold). The tool checks the resting, hover and pressed colours, and samples a gradient along its whole length. An icon-only button is checked at 3:1, the level for graphics.
- Focus ring — 1.4.11 Non-text Contrast with 2.4.7 Focus Visible: an outline drawn outside the button must reach 3:1 against the page around it; one drawn inside (a negative offset) against the button.
outline: nonewithout a replacement fails. - Focus ring size — 2.4.13 Focus Appearance (AAA): at least as large as a 2px outline around the button, with 3:1 between the focused and unfocused pixels.
- Target size — 2.5.8 Target Size (Minimum): at least 24 × 24 CSS pixels, measured on the real button in your browser (smaller targets can pass if they are spaced 24px apart). 44 × 44 px meets the enhanced level 2.5.5 and is easier to tap.
- Button edge: WCAG does not require a button to have a 3:1 border or background when its text shows it is a button; the tool mentions it because a visible edge helps people find controls.
How the states are written
Hover and pressed styles use :not(:disabled, [aria-disabled="true"]), so a disabled button does not react, and the disabled style lowers opacity — WCAG exempts inactive controls from contrast rules. Focus uses :focus-visible, which shows the ring for keyboard users without flashing it on every mouse click. Automatic hover and pressed colours move the background’s OKLCH lightness a few steps darker (or lighter for dark buttons) while keeping its hue. A prefers-reduced-motion rule removes the transition and the movement, and the Tailwind output puts movement behind motion-safe:.
Fonts
System fonts need no download: system-ui shows San Francisco on Apple devices, Segoe UI on Windows and Roboto on Android. The library fonts (Inter, Poppins, Montserrat, Noto Sans, Archivo and display and handwriting faces) are open-licence (SIL OFL 1.1) families served from this site for the preview. To use one on your own site, load it there — the CSS comment shows the Fontsource package that self-hosts it.
Limitations
- The contrast checks use the colours you enter; text over a background image or video cannot be checked here.
- The preview shows how your browser draws the button; fonts, rounding and shadows can differ slightly in others.
- Tailwind output uses arbitrary values (such as
px-[22px]) to keep your exact numbers; you may prefer to map them to your theme scale. - Target size is measured for the button alone; whether nearby targets are spaced far enough apart depends on your page layout.
Privacy
Everything happens in your browser. What you enter or open here is not uploaded or stored by MySmartCoPilot.
Frequently asked questions
Should I use a <button> or a link styled as a button?
Use <button type="button"> (or type="submit" in a form) when it does something on the page, and <a href="…"> when it goes to another page. The generated CSS works on both; it sets text-decoration: none so a link looks the same.
Why is my focus ring marked Fail?
The ring must reach 3:1 against the colour next to it. A light blue ring on a white page often has less. Pick a darker ring colour, make it thicker, or move it inside the button with a negative offset and check it against the button colour instead.
Does an icon-only button need a label?
Yes. It needs an accessible name, so the generated HTML puts your label in aria-label and hides the icon from screen readers with aria-hidden="true".
How do I keep the hover effect from playing for people who dislike motion?
The CSS includes @media (prefers-reduced-motion: reduce), which removes the transition and the lift and squeeze; colour changes still show. In Tailwind, the movement classes start with motion-safe:.
Is anything uploaded?
No. The button is built in your browser, and the page works offline once loaded.