Home / Snippets / UI Components /
Ghost button
Transparent with border — fills on hover for a clean secondary action.
Quick implementation
.btn-ghost {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.65rem 1.5rem;
font: 600 0.9rem/1.2 system-ui, sans-serif;
color: oklch(0.72 0.19 265);
background: transparent;
border: 1.5px solid oklch(0.72 0.19 265);
border-radius: 0.5rem;
cursor: pointer;
transition: background 0.2s ease-out, color 0.2s ease-out;
}
.btn-ghost:hover {
background: oklch(0.52 0.22 265 / 0.1);
}
.btn-ghost:active {
transform: scale(0.97);
}
.btn-ghost:focus-visible {
outline: 2px solid oklch(0.72 0.19 265);
outline-offset: 3px;
}
.btn-ghost:disabled {
opacity: 0.45;
cursor: not-allowed;
pointer-events: none;
}
Prompt this to your LLM
Includes role, constraints, two framework variants, and edge cases to handle.
You are a senior frontend engineer building a button system.
Goal: A ghost (outline) button for secondary actions with complete state coverage.
Technical constraints:
- Transparent background with a 1.5px solid border matching the text color.
- Hover: add a subtle background tint using oklch() with alpha.
- Active: scale(0.97) for press feedback.
- Focus-visible: 2px outline with 3px offset — keyboard only.
- Disabled: opacity 0.45, pointer-events: none.
- Use oklch() for all colors, not hex or rgba().
Framework variant (pick one):
A) Vanilla HTML + CSS only.
B) React component — accept variant, disabled, onClick, and children props.
Edge cases to handle:
- Ghost button on dark backgrounds must have enough contrast (check WCAG).
- Pair with a primary button — the ghost button should feel lighter.
- Ensure the border does not cause layout shift vs a borderless primary button (use matching padding).
Return CSS. No JavaScript.
Why this matters in 2026
Ghost buttons provide a visual hierarchy below primary buttons. They say "this is an action, but not the main one." Without a proper ghost variant, teams end up with text links styled as buttons or inconsistent secondary actions. A well-crafted ghost button completes a design system's button tier.
The logic
The button starts transparent with a border matching the text color. On hover, a tinted background appears using oklch() with low alpha — this keeps the effect subtle without introducing a new color. :focus-visible ensures keyboard users see the outline without it appearing on mouse click. The transition on background and color creates a smooth state change.
Accessibility & performance
Ghost buttons must meet WCAG AA contrast requirements for both the text and the border against the page background. On dark backgrounds, oklch(0.72 0.19 265) provides sufficient contrast. Never rely on border alone for visibility — color-blind users may not distinguish the border from the background. All transitions use compositor-friendly properties for smooth rendering.