SVG Fill and Stroke
Purpose and Scope
This page is a focused reference for Tailwind CSS utilities that style SVG paint and stroke geometry. In SVG, fill controls the interior paint of shapes, stroke controls the outline paint, and stroke-width controls how thick that outline is. Tailwind exposes these SVG concerns as utility classes so icons and inline illustrations can participate in the same utility-first workflow as HTML elements. The official SVG documentation groups these APIs into fill, stroke, and stroke-width, with color-driven classes for paint and numeric or arbitrary-value classes for line width.
The most common reader problem is choosing the right class family for an icon component. Use fill-* when the SVG path or shape should be painted as a solid interior, use stroke-* when the icon is drawn with outlines, and combine stroke-* with stroke-<number> when the outline needs an explicit width. These utilities are especially useful for component libraries because fill-current and stroke-current allow SVG elements to inherit the surrounding text color through currentColor, keeping icons synchronized with button, link, alert, and navigation states.
Tailwind’s public documentation supplies the concrete utility names and declarations for this page. The targeted repository source for this page does not enumerate the SVG utilities directly, but it does show an important implementation contract: utility-like class strings are represented as candidates that can be parsed, inspected, transformed, and printed again by a DesignSystem. That same candidate model is what makes classes such as md:stroke-2, hover:fill-red-500, and arbitrary forms like stroke-[1.5] fit into the wider compiler and migration ecosystem. Sources: packages/@tailwindcss-upgrade/src/codemods/template/migrate-max-width-screen.ts
Relevant Source Files
packages/@tailwindcss-upgrade/src/codemods/template/migrate-max-width-screen.ts— Shows how Tailwind tooling accepts a raw class candidate, parses it throughdesignSystem.parseCandidate, checks structured candidate fields such askind,root, andvalue, and emits a normalized class withdesignSystem.printCandidate. This supports the page’s explanation of SVG utilities as candidates, even though the file’s specific codemod targetsmax-w-screen-*migration.
Utility Families
The fill utilities set the SVG fill property. The official reference includes keyword-like utilities such as fill-none, fill-inherit, fill-current, and fill-transparent, followed by palette-backed classes like fill-black, fill-white, and color scale entries such as fill-red-500. In practice, use fill-none for outline-only icons or paths that should not be painted inside, fill-current when an icon should inherit text color, and palette classes when the SVG itself should carry a fixed semantic color independent of surrounding text.
The stroke utilities mirror the paint-oriented behavior of fill, but they write the SVG stroke property instead. The official reference lists stroke-none, stroke-inherit, stroke-current, stroke-transparent, stroke-black, stroke-white, and color scale classes such as stroke-red-500. For line-based icon sets, stroke-current is often the default because it lets the icon color track text-* utilities on a parent or the SVG element itself. For decorative illustrations, palette-backed stroke-* classes let individual paths use theme colors directly.
The stroke-width utilities control the SVG stroke-width property rather than a color. The official quick reference defines stroke-<number> as stroke-width: <number>;, stroke-(length:<custom-property>) as a CSS-variable shorthand, and stroke-[<value>] as the arbitrary-value form. The basic documented examples are stroke-1 and stroke-2, which are useful for icon sets such as Heroicons. When the desired width is not an integer token, use stroke-[1.5]; when the width should come from a variable, use stroke-(length:--my-stroke-width).
Quick Reference
| Utility family | Example class | CSS effect | Typical use |
|---|---|---|---|
| Fill keyword | fill-none | fill: none; | Prevent an SVG path from having an interior paint. |
| Fill inherited color | fill-current | fill: currentColor; | Make a solid icon follow surrounding text color. |
| Fill theme color | fill-red-500 | fill: var(--color-red-500); | Apply a palette color to an SVG shape. |
| Stroke keyword | stroke-none | stroke: none; | Remove the outline paint from an SVG shape. |
| Stroke inherited color | stroke-current | stroke: currentColor; | Make outline icons follow surrounding text color. |
| Stroke theme color | stroke-red-500 | stroke: var(--color-red-500); | Apply a palette color to icon outlines. |
| Stroke width | stroke-2 | stroke-width: 2; | Give an outline icon a standard line width. |
| Arbitrary stroke width | stroke-[1.5] | stroke-width: 1.5; | Use a nonstandard numeric width. |
| Variable stroke width | stroke-(length:--my-stroke-width) | stroke-width: var(--my-stroke-width); | Bind outline width to a custom property. |
These classes can be composed with the same variants used elsewhere in Tailwind. The stroke-width documentation explicitly demonstrates responsive composition with stroke-1 md:stroke-2, meaning the element uses a smaller stroke by default and switches at the medium breakpoint and above. The same composition model is useful for stateful SVG styling: a link icon might start as stroke-current and then combine with a color utility under a state variant, while a filled badge icon might use fill-current so the parent component controls color through normal text utilities.
Candidate Model and Migration Behavior
The repository source supplied for this page is a codemod named migrateMaxWidthScreen. It receives a DesignSystem, an optional compatibility Config, and a rawCandidate string, then loops over designSystem.parseCandidate(rawCandidate). The function checks whether a parsed candidate is functional, whether its root is max-w, and whether its value begins with screen-; if so, it returns a printed replacement candidate whose value is rewritten to a theme lookup. Otherwise, it returns the original raw candidate. Sources: packages/@tailwindcss-upgrade/src/codemods/template/migrate-max-width-screen.ts
That file is not an SVG-specific implementation, so it should not be read as the source of fill-* or stroke-* declarations. Its value for SVG documentation is architectural: Tailwind tooling treats class strings as structured candidates rather than opaque text whenever migration logic needs to understand a utility. A class like stroke-[1.5] has a recognizable root and value shape; a class like md:stroke-2 adds a variant prefix around the underlying utility; and a class like fill-red-500 uses a color value that resolves through the design system. The codemod demonstrates this parse, inspect, and print pattern in a concrete repository file. Sources: packages/@tailwindcss-upgrade/src/codemods/template/migrate-max-width-screen.ts
For authors, this means SVG utilities should be written in canonical Tailwind syntax instead of hidden inside string concatenation that tooling cannot analyze reliably. If a component accepts an icon color prop, prefer mapping that prop to complete class names such as fill-current, stroke-current, fill-red-500, or stroke-sky-600 rather than assembling fragments that obscure the candidate root. This advice follows from the candidate-based migration model: transformations can only reason about what the design system can parse as a candidate. Sources: packages/@tailwindcss-upgrade/src/codemods/template/migrate-max-width-screen.ts
Usage Patterns
For a solid icon, use a fill utility and avoid setting a stroke unless the SVG artwork needs both. A common pattern is a small inline icon that inherits text color from a link or button. The SVG can use class="size-5 fill-current", while the parent applies color and state classes. This keeps the icon implementation neutral: it does not need to know whether it is rendered in a primary button, destructive action, disabled label, or dark-mode navigation item.
For outline icons, pair stroke-current with an explicit stroke width. A typical SVG might use class="size-5 fill-none stroke-current stroke-2", leaving individual path elements to define their geometry. If the icon set expects thinner lines at small sizes and thicker lines at larger sizes, use responsive variants such as stroke-1 md:stroke-2. Because stroke-width is independent from stroke color, you can adjust visual weight without changing semantic color or component state handling.
For illustrations that mix filled shapes and outlines, apply utilities at the element level that matches the SVG structure. A parent <svg> can set defaults like stroke-current, while individual child paths can override with fill-red-500 or stroke-transparent. This mirrors CSS inheritance behavior: not every SVG property behaves identically on every element, but Tailwind utilities still compile to straightforward CSS declarations. Keep the structure readable, and favor explicit classes on important paths when the image must remain understandable during maintenance.
<button class="text-slate-700 hover:text-sky-600">
<svg viewBox="0 0 20 20" class="size-5 fill-none stroke-current stroke-2">
<path d="M4 10h12" />
<path d="M10 4v12" />
</svg>
Add item
</button>Implementation Notes for Component Authors
When using fill-current or stroke-current, remember that the SVG paint is driven by the computed color property. That makes these utilities pair naturally with text-* color utilities, including variant-prefixed classes on the parent. In a design system, this is usually preferable to hard-coding every icon color, because the icon inherits disabled, hover, active, selected, and dark-mode colors from the surrounding component. Use direct palette classes only when the icon itself carries meaning that should not follow surrounding text.
When using arbitrary stroke widths, choose values that match the coordinate system and rendering style of the icon set. stroke-[1.5] is valid when the artwork was designed for a fractional line width, but mixing many arbitrary widths across an application can make iconography feel inconsistent. If the same custom width appears repeatedly, the CSS-variable shorthand stroke-(length:--my-stroke-width) can centralize that decision and make the component easier to theme. The official documentation explains that this shorthand expands to the corresponding var() usage automatically.
Next Steps
If you are styling icons for a component library, start with fill-current for solid icons and fill-none stroke-current stroke-2 for outline icons, then layer responsive or state variants only where the design requires them. If you are migrating older class strings or writing codemods, read the candidate model carefully: the supplied upgrade source shows that Tailwind transformations operate on parsed candidates and print them back into canonical class syntax. From here, continue to the Colors page for palette behavior, Hover, Focus, and Other States for variant composition, and Theme for CSS variable customization.