Theme
On this page (10)
Component Skill — components/icon/component-skill.md

Native basis

<i> element with data-lucide attribute. Icons are provided by the Lucide icon library via CDN. Lucide replaces each <i data-lucide="name"> with an inline SVG on page load.

Web Platform APIs

<svg>aria-hiddencurrentColorprefers-reduced-motionforced-colorsprefers-contrast

Data attributes

• data-lucide - icon name (required)

• data-size - xs | sm | md | lg | xl

• data-animate - spin

Notes

• Icons inherit currentColor for stroke - they automatically match the parent's text color

• Browse all available icons at lucide.dev/icons

• Lucide provides ~1,500 icons covering every common web app need

• The CDN script replaces <i data-lucide="name"> elements with inline SVGs on page load

• Use stroke-width attribute to adjust line thickness (default: 2)

• Prefer visually-hidden text (.sr-only) over aria-label for accessible standalone icons

• Animations (e.g., data-animate="spin") are suppressed when the user has prefers-reduced-motion enabled

• prefers-contrast: more increases stroke width to 2.5 for better visibility

§Basic usage

Use data-lucide with any icon name from lucide.dev/icons.

§Sizes

Use data-size to control icon size.

§With buttons

Icons inside buttons inherit the button's color.

§Color

Icons inherit currentColor. Change color with text color utilities.

§Stroke width

Adjust line thickness with the stroke-width attribute. Default is 2.

§Accessible icon

For standalone icons that convey meaning, use visually-hidden text or aria-label.

§Animated (spinner)

Add data-animate='spin' for loading indicators. Animation is suppressed when the user has prefers-reduced-motion enabled.

§Filled icons

Use the fill and stroke-width attributes for filled icon variants. Works well with simple shapes.

§Browse all icons

Lucide provides ~1,500 icons. Browse and search the full set at:

lucide.dev/icons

§CSS view file

/* -- Icon component ---------------------------------------- */
/* Styling for Lucide CDN icons (<i data-lucide="name">).     */
/* Lucide replaces <i> with <svg>, these styles target that.  */
@layer components {
  [data-lucide] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    vertical-align: middle;
    width: 1rem;
    height: 1rem;
    pointer-events: none;
    /* -- Sizes via data-size --------------------------------- */
    &[data-size="xs"] { width: 0.75rem; height: 0.75rem; }
    &[data-size="sm"] { width: 0.875rem; height: 0.875rem; }
    &[data-size="md"] { width: 1.25rem; height: 1.25rem; }
    &[data-size="lg"] { width: 1.5rem; height: 1.5rem; }
    &[data-size="xl"] { width: 2rem; height: 2rem; }
    /* -- Spin animation ------------------------------------- */
    &[data-animate="spin"] {
      animation: icon-spin 1s linear infinite;
    }
  }
  @keyframes icon-spin {
    to { transform: rotate(360deg); }
  }
  /* ---- Accessibility ---------------------------------------- */
  @media (prefers-reduced-motion: reduce) {
    [data-lucide] {
      animation: none !important;
      transition: none !important;
    }
  }
  @media (prefers-contrast: more) {
    [data-lucide] {
      stroke-width: 2.5;
    }
  }
  @media (forced-colors: active) {
    [data-lucide] {
      color: CanvasText;
    }
  }
}

Comments, ideas or improvements? Edit this page's source on GitHub