Tailwind CSS Icons: Complete Guide for 2025
How to style SVG icons with Tailwind CSS — sizing, color, stroke width, dark mode, and animated icons — with copy-paste examples using krz-icons.
Tailwind CSS and SVG icon components are a natural fit. Icons inherit currentColor by default, so they pick up Tailwind text utilities automatically. Here is a complete reference for every pattern you will use in a real Tailwind project.
Install
npm install krz-icons
No Tailwind plugin is needed. Icons are React components that accept the same className prop as any other element.
Sizing icons
Icons default to 24 px. Pass the size prop for a simple square, or use Tailwind's sizing utilities for more control.
// Prop — simplest for fixed sizes
<Home size={20} />
// Tailwind class — useful when size comes from a parent grid
<Home className="size-5" /> // 20px
<Home className="size-6" /> // 24px
<Home className="size-8" /> // 32px
size-* overrides both width and height via the CSS width/height utilities, which overrides the SVG's inline width/height attributes.
Coloring icons
Icons inherit currentColor by default, which means any Tailwind text color class on the icon or a parent element applies.
// Direct class
<Search className="text-zinc-500" />
// Inherited from parent
<button className="text-blue-600 hover:text-blue-800">
<Search size={16} /> Search
</button>
// Dark mode
<Bell className="text-zinc-600 dark:text-zinc-300" />
Stroke width
The default stroke width is 1 px. For heavier strokes, pass the strokeWidth prop.
<Home strokeWidth={1.5} /> // medium
<Home strokeWidth={2} /> // bold
For strokes that stay the same thickness at every size (like Material icons), pass absoluteStrokeWidth:
<Home size={32} strokeWidth={1} absoluteStrokeWidth />
Icon buttons
The most common pattern: a button containing an icon, with consistent padding and a focus ring.
function IconButton({ icon: Icon, label, onClick }) {
return (
<button
onClick={onClick}
aria-label={label}
className="
flex items-center justify-center
size-9 rounded-lg
text-zinc-600 hover:text-zinc-900 hover:bg-zinc-100
focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-zinc-400
dark:text-zinc-400 dark:hover:text-zinc-100 dark:hover:bg-zinc-800
"
>
<Icon size={18} />
</button>
);
}
Icons with labels
<button className="flex items-center gap-2 px-4 py-2 text-sm rounded-lg bg-zinc-900 text-white">
<Download size={16} />
Download
</button>
Badge / chip
<span className="flex items-center gap-1.5 px-2.5 py-1 rounded-full border border-zinc-200 text-xs">
<CheckCircle size={12} className="text-emerald-500" />
Verified
</span>
Animated icons
Tailwind's animation utilities work directly on icon components.
// Spinning loader
<Loader size={20} className="animate-spin text-zinc-400" />
// Pulsing status dot (use a simple circle, not a spinner)
<span className="flex items-center gap-2">
<span className="relative flex size-2">
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75" />
<span className="relative inline-flex rounded-full size-2 bg-emerald-500" />
</span>
Online
</span>
Active / selected state
Use conditional classes or data attributes to toggle icon color on selection.
function NavItem({ href, icon: Icon, label, active }) {
return (
<a
href={href}
aria-current={active ? "page" : undefined}
className={[
"flex items-center gap-3 px-3 py-2 rounded-md text-sm",
active
? "bg-zinc-100 font-medium text-zinc-900 dark:bg-zinc-800 dark:text-white"
: "text-zinc-500 hover:text-zinc-900 dark:hover:text-white",
].join(" ")}
>
<Icon size={16} className={active ? "text-emerald-500" : ""} />
{label}
</a>
);
}
Duotone icons
krz-icons duotone variants have a filled shape at 20 % opacity plus a stroke. They respond to text color the same way.
import { HomeDuotone } from "krz-icons";
<HomeDuotone size={24} className="text-emerald-500" />
Summary
Because SVG icons use currentColor, Tailwind's entire text color palette is available without any extra configuration. Use size or size-* classes for sizing, and pass strokeWidth when the design calls for heavier strokes.