Skip to main content

Overview

The lum-btn utility creates fully-styled, accessible buttons with smooth animations, hover effects, and adaptive padding.

CSS Implementation

@utility lum-btn {
  @apply flex items-center 
         motion-safe:transition duration-300 hover:duration-75 active:duration-75 ease-out 
         disabled:opacity-50 
         hover:drop-shadow-lg active:drop-shadow-lg 
         motion-safe:active:scale-95 
         whitespace-nowrap touch-manipulation select-none 
         lum-btn-p-2 text-base 
         lum-bg-lum-input-bg 
         hover:lum-bg-lum-input-hover-bg 
         active:lum-bg-lum-input-hover-bg;
  border-radius: var(--lum-border-radius);
  corner-shape: superellipse(var(--lum-border-superellipse));
}

Usage

<button class="lum-btn">
  Click me
</button>

Applied Classes

The lum-btn utility applies the following Tailwind classes:

Layout

  • flex items-center - Flexbox with centered items
  • whitespace-nowrap - Prevents text wrapping

Animation

  • motion-safe:transition - Smooth transitions (respects reduced-motion)
  • duration-300 - 300ms transition by default
  • hover:duration-75 - Faster 75ms transition on hover
  • active:duration-75 - Faster 75ms transition on active
  • ease-out - Easing function
  • motion-safe:active:scale-95 - Slight scale down on click

Effects

  • hover:drop-shadow-lg - Large drop shadow on hover
  • active:drop-shadow-lg - Large drop shadow on active
  • disabled:opacity-50 - 50% opacity when disabled

Interaction

  • touch-manipulation - Optimized for touch devices
  • select-none - Prevents text selection

Styling

  • lum-btn-p-2 - Smart padding utility (see below)
  • text-base - Base font size
  • lum-bg-lum-input-bg - Background color
  • hover:lum-bg-lum-input-hover-bg - Hover background
  • active:lum-bg-lum-input-hover-bg - Active background
  • border-radius: var(--lum-border-radius) - Rounded corners
  • corner-shape: superellipse - Smooth superellipse corners

lum-btn-p-* (Padding Utility)

Smart padding utility that creates adaptive padding with a 2:1 horizontal to vertical ratio.

CSS Implementation

@utility lum-btn-p-* {
  padding: calc(var(--spacing) * --value(integer))
           calc(var(--spacing) * --value(integer) * var(--lum-btn-p-x))
           calc(var(--spacing) * --value(integer))
           calc(var(--spacing) * --value(integer) * var(--lum-btn-p-x));

  gap: calc(
    var(--spacing) * --value(integer) * clamp(0.65, 4 / --value(integer), 1)
  );
}

Usage

<button class="lum-btn lum-btn-p-1">
  Small
</button>

Padding Scale

lum-btn-p-1
utility
Small: 0.25rem vertical, 0.5rem horizontal (4px/8px)
lum-btn-p-2
utility
Default: 0.5rem vertical, 1rem horizontal (8px/16px)
lum-btn-p-3
utility
Large: 0.75rem vertical, 1.5rem horizontal (12px/24px)
lum-btn-p-4
utility
Extra Large: 1rem vertical, 2rem horizontal (16px/32px)
The gap between button content (text and icons) is automatically calculated based on padding size with adaptive scaling.

CSS Variables

--lum-btn-p-x
number
default:"2"
Horizontal padding multiplier (creates 2:1 horizontal to vertical ratio)
--lum-border-radius
length
default:"var(--radius-lg)"
Border radius for button corners
--lum-border-superellipse
number
default:"1"
Superellipse corner smoothing (0 = circle, 1 = squircle, 2+ = rounded square)
--color-lum-input-bg
color
default:"var(--color-gray-800)"
Default button background color
--color-lum-input-hover-bg
color
default:"var(--color-gray-700)"
Hover and active background color

States

Hover State

<button class="lum-btn">
  <!-- On hover: -->
  <!-- - Lighter background (gray-700) -->
  <!-- - Drop shadow appears -->
  <!-- - Faster 75ms transition -->
  Hover me
</button>

Active State

<button class="lum-btn">
  <!-- On click/active: -->
  <!-- - Scales down to 95% -->
  <!-- - Lighter background (gray-700) -->
  <!-- - Drop shadow appears -->
  <!-- - Faster 75ms transition -->
  Click me
</button>

Disabled State

<button class="lum-btn" disabled>
  <!-- When disabled: -->
  <!-- - 50% opacity -->
  <!-- - No hover/active effects -->
  <!-- - Cursor: not-allowed (browser default) -->
  Disabled
</button>

Focus State

<button class="lum-btn">
  <!-- On focus (from lum-bg utility): -->
  <!-- - Accent border appears -->
  <!-- - No outline -->
  Focus me with Tab
</button>
The button inherits focus styles from the lum-bg utility. Make sure you don’t override these with focus:outline-none unless you provide alternative focus indicators for accessibility.

Customization Examples

<button class="lum-btn lum-bg-blue-600 hover:lum-bg-blue-500 active:lum-bg-blue-500 text-white">
  Primary Action
</button>

Accessibility

The lum-btn utility includes several accessibility features:
  • Respects prefers-reduced-motion with motion-safe: variants
  • Touch-optimized with touch-manipulation
  • Prevents accidental text selection with select-none
  • Includes disabled state with visual feedback
  • Inherits focus styles from lum-bg utility

Best Practices

  1. Always use semantic <button> elements for actions
  2. Add type="button" to prevent form submission
  3. Include descriptive text or aria-label for icon-only buttons
  4. Don’t override focus styles without providing alternatives
  5. Use appropriate color contrast for text
  6. Consider loading states with disabled attribute

Build docs developers (and LLMs) love