Linear Gradients in SVG

Veröffentlicht am Samstag, 28. Februar 2009, von infinity auf Alphane Moon

In SVG kann man Objekte auf verschiedenen Wegen füllen: mit einer gleichmäßigen Farbfüllung, mit einem linearen Farbverlauf von einer Farbe zur nächsten entlang einer Linie (ein linearer Gradient), oder mit einem Farbverlauf entlang von Kreisen (radialer Gradient). Diese drei Möglichkeiten kann man im Bild unten sehen, wo ich drei Kreisflächen gefüllt habe. Und dann gibt es natürlich noch Füllmuster (Patterns), aber das ist eine andere Geschichte.

SVG offers three different ways to fill an object: You can fill an object with a solid color. Or you can apply a gradient to fill the object. The gradient can be linear, a smooth transition from one color to another along a straight line, or radial, where the transition occurs along circular paths. You can see the three alternatives in the first picture below, where I have used them to fill three circles. Another way to fill an object is the application of patterns, but that is a different story.

A linear gradient is created with the <linearGradient> element, which we are going to explore in this little tutorial. I have created a very basic example file that you can use as a starting point for your experiments: SVG Example File for Linear Gradients.
You can download the file and modify it in a text editor. Save the file as UTF-8 after editing.

Lineare Farbverläufe für Füllungen erzeugt man mit dem Element <linearGradient>, das ich in diesem kleinen Tutorial ein wenig vorstellen möchte. Zum Ausprobieren habe ich eine einfache Beispiel-Datei geschreiben: SVG-Beispiel für lineare Farbverläufe.
Du kannst die Datei herunterladen und mit einem Text-Editor bearbeiten. Die Datei sollte nach dem Editieren immer in UTF-8 kodiert gespeichert werden.

Exploring the <linearGradient> Element

A linear gradient is created by the <linearGradient> element. This element lives in the <defs> section of the SVG document, where we can define all kinds of useful things that are referenced later in the document. The <linearGradient> element contains at least two <stop> elements to define the color values for the transition. We will take a closer look at the <stop> element in a moment. First let’s see how a gradient can be applied to an object.

Einen linearen Verlauf erzeugt man mit dem Element <linearGradient>, das im <defs>-Bereich des SVG-Dokuments zu Hause ist. In diesem Bereich kann man nützliche Sachen definieren, die an späterer Stelle referenziert werden. Das <linearGradient>-Element enthält mindestens zwei <stop>-Elemente. Diese legen die Farben für den Verlauf fest, das schauen wir uns gleich noch genauer an. Zuerst werfen wir noch ein Blick darauf, wie man einen Gradienten auf ein Objekt anwenden kann.

<defs>
  <linearGradient id="grady">
    <stop offset="0" style="stop-color:#009900"/>
    <stop offset="1" style="stop-color:#FFFFFF"/>
  </linearGradient>
  <style type="text/css">
    <![CDATA[
      .grad {fill:url(#grady)}
    ]]>
  </style>
</defs>

<rect class="grad" x="50" y="50" width="300" height="300"/>

To use the gradient the <linearGradient> element is given an id. In the sample code above the <defs> section contains a <style> element, where a CSS class is created. The gradient is then applied to the fill property by using url(#gradientID). Now every object of this class will be filled with the color gradient. CSS is really nice :)

Um einen Gradienten anzuwenden geben wir dem <linearGradient>-Element eine id. Im Beispielcode enthält der <defs>-Bereich ein <style>-Element, wo eine neue CSS-Klasse ins Leben gerufen wird. Der Eigenschaft fill übergeben wir den Gradienten über seine id mit url(#gradientID). Jetzt wird jedes Objekt dieser Klasse mit dem Gradienten gefüllt.

A linear Gradient can be used to fill the inside of an object. But you can also use it to fill it’s outline. You can see both in the picture, where I have applied the same gradient first to the inside of a circle and then to the outline. Some more source code to play with is listed below.

Lineare Gradienten kann man dazu verwenden einem Objekt ein abwechslungsreiches und farbenfrohes Innenleben zu verpassen. Man kann den Gradienten aber auch auf die Umrißlinie anwenden und diese mit einem Farbverlauf einfärben. Im Bild sind die beiden Möglichkeiten zu sehen. Etwas Quelltext zum Ausprobieren:

<defs>
 <linearGradient id="grady">
  <stop offset="0" style="stop-color:#009900"/>
  <stop offset="1" style="stop-color:#FFFFFF"/>
 </linearGradient>
 <style type="text/css">
  <![CDATA[
    .gra {fill:url(#grady)}
    .gra2 {fill:none;
       stroke:url(#grady);
       stroke-width:10px;}
  ]]>
 </style>
</defs>

<circle cx="75" cy="100" r="60" class="gra" />
<circle cx="230" cy="55" r="100" class="gra2" />

The fill property is not the only property, which can be used with a gradient. In the example above I have applied the gradient to the stroke property of a circle to style it’s outline.

Die fill-Eigenschaft ist nicht die einzige, auf die man einen Gradienten anwenden kann. Im Beispiel oben habe ich die Eigenschaft stroke benutzt, um die Umrißlinie eines Kreises mit einem Verlauf auszufüllen.

Spectrum Travelling with the <stop> Element

You can define additional colors for the transition by using more than just the two <stop> elements. The <stop> element has two required attributes: offset and stop-color.

The value of the offset attribute is expressed as a decimal number from 0 to 1.0 or as a percentage from 0% to 100%. The offset value gives the point at which the color should be equal to the color value set in the stop-color. In the next example I have used some more <stop> elements to create a transition similar to the electromagnetic spectrum:

Zusätzliche Farben für den Verlauf kann man einführen, indem man weitere <stop>-Elemente verwendet. Das <stop>-Element benötigt zwei Attribute: offset und stop-color.

Der Wert des offset-Attributs kann eine Dezimalzahl zwischen 0 und 1.0 sein oder ein prozentualer Wert von 0% bis 100%. Der offset-Wert sagt dann den Punkt im Verlauf an, an dem die Farbe erreicht sein soll, die mit stop-color festgesetzt wurde. Im Beispiel habe ich weitere <stop>-Elemente benutzt, um ein elektromagnetisches Spektrum zu zeichnen.

<defs>
 <linearGradient id="spectrum">
  <stop offset="0" style="stop-color:#000000"/>
  <stop offset="0.1" style="stop-color:#FD0404"/>
  <stop offset="0.2" style="stop-color:#FC6804"/>
  <stop offset="0.3" style="stop-color:#F6F302"/>
  <stop offset="0.4" style="stop-color:#23EA00"/>
  <stop offset="0.5" style="stop-color:#00EA16"/>
  <stop offset="0.6" style="stop-color:#01DDDE"/>
  <stop offset="0.7" style="stop-color:#0092D8"/>
  <stop offset="0.8" style="stop-color:#0300D0"/>
  <stop offset="0.9" style="stop-color:#8607AD"/>
  <stop offset="1" style="stop-color:#000000"/>
 </linearGradient>
</defs>

Changing the Direction of the Color Transition

The standard direction of a gradient is from the left to the right side of an object along a horizontal line, just like in the spectrum example. The direction can be changed by specifying the starting and ending points of the transition: Use the attributes x1 and y1 to define the start coordinates and x2 and y2 to define the destination coordinates of the gradient.

Like the offset attribute the values of the coordinates x1, y1, x2 and y2 can be given by a decimal number from 0 to 1.0 or by a percentage from 0% to 100%. The next picture shows a gradient from green to blue with different directions of the transition: from right to left, from top to bottom and diagonally from the top right corner to the lower left.

Solange man keine speziellen Angaben macht, verläuft ein Gradient immer entlang einer horizontalen Linie von links nach rechts, wie im Spektrum-Beispiel. Die Verlaufsrichtung kann man ändern, indem man mit den Attributen x1 und y1 einen Anfangspunkt und mit den Attributen x2 und y2 einen Endpunkt für den Verlauf festlegt. Als Werte können wie bei offset Dezimalzahlen von 0 bis 1.0 oder Prozentwerte von 0% bis 100% benutzt werden.

Das Beispiel zeigt einen Gradienten von grün nach blau mit verschiedenen Richtungen: von rechts nach links, von oben nach unten und diagonal von rechts oben nach links unten.

<defs>
 <linearGradient id="simpleGrad">
  <stop offset="0" style="stop-color:#00BB00"/>
  <stop offset="1" style="stop-color:#5500BB"/>
 </linearGradient>
 
 <linearGradient id="righttoleft"
    x1="100%" y1="0%" x2="0%" y2="0%"
    xlink:href="#simpleGrad" />

 <linearGradient id="top-down"
    x1="0%" y1="0%" x2="0%" y2="100%"
    xlink:href="#simpleGrad" />

 <linearGradient id="topleft-downright"
    x1="0%" y1="0%" x2="100%" y2="100%"
    xlink:href="#simpleGrad" />
	
 <style type="text/css">
   <![CDATA[
   .right-to-left {fill:url(#righttoleft)}
   .top-bottom {fill:url(#top-down)}
   .topleft-bottomright {fill:url(#topleft-downright)}
   ]]>
  </style>
  
</defs>

<!-- Let’s fill some rectangles -->

<rect class="right-to-left" x="0" y="25"
   width="150" height="150"/>
<rect class="top-bottom" x="200" y="25"
   width="150" height="150"/>
<rect class="topleft-bottomright" x="400" y="25"
   width="150" height="150"/>

The spreadMethod Attribute

Und was passiert, wenn der Gradient nicht das gesamte Innere des Objekts ausfüllt? Der Farbverlauf muß sich nicht von einer Ecke zu anderen erstrecken, sondern kann zum Beispiel von (20%,25%) nach (45%,80%) gehen. In diesem Fall kann man das Attribut spreadMethod des <linearGradient>-Elements benutzen, um festzulegen, was mit dem Objekt außerhalb des Bereichs passiert, der vom Gradienten abgegrast wird.

Das spreadMethod-Attribut kann man auf einen von drei erlaubten Werten setzen:

Im nächsten Bild kann man alle drei Werte in Aktion sehen, von links nach rechts wurden pad, repeat und dann reflect benutzt, um die Rechtecke zu füllen. Quelltext ist weiter unten.

What will happen if a gradient does not completely fill the inside of an object? The color transition does not have to proceed from one corner of the object to the other, but can for example range from (20%,25%) to (45%,80%) only. In this case you can set the spreadMethod attribute of the <linearGradient> element to specify what should happen to the region that is not reached by the gradient.

The spreadMethod attribute can be set to one of the three possible values:

The picture above shows an application of all three possible values pad, repeat and finally reflect to fill some rectangles. A simplified source code for a gradient with reflect:

<defs>

<linearGradient id="gradx" x1="20%" y1="20%" x2="50%" y2="50%">
  <stop offset="0" style="stop-color:stop-color:#000000"/>
  <stop offset="1" style="stop-color:#FFFFFF"/>
</linearGradient>

<linearGradient id="reflect" spreadMethod="reflect"
	xlink:href="#gradx" />

<style type="text/css">
  <![CDATA[
   .reflectgrad {
     fill:url(#reflect);
     fill-rule:nonzero;
     stroke-width:1; stroke:#333}
  ]]>
</style>

</defs>

<rect class="reflectgrad" x="0" y="0" width="400" height="400"/>

The <defs> section contains three things: First, a partial gradient is defined, which would not completely fill the object (a rectangle). Second, the partial gradient is referenced via our friend xlink:href to set a value of the spreadMethod attribute and to define another gradient. The third ingredient is the CSS in the style element, which is later used to style the rectangle with a reflected gradient. Try it out with the example file :)

Im Quelltext oben enthält der <defs>-Bereich drei Dinge: zuerst wird ein partieller Gradient definiert, der das Objekt (ein Rechteck) nicht vollständig ausfüllen würde. In einem zweiten Schritt wird dieser partielle Gradient über xlink:href dazu benutzt einen weiteren Gradienten zu definieren - jetzt mit einem gesetzten Wert für das spreadMethod-Attribut. Mit diesem wird dann das Rechteck gestyled. Damit das geht brauchen wir als drittes noch ein wenig CSS und dann kann es losgehen. Probiere das mit der Beispiel-Datei aus :)

Browser Support of Linear Gradients

A note on browser support: Opera 9.63 and Firefox/3.0.4 support all elements and attributes that I have used on this page. The new Safari 4 browser can understand basic gradients, but it seems that it does not support the spreadMethod attribute, in the above example all rectangles look exactly the same. Well, and the Internet Explorer, … ah, fuck it! *LOL* :)

Eine Bemerkung zur Browserunterstützung: Opera 9.63 und Firefox/3.0.4 verstehen anscheinend die Elemente und Attribute, die ich auf dieser Seite verwendet habe, ganz gut und stellen die Beispiele wie erwartet dar. Der neue Safari 4 Browser kann zwar Gradienten anzeigen, das Attribut spreadMethod wird aber anscheinend noch nicht unterstützt. Wer diese Seite mit Safari 4 besucht sollte sich deshalb nicht allzu sehr wundern, wenn im Beispiel oben alle Rechtecke völlig gleich aussehen. Und Internet Explorer, … ein Fall für die Tonne :)

Conclusion

I hope you enjoyed this little tutorial on linear gradients in SVG. Next time I will write about the application of radial gradients :)

Ich hoffe, dass dir dieses Tutorial über lineare Farbverläufe in SVG gefallen hat. Nächstes Mal schreibe ich dann etwas über die Anwendung von radialen Gradienten :)

Links and Ressources

all content copyright © 2007-2010 Alphane Moon