Snippets / UI Components /

Outline Button

Ghost/outline button with visible border and transparent background, with hover fill effect.

Widely Supported
ui no-js

Quick implementation

.outline-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.625rem 1.25rem;
  background-color: transparent;
  color: var(--accent);
  font-weight: 600;
  font-size: 0.95rem;
  border: 1.5px solid var(--accent);
  border-radius: var(--radius);
  cursor: pointer;
  transition: all 0.2s ease;
}

.outline-button:hover {
  background-color: var(--accent);
  color: var(--bg);
}

.outline-button:active {
  transform: scale(0.98);
}

.outline-button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.outline-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

Prompt this to your LLM

Includes role, constraints, two framework variants, and edge cases to handle.

You are a senior frontend engineer specializing in accessible button design and visual hierarchy.

Your goal: Build an outline (ghost) button that communicates "secondary action" through a transparent background and colored border—with a smooth fill effect on hover.

Technical constraints:
1. Use transparent background with colored border (not solid background)
2. Border width must be 1.5–2px for visibility
3. Text color should match border color for visual consistency
4. Hover state must fill background with border color (inverted contrast)
5. On hover, text color must flip to ensure readability on filled background
6. Active state should include visual feedback (scale, shadow, or color shift)
7. Focus state must use outline for keyboard navigation
8. Must maintain minimum 44px clickable area on touch devices
9. All state transitions must be smooth (0.2–0.3s)

Vanilla implementation:
- Create button.outline-button selector with transparent background and border
- Use :hover to set background-color and invert text color
- Use :active with transform: scale() for press feedback
- Apply :focus-visible with outline in contrasting color
- Provide :disabled state with opacity reduction

React implementation:
- Create Button component with variant prop (outline, solid, etc.)
- Support size prop (sm, md, lg) for responsive button sizing
- Use CSS Modules or styled-components for state management
- Support loading state with spinner overlay and disabled during load
- Export accessible ButtonGroup component for button clusters

Edge cases to handle:
1. Very long text: ensure button doesn't overflow container
2. Icon + text combinations: align properly with flexbox gap
3. Multiple buttons in a row: maintain consistent spacing (0.75–1rem gap)
4. Dark mode: ensure border is visible on dark background
5. Tooltip below button: don't interfere with focus outline

Why this matters in 2026

Outline buttons are the Swiss Army knife of secondary actions. They work in any context—light or dark backgrounds—because their visual weight comes from the border, not fill. This makes them incredibly versatile for complex UIs with multiple competing actions.

The hover-fill effect creates immediate visual feedback that communicates interactivity through animation. Users can see the button "activate" without waiting for a page load. In 2026, this micro-interaction is table stakes for premium UX. Outline buttons also reduce visual noise compared to solid secondary buttons, making primary CTAs stand out.

The logic

The outline button starts with background-color: transparent and a colored border using var(--accent). The text color also uses var(--accent), creating visual unity. On hover, the background fills with the accent color, and the text color inverts to var(--bg) to maintain contrast.

The active state uses transform: scale(0.98) to create a subtle compression effect that simulates pressing. The focus-visible outline uses the accent color with a 2px width and 2px offset to create a clear focus indicator for keyboard navigation. The disabled state reduces opacity to 0.5 while maintaining the border, so users can still see what action is unavailable.

Accessibility & performance

Accessibility: Outline buttons must maintain sufficient contrast between text and background in all states. The initial state (accent text on dark background) should have a 4.5:1 contrast ratio. The hover state (inverted: dark text on accent background) must also meet 4.5:1. The border itself acts as a visual indicator of the button's interactive nature. Always include :focus-visible with a clearly visible outline for keyboard users.

Performance: The background-color, color, and transform transitions all have minimal performance cost. The 0.2s duration is ideal—fast enough to feel responsive without introducing jank. Avoid animating border-width or padding, which trigger layout recalculations. Use transform and opacity for all animations.