Tutorial

Teknik Warna SVG: Fill, Stroke, dan Gradien

Baca 9 menit

SVG (Scalable Vector Graphics) has its own color system that sits alongside but separate from HTML/CSS. Understanding how SVG handles color unlocks resolution-independent icons, animated illustrations, and gradient effects that scale perfectly to any screen size. This guide covers every major SVG color technique, from basic fill and stroke through complex gradients, with practical examples throughout.

The SVG Fill Attribute

The fill attribute controls the color inside a shape. It is the SVG equivalent of background-color for HTML elements. Every SVG shape — <rect>, <circle>, <path>, <polygon>, <ellipse> — accepts a fill.

Basic Fill Values

Fill accepts all the same color formats as CSS:

<!-- Hex colors -->
<circle cx="50" cy="50" r="40" fill="#3B82F6" />

<!-- Named colors -->
<rect width="100" height="60" fill="tomato" />

<!-- RGB -->
<polygon points="50,10 90,90 10,90" fill="rgb(34, 197, 94)" />

<!-- HSL -->
<ellipse cx="60" cy="40" rx="50" ry="30" fill="hsl(220, 80%, 55%)" />

<!-- Transparent fill -->
<circle cx="50" cy="50" r="40" fill="none" stroke="#EF4444" stroke-width="3" />

A fill="none" removes the fill entirely, leaving only the stroke visible — a common pattern for outline icons.

Fill Opacity

The fill-opacity attribute controls transparency independently from color:

<!-- Semi-transparent overlay -->
<rect width="200" height="120" fill="#1E3A8A" fill-opacity="0.3" />

<!-- Or use rgba() directly -->
<rect width="200" height="120" fill="rgba(30, 58, 138, 0.3)" />

<!-- Or use 8-digit hex -->
<rect width="200" height="120" fill="#1E3A8A4D" />

All three examples above produce the same result. The fill-opacity attribute has slightly better support in older SVG renderers, while rgba() and 8-digit hex require modern browser versions. For anything targeting modern browsers, all three are equivalent.

Fill Rule

When a path crosses itself, the fill-rule attribute determines which areas count as inside:

<!-- evenodd: alternating areas filled and empty (for donut shapes, stars) -->
<path d="M50,10 L61,35 L90,35 L68,57 L79,82 L50,65 L21,82 L32,57 L10,35 L39,35 Z"
      fill="#F59E0B"
      fill-rule="evenodd" />

<!-- nonzero (default): most areas are filled -->
<path d="..." fill="#3B82F6" fill-rule="nonzero" />

The evenodd rule is particularly useful for star shapes and hollow path designs. Without it, a five-pointed star drawn as a single path fills in the center — evenodd makes the center hollow.

SVG Stroke Properties

Stroke draws a line along the path or shape outline. Unlike HTML's border, SVG strokes are centered on the path boundary by default, extending equally inside and outside the shape.

Basic Stroke Attributes

<!-- Stroke color and width -->
<circle cx="60" cy="60" r="40"
        fill="none"
        stroke="#0EA5E9"
        stroke-width="4" />

<!-- Stroke on a filled shape -->
<rect width="120" height="80" rx="8"
      fill="#DBEAFE"
      stroke="#2563EB"
      stroke-width="2" />

Stroke Dash Patterns

The stroke-dasharray and stroke-dashoffset attributes create dashed lines and animated drawing effects:

<!-- Simple dashes: 10px dash, 5px gap -->
<line x1="10" y1="50" x2="290" y2="50"
      stroke="#64748B"
      stroke-width="2"
      stroke-dasharray="10 5" />

<!-- Dots: very short dash, larger gap -->
<line x1="10" y1="50" x2="290" y2="50"
      stroke="#EF4444"
      stroke-width="3"
      stroke-dasharray="1 8"
      stroke-linecap="round" />

<!-- Irregular pattern -->
<path d="M10,50 Q150,10 290,50"
      fill="none"
      stroke="#8B5CF6"
      stroke-width="2"
      stroke-dasharray="15 5 3 5" />

The classic SVG drawing animation uses stroke-dashoffset:

/* CSS animation: path "draws" itself on page load */
.animated-path {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  animation: draw 2s ease-in-out forwards;
}

@keyframes draw {
  to { stroke-dashoffset: 0; }
}

Stroke Line Caps and Joins

stroke-linecap controls how line ends look. stroke-linejoin controls how path corners meet:

<!-- Butt cap (default): ends cut flush -->
<line x1="20" y1="20" x2="180" y2="20"
      stroke="#1A1A2E" stroke-width="12"
      stroke-linecap="butt" />

<!-- Round cap: ends have semicircles -->
<line x1="20" y1="50" x2="180" y2="50"
      stroke="#3B82F6" stroke-width="12"
      stroke-linecap="round" />

<!-- Square cap: ends extend beyond the endpoint -->
<line x1="20" y1="80" x2="180" y2="80"
      stroke="#22C55E" stroke-width="12"
      stroke-linecap="square" />

stroke-linecap="round" is the standard choice for icon strokes — it gives a smooth, friendly appearance that works well at all sizes.

Stroke Opacity

Like fill-opacity, stroke-opacity controls stroke transparency:

<circle cx="60" cy="60" r="40"
        fill="none"
        stroke="#EF4444"
        stroke-width="6"
        stroke-opacity="0.5" />

Linear Gradients in SVG

SVG defines gradients in <defs> blocks and references them by ID. This separation of definition and use allows a single gradient definition to be applied to multiple shapes.

Defining a Linear Gradient

<svg viewBox="0 0 300 200" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <linearGradient id="blueGradient" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%"   stop-color="#3B82F6" />
      <stop offset="100%" stop-color="#1E3A8A" />
    </linearGradient>
  </defs>

  <rect width="300" height="200" fill="url(#blueGradient)" />
</svg>

The x1/y1/x2/y2 attributes define the gradient direction as a vector within the shape's bounding box:

Direction x1 y1 x2 y2
Left to right 0% 0% 100% 0%
Right to left 100% 0% 0% 0%
Top to bottom 0% 0% 0% 100%
Diagonal TL→BR 0% 0% 100% 100%
Diagonal BL→TR 0% 100% 100% 0%

Multiple Color Stops

<defs>
  <linearGradient id="sunsetGradient" x1="0%" y1="0%" x2="100%" y2="0%">
    <stop offset="0%"   stop-color="#FF6B6B" />
    <stop offset="50%"  stop-color="#FFC300" />
    <stop offset="100%" stop-color="#FF3C00" />
  </linearGradient>
</defs>

This produces a sunset gradient from #FF6B6B through #FFC300 to #FF3C00.

Gradient Units

By default (gradientUnits="objectBoundingBox"), the gradient coordinates are percentages of the shape's bounding box. With gradientUnits="userSpaceOnUse", coordinates are in the SVG canvas's pixel space:

<defs>
  <!-- Absolute coordinates in SVG pixels -->
  <linearGradient id="absGradient"
                  x1="0" y1="0" x2="300" y2="0"
                  gradientUnits="userSpaceOnUse">
    <stop offset="0%"   stop-color="#667EEA" />
    <stop offset="100%" stop-color="#764BA2" />
  </linearGradient>
</defs>

userSpaceOnUse is useful when multiple shapes share a single large gradient that spans the full SVG canvas.

Animating Gradient Stops

SVG supports native SMIL animation within gradient definitions:

<linearGradient id="animGradient" x1="0%" y1="0%" x2="100%" y2="0%">
  <stop offset="0%" stop-color="#3B82F6">
    <animate attributeName="stop-color"
             values="#3B82F6; #8B5CF6; #EC4899; #3B82F6"
             dur="4s"
             repeatCount="indefinite" />
  </stop>
  <stop offset="100%" stop-color="#1E3A8A">
    <animate attributeName="stop-color"
             values="#1E3A8A; #5B21B6; #9D174D; #1E3A8A"
             dur="4s"
             repeatCount="indefinite" />
  </stop>
</linearGradient>

This animates the gradient colors through a blue → purple → pink → blue cycle. CSS animations cannot directly animate gradient stop colors (only CSS custom properties via @property can), so SVG SMIL animation is the most direct approach for this effect.

Radial Gradients in SVG

Radial gradients in SVG radiate outward from a center point (the focal point) to an outer circle. They support two independent centers: the gradient center (cx/cy) and the focal point (fx/fy).

Basic Radial Gradient

<defs>
  <radialGradient id="glowGradient" cx="50%" cy="50%" r="50%">
    <stop offset="0%"   stop-color="#FFF176" />
    <stop offset="100%" stop-color="#F57F17" />
  </radialGradient>
</defs>

<circle cx="150" cy="100" r="80" fill="url(#glowGradient)" />

This creates a sun-like glow: bright yellow #FFF176 at the center, deepening to amber #F57F17 at the edge.

Off-Center Focal Point

Setting fx/fy separately from cx/cy creates a perspective effect — like a sphere lit from one side:

<defs>
  <radialGradient id="sphereGradient"
                  cx="50%" cy="50%" r="50%"
                  fx="35%" fy="35%">
    <stop offset="0%"   stop-color="#A8E6CF" stop-opacity="1" />
    <stop offset="60%"  stop-color="#2D6A4F" stop-opacity="1" />
    <stop offset="100%" stop-color="#1B4332" stop-opacity="1" />
  </radialGradient>
</defs>

<circle cx="150" cy="150" r="120" fill="url(#sphereGradient)" />

The highlight cluster at 35%, 35% (upper-left) gives the circle a three-dimensional sphere appearance.

Transparent Stop for Glow Effects

Using transparent stops creates glow overlays:

<defs>
  <radialGradient id="glowOverlay" cx="50%" cy="50%" r="50%">
    <stop offset="0%"   stop-color="#60A5FA" stop-opacity="0.8" />
    <stop offset="100%" stop-color="#60A5FA" stop-opacity="0" />
  </radialGradient>
</defs>

<!-- Dark background -->
<rect width="300" height="200" fill="#0F172A" />
<!-- Glow overlay -->
<rect width="300" height="200" fill="url(#glowOverlay)" />

Use the Gradient Generator to experiment with color combinations before committing to SVG gradient code. Set your start and end colors visually and copy the hex values for your stop-color attributes.

The currentColor Keyword

currentColor is one of the most powerful SVG color techniques. It makes an SVG element inherit its color from the CSS color property of its parent HTML element, allowing CSS to control SVG colors without touching the SVG markup.

How currentColor Works

<!-- HTML: CSS color property cascades into SVG -->
<button class="icon-button" style="color: #3B82F6;">
  <svg viewBox="0 0 24 24" fill="currentColor">
    <path d="M12 2L2 7l10 5 10-5-10-5z M2 17l10 5 10-5 M2 12l10 5 10-5" />
  </svg>
  Export
</button>
.icon-button {
  color: #3B82F6;      /* Icon fills with blue */
}

.icon-button:hover {
  color: #1D4ED8;      /* Icon fills with dark blue on hover */
}

.icon-button:disabled {
  color: #9CA3AF;      /* Icon fills with gray when disabled */
}

No additional SVG-specific rules needed — one color declaration drives all states.

currentColor in Strokes

The keyword works equally well for strokes:

<svg viewBox="0 0 24 24"
     fill="none"
     stroke="currentColor"
     stroke-width="2"
     stroke-linecap="round">
  <circle cx="12" cy="12" r="10" />
  <polyline points="12 6 12 12 16 14" />
</svg>

This clock icon inherits its stroke color from the parent CSS color value — a single CSS property changes both the icon and any adjacent text color.

Mixed currentColor and Fixed Colors

You can combine currentColor with fixed colors in a single SVG for multi-color icons:

<svg viewBox="0 0 24 24">
  <!-- Body: inherits from currentColor -->
  <path fill="currentColor"
        d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z" />
  <!-- Badge: fixed accent color -->
  <circle cx="18" cy="6" r="4" fill="#EF4444" />
</svg>

This pattern is common for notification badges: the main icon color follows the parent's text color, but the badge stays red regardless of context.

CSS Styling of SVGs

When SVG is inline in HTML (not in an <img> tag), standard CSS can style it directly. This unlocks CSS custom properties, pseudo-classes, transitions, and animations — far more flexible than SVG attributes alone.

CSS Overrides SVG Presentation Attributes

CSS has higher specificity than SVG presentation attributes (the fill="" and stroke="" attributes directly in SVG markup). This means you can override any attribute with CSS:

/* Override any inline fill attribute */
.icon-danger path {
  fill: #EF4444;
}

/* Override stroke for a specific variant */
.icon-outline circle,
.icon-outline path {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
}

CSS Custom Properties in SVG

Custom properties cascade into inline SVG elements, enabling dynamic theming:

<svg viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="40"
          fill="var(--chart-primary, #3B82F6)"
          stroke="var(--chart-border, #1E3A8A)"
          stroke-width="2" />
</svg>
:root {
  --chart-primary: #3B82F6;
  --chart-border:  #1E3A8A;
}

[data-theme="dark"] {
  --chart-primary: #60A5FA;
  --chart-border:  #93C5FD;
}

The SVG element automatically picks up dark mode colors when the theme changes — without any JavaScript.

CSS Transitions on SVG

CSS transitions work on SVG color properties:

.icon path {
  fill: #6B7280;
  transition: fill 200ms ease;
}

.icon:hover path {
  fill: #3B82F6;
}

This produces a smooth color transition when hovering over the icon — impossible with SVG attributes alone.

Clipping and Masking for Color Effects

For advanced effects, CSS clip-path and SVG masks can reveal gradients through complex shapes:

<!-- Gradient text using SVG -->
<svg viewBox="0 0 400 100">
  <defs>
    <linearGradient id="textGrad" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%"   stop-color="#667EEA" />
      <stop offset="100%" stop-color="#764BA2" />
    </linearGradient>
  </defs>
  <text x="10" y="80" font-size="72" font-weight="bold"
        fill="url(#textGrad)">ColorFYI</text>
</svg>

The Gradient Generator can help you design the gradient color pairs. Use the Color Converter to translate any HSL or RGB color you have in mind into the hex values needed for SVG stop-color attributes.

Color Format Compatibility

SVG color attributes accept the same formats as CSS, but there are some compatibility notes worth knowing:

Format SVG Attribute Support CSS Property Support
Named colors Full Full
#RRGGBB hex Full Full
#RGB shorthand Full Full
#RRGGBBAA 8-digit Modern browsers Modern browsers
rgb() Full Full
rgba() Full Full
hsl() Full Full
oklch() Modern browsers Modern browsers
currentColor Full N/A
url(#id) for gradients Full Partial

For maximum compatibility in SVG fills, stick to 6-digit hex codes. For transparency, use fill-opacity rather than 8-digit hex or rgba() if you need to support older SVG renderers (like SVGs used in PDF export pipelines).

Key Takeaways

  • SVG uses fill and stroke attributes to color shapes and paths respectively. Both accept all standard CSS color formats including hex, RGB, HSL, and named colors.
  • fill-opacity and stroke-opacity control transparency independently from color, with slightly better compatibility in older SVG environments than 8-digit hex or rgba().
  • SVG gradients are defined in <defs> blocks with a unique id, then applied using fill="url(#id)". Linear gradients use vector coordinates for direction; radial gradients support independent focal point (fx/fy) for perspective effects.
  • The currentColor keyword is the most important SVG color technique for icon systems — it inherits the CSS color property, allowing a single CSS rule to control icon color across all states (hover, disabled, active).
  • Inline SVG can be styled with standard CSS including custom properties, pseudo-class selectors, and transitions — making dynamic theming and interactive animations straightforward.
  • Use the Gradient Generator to design gradient color pairs visually and the Color Converter to translate colors between formats needed for SVG attributes.

Warna Terkait

Merek Terkait

Alat Terkait