v1.1.1

Button

A clickable control that triggers an action.

Variants

Different visual styles for different contexts.

html
<button class="vt-btn vt-btn-primary">
  Primary
</button>
<button class="vt-btn vt-btn-secondary">
  Secondary
</button>
<button class="vt-btn vt-btn-bordered">
  Bordered
</button>
<button class="vt-btn vt-btn-ghost">
  Ghost
</button>
<button class="vt-btn vt-btn-danger">
  Danger
</button>
<button class="vt-btn vt-btn-link">
  Link
</button>

Sizes

Available in small, default, large, and icon sizes.

html
<button class="vt-btn vt-btn-primary vt-btn-sm">
  Small
</button>
<button class="vt-btn vt-btn-primary">
  Default
</button>
<button class="vt-btn vt-btn-primary vt-btn-lg">
  Large
</button>
<button class="vt-btn vt-btn-primary vt-btn-icon" aria-label="Continue">

  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-arrow-right vt-w-4 vt-h-4">
    <path d="M5 12h14"></path><path d="m12 5 7 7-7 7"></path>
  </svg>
</button>

With Icon

Buttons can include leading or trailing icons.

html
<button class="vt-btn vt-btn-primary">

  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-upload vt-w-4 vt-h-4">
    <path d="M12 3v12"></path><path d="m17 8-5-5-5 5"></path><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
  </svg>
  Upload
</button>
<button class="vt-btn vt-btn-bordered">

  Next
  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-chevron-right vt-w-4 vt-h-4">
    <path d="m9 18 6-6-6-6"></path>
  </svg>
</button>
<button class="vt-btn vt-btn-primary">

  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-mail vt-w-4 vt-h-4">
    <path d="m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7"></path><rect x="2" y="4" width="20" height="16" rx="2"></rect>
  </svg>
  Send Email
</button>

States

Disabled and loading states.

html
<button class="vt-btn vt-btn-primary" disabled="">
  Disabled
</button>
<button disabled="" class="vt-btn vt-btn-primary vt-opacity-80 vt-cursor-wait">
  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-loader-circle vt-w-4 vt-h-4 vt-animate-spin">
    <path d="M21 12a9 9 0 1 1-6.219-8.56"></path>
  </svg>
  Loading...
</button>
<button class="vt-btn vt-btn-bordered" disabled="">
  Disabled
</button>

Full Width

Button that stretches to fill its container.

html
<button class="vt-btn vt-btn-primary vt-w-full">
  Sign In
</button>
<button class="vt-btn vt-btn-bordered vt-w-full">
  Create Account
</button>

Icon Only

Buttons that contain only an icon, used for compact actions and toolbars.

html

Primary

Secondary

Bordered

Ghost

Danger

<div class="vt-text-center">
  <button class="vt-btn vt-btn-primary vt-btn-icon" aria-label="Edit">
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-pencil vt-w-4 vt-h-4">
      <path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"></path><path d="m15 5 4 4"></path>
    </svg>
  </button>
  <p class="vt-text-xs vt-text-foreground-muted vt-mt-2">Primary</p>
</div>

<div class="vt-text-center">
  <button class="vt-btn vt-btn-secondary vt-btn-icon" aria-label="Edit">
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-pencil vt-w-4 vt-h-4">
      <path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"></path><path d="m15 5 4 4"></path>
    </svg>
  </button>
  <p class="vt-text-xs vt-text-foreground-muted vt-mt-2">Secondary</p>
</div>

<div class="vt-text-center">
  <button class="vt-btn vt-btn-bordered vt-btn-icon" aria-label="Edit">
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-pencil vt-w-4 vt-h-4">
      <path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"></path><path d="m15 5 4 4"></path>
    </svg>
  </button>
  <p class="vt-text-xs vt-text-foreground-muted vt-mt-2">Bordered</p>
</div>

<div class="vt-text-center">
  <button class="vt-btn vt-btn-ghost vt-btn-icon" aria-label="Edit">
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-pencil vt-w-4 vt-h-4">
      <path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"></path><path d="m15 5 4 4"></path>
    </svg>
  </button>
  <p class="vt-text-xs vt-text-foreground-muted vt-mt-2">Ghost</p>
</div>

<div class="vt-text-center">
  <button class="vt-btn vt-btn-danger vt-btn-icon" aria-label="Delete">
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-trash-2 vt-w-4 vt-h-4">
      <path d="M10 11v6"></path><path d="M14 11v6"></path><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"></path><path d="M3 6h18"></path><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
    </svg>
  </button>
  <p class="vt-text-xs vt-text-foreground-muted vt-mt-2">Danger</p>
</div>

Icon Rounded

Circle icon buttons using rounded-full.

html
<button class="vt-btn vt-btn-primary vt-btn-icon vt-rounded-full" aria-label="Add">
  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-plus vt-w-4 vt-h-4">
    <path d="M5 12h14"></path><path d="M12 5v14"></path>
  </svg>
</button>
<button class="vt-btn vt-btn-secondary vt-btn-icon vt-rounded-full" aria-label="Like">
  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-heart vt-w-4 vt-h-4">
    <path d="M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5"></path>
  </svg>
</button>
<button class="vt-btn vt-btn-bordered vt-btn-icon vt-rounded-full" aria-label="Share">
  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-share-2 vt-w-4 vt-h-4">
    <circle cx="18" cy="5" r="3"></circle><circle cx="6" cy="12" r="3"></circle><circle cx="18" cy="19" r="3"></circle><line x1="8.59" x2="15.42" y1="13.51" y2="17.49"></line><line x1="15.41" x2="8.59" y1="6.51" y2="10.49"></line>
  </svg>
</button>
<button class="vt-btn vt-btn-ghost vt-btn-icon vt-rounded-full" aria-label="More options">
  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-ellipsis vt-w-4 vt-h-4">
    <circle cx="12" cy="12" r="1"></circle><circle cx="19" cy="12" r="1"></circle><circle cx="5" cy="12" r="1"></circle>
  </svg>
</button>

Icon Sizes

Icon buttons in small, default, and large sizes.

html

sm

md

lg

<div class="vt-text-center">
  <button class="vt-btn vt-btn-primary vt-btn-icon vt-btn-sm" aria-label="Add">
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-plus vt-w-3.5 vt-h-3.5">
      <path d="M5 12h14"></path><path d="M12 5v14"></path>
    </svg>
  </button>
  <p class="vt-text-xs vt-text-foreground-muted vt-mt-2">sm</p>
</div>
<div class="vt-text-center">
  <button class="vt-btn vt-btn-primary vt-btn-icon" aria-label="Add">
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-plus vt-w-4 vt-h-4">
      <path d="M5 12h14"></path><path d="M12 5v14"></path>
    </svg>
  </button>
  <p class="vt-text-xs vt-text-foreground-muted vt-mt-2">md</p>
</div>
<div class="vt-text-center">
  <button class="vt-btn vt-btn-primary vt-btn-icon vt-btn-lg" aria-label="Add">
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-plus vt-w-5 vt-h-5">
      <path d="M5 12h14"></path><path d="M12 5v14"></path>
    </svg>
  </button>
  <p class="vt-text-xs vt-text-foreground-muted vt-mt-2">lg</p>
</div>

Guidelines

Reach for a button for any clickable action, including low-emphasis text actions. Keep one primary button per view — secondary actions use bordered or ghost. Don't use a button for inline navigation inside text; use a link instead.

Do
Use one primary button per view; give secondary actions lower emphasis with bordered or ghost.
Don't
Don't place multiple primary buttons competing for the same attention.

Read our documentation to get started.

Do
For inline navigation inside text, use a link — not a button.

Read our to get started.

Don't
Don't drop a button into a sentence to act as a text link.

API Reference

All CSS classes available for the Button component.

Class Type Description
vt-btn Base Base button styles — flex, rounded, font, transition
vt-btn-primary Variant Blue fill, white text — primary actions
vt-btn-secondary Variant Muted fill — secondary actions
vt-btn-bordered Variant Outline only, no fill
vt-btn-danger Variant Red fill — destructive actions
vt-btn-link Variant Looks like a link — underline on hover
vt-btn-ghost Variant Transparent, subtle hover background
vt-btn-sm Size Small button (32px height, text-xs)
vt-btn-lg Size Large button (44px height, text-base)
vt-btn-icon Modifier Square aspect ratio for icon-only buttons
disabled State HTML attribute — reduced opacity, no pointer events

Accessibility

Keyboard and screen reader support.

Feature Details
Role Use <button> for actions, <a> for navigation
Keyboard Enter and Space activate the button
Focus Visible focus ring via :focus-visible
Disabled Use disabled attribute — removes from tab order automatically
Icon-only Add aria-label to describe the action when there is no visible text