SVG
SVG-Elemente haben geometry und presentational Attribute. Mit den presentational attributes können wir das Aussehen kontrollieren (und im CSS verändern !!). Wir können also entweder inline-Attribute im SVG verwenden oder die Eigenschaft mit einer CSS-Deklaration verändern, wobei CSS die inline-Attribute überschreibt.
Linien <line>
Section titled “Linien <line>” <svg width="280" height="280"> <line x1="80" y1="80" x2="200" y2="200" stroke="oklch(0.9 0.3 164)" stroke-width="5" /> </svg>Rechtecke <rect>
Section titled “Rechtecke <rect>”<svg width="280" height="280"> <rect x="40" y="80" width="160" height="100" fill="none" stroke="hotpink" stroke-width="5" /></svg>Rechteck mit abgerundeten Ecken
Section titled “Rechteck mit abgerundeten Ecken”Man kann den Eckradius für x und y separat setzen, aber das Ergebnis sieht dann komisch aus:
<svg width="280" height="280"> <rect x="80" y="100" width="500" height="500" rx="100" ry="50" stroke="goldenrod" stroke-width="5" fill="none" /></svg>Wenn wir den Radius nur für x setzen, wird y automatisch gleich gesetzt:
<svg width="280" height="280"> <rect x="80" y="100" rx="5" width="140" height="100" stroke="goldenrod" stroke-width="5" fill="none" /></svg>Wenn wir in CSS runde Formen oder Pill-Shapes haben wollen, nehmen wir für den Border-Radius einfach eine absurd hohe Zahl. Ein Border-Radius von 50% macht nämlich nur eine Ellipse (außer bei Quadraten). Mit SVG funktioniert das nicht, das ist aber egal, denn in einem SVG kennen wir üblicherweise die Maße und können den Border-Radius genau auf 50% der Breite oder Höhe setzen.
Kreise <circle>
Section titled “Kreise <circle>”<svg width="280" height="280"> <circle cx="120" cy="120" r="100" stroke="cornflowerblue" stroke-width="5" fill="none" /></svg>Fill ist das Äquivalent zu background-color. Die meisten Elemente sind automatisch schwarz gefüllt (was auch bei dark-mode so ist, SVG kennt kein color-scheme)
<svg width="280" height="280"> <circle class="filled" cx="120" cy="120" r="80" stroke="cornflowerblue" stroke-width="5" fill="none" /></svg>fill="none" funktioniert übrigens auch im svg-Element selbst, da es (pst!) heimlich verrebbar ist. Wenn also ein SVG mehrere Formen enthält, kann man die mit einer Zeile ungefüllt lassen. Genauso können wir natürlich auch alle anderen Attribute im SVG-Element selbst festlegen! currentColor verwenden wir, wenn z.B. die Farbe eines Icons automatisch die Textfarbe annehmen soll.
Transparenz bei Fill und Stroke
Section titled “Transparenz bei Fill und Stroke”Statt fill-opacity können wir auch eine CSS-Farbe mit Alpha-Kanal verwenden.
<svg width="200" height="200"> <circle cx="100" cy="100" r="40" stroke="tomato" stroke-width="5" fill="tomato" fill-opacity="0.25" /></svg>Genauso wie die Füllung können wir natürlich auch die Kontur transparent machen:
<svg width="200" height="200"> <circle cx="100" cy="100" r="40" stroke="tomato" stroke-width="15" fill="tomato" stroke-opacity="0.5" /></svg>Ellipsen
Section titled “Ellipsen”Eine Ellipse ist wie ein Kreis, aber wir können den vertikalen und den horizontalen Radius getrennt setzen:
<svg width="280" height="280"> <ellipse cx="120" cy="140" rx="100" ry="70" fill="none" stroke="rebeccapurple" stroke-width="5" /></svg>Polyline
Section titled “Polyline”Mit Polylines können wir nicht nur einfacher mehrere verbundene Linien zeichnen, sondern auch die Verbindungen zwischen den Linien kontrollieren!
<svg width="280" height="280"> <polyline points=" 60,100 100,180 140,140 180,180 220,100 " fill="none" stroke="lightsalmon" stroke-width="5" /></svg>Polygon
Section titled “Polygon”Polygone sind fast identisch mit Polylines, schließen sich aber automatisch:
<svg width="280" height="280"> <polygon points=" 60,100 100,180 140,140 180,180 220,100 " fill="lightsalmon" stroke="tomato" stroke-width="5" /></svg>Reguläre oder equilaterale Polygone sind übrigens eine Untergruppe der Polygone!
text-anchor: start | middle | enddominant-baseline: auto | middle | hanging- Schriftgröße etc. per CSS …
<svg width="280" height="280"> <text x="140" y="140" text-anchor="middle" dominant-baseline="auto" fill="midnightblue" > Hello <tspan>World!</tspan> </text></svg>Text-Outlines
Section titled “Text-Outlines”Strokes kann man auch für Texte verwenden, wobei es hier eine Besonderheit bzw. einen kleinen Trick gibt: Da die Outline nicht außen sitzt, sondern von der Mitte des Pfades ausgeht, kann Text mit Outline je nach Schriftart bzw. -größe komisch aussehen. Wir können das aber mit einer etwas obskuren CSS-Eigenschaft austricksen: paint-order. Wenn wir paint-order: stroke fill; setzen, dann wird zuerst die Outline gezeichnet und dann die Füllung. Normalerweise wird der Umriss auf die Füllung gezeichnet, wir kehren die Reihenfolge also um. Die Füllung überdeckt also die Hälfte des Umrisses.
Für ältere Browser könnte man auch den Text layern, also das svg kopieren und eine Variante mit Stroke und ohne Füllung unten und eine ohne Stroke und mit Füllung darüber legen.
Text-Umrisse können auch stroke-linejoin UND wir können das auch für HTML-Texte verwenden, und zwar mit der -webkit-text-stroke Eigenschaft 😄. Das ist aber mit Vorsicht zu genießen, da der Browser-Support nicht unbedingt gut gewährleistet ist. @supports sagt uns auch nur, ob es diese Eigenschaft gibt, und nicht, ob sie auch unterstützt wird.
<svg class="text-stroke" width="280" height="280"> <text x="50%" y="50%" text-anchor="middle" > Hello World! </text></svg>Overflow
Section titled “Overflow”Wenn man eine Form zeichnet, die bis zum Rahmen geht, wird der Overflow abgeschnitten:
<svg width="280" height="280"> <circle class="filled" cx="140" cy="140" r="140" stroke="cornflowerblue" stroke-width="5" fill="none" /></svg>Das passiert, weil die Kontur von der Mitte des Pfades aus gezeichnet wird. Man könnte jetzt rechnen und die Form an die Grenzen des SVG anpassen, oder man macht den overflow mit CSS einfach sichtbar: overflow=“visible”. Bei SVGs wird der Overflow standardmäßig abgeschnitten, anders als in CSS.
<svg class="ovw" width="280" height="280"> <circle class="filled" cx="140" cy="140" r="140" stroke="cornflowerblue" stroke-width="5" fill="none" /></svg>Caps und Joins
Section titled “Caps und Joins”Standardmäßig endet ein Pfad mit einer geraden Linie. Wir können dieses Verhalten mit stroke-linecap kontrollieren (butt = default, round, square, wobei square einfach über die Kontur rausgeht):
<svg width="220" height="220" stroke="limegreen" stroke-width="20" stroke-linecap="butt"> <line x1="40" y1="40" x2="180" y2="180" /> <line x1="180" y1="40" x2="40" y2="180" /></svg><svg width="220" height="220" stroke="limegreen" stroke-width="20" stroke-linecap="round"> <line x1="40" y1="40" x2="180" y2="180" /> <line x1="180" y1="40" x2="40" y2="180" /></svg><svg width="220" height="220" stroke="limegreen" stroke-width="20" stroke-linecap="square"> <line x1="40" y1="40" x2="180" y2="180" /> <line x1="180" y1="40" x2="40" y2="180" /></svg>Ähnlich ist stroke-linejoin. Damit kontrollieren wir, wie zwei Linien bei polygon oder polyline zusammenstoßen (miter = default, round, bevel). Miter kann oft sehr spitze Ecken machen, es wird dann automatisch zu bevel.
<div class="flex-wrap"> <svg width="220" height="220" fill="none" stroke="lime" stroke-width="15" stroke-linejoin="miter" > <polygon points="110,60 170,170 50,170" /> </svg> <svg width="220" height="220" fill="none" stroke="lime" stroke-width="15" stroke-linejoin="miter" > <polyline points="60,160 160,160 89,89" /> </svg> <svg width="220" height="220" fill="none" stroke="lime" stroke-width="15" stroke-linejoin="miter" > <polyline points="60,160 160,160 65,127" /> </svg></div>Bevel ist unschön. Um unsere Winkel spitz zu halten, können wir stroke-miterlimit auf einen großen Wert setzen, z.B. 100.
Dashes
Section titled “Dashes”Mit SVG Dashes haben wir sehr viel mehr Spielraum als mit CSS dashed und dotted, da auch die Länge der Zwischenräume kontrolliert werden kann: das macht stroke-dasharray. (Die Werte können mit Komma oder Leerzeichen getrennt werden.)
<svg class="animated" width="280" height="280"> <polyline points=" 60,60 80,260 200,260 220,60 " fill="none" stroke="hotpink" stroke-width="5" stroke-dasharray="10,10" /></svg>Dashes sind animierbar! Und wir können Dash-Muster auch wiederholen: dash - gap - dash -gap. Und um der Sache die Krone aufzusetzen, auch stroke-linecap funktioniert mit dasharray!
<div class="flex-wrap"> <svg width="200" height="200" fill="none"> <circle cx="100" cy="100" r="40" stroke="hotpink" stroke-width="10" stroke-dasharray="6,4,6,20" /> </svg> <svg width="300" height="300"> <circle cx="150" cy="150" r="100" fill="none" stroke="oklch(0.9 0.3 164)" stroke-width="5" stroke-dasharray="20,30" stroke-linecap="round" /> </svg></div>dash-offset … bewirkt, dass dieses Muster um den Pfad herumläuft. Das wird mit einem sehr großen gap interessant:
<svg width="276" height="276" fill="none"> <circle cx="138" cy="138" r="87.54" stroke="slateblue" stroke-width="5" stroke-dasharray="100,450" stroke-dashoffset="0" stroke-linecap="round" /></svg>Excercises
Section titled “Excercises”Smiley
Section titled “Smiley”<svg width="240" height="240"> <circle r="120" cx="120" cy="120" fill="hsl(45deg 100% 50%)" /> <ellipse cx="80" cy="100" rx="15" ry="20" fill="hsl(35deg 80% 20%)" /> <ellipse cx="160" cy="100" rx="15" ry="20" fill="hsl(35deg 80% 20%)" /> <circle cx="120" cy="120" r="60" fill="none" stroke="hsl(35deg 80% 20%)" stroke-width="10" stroke-dasharray="100,450" stroke-dashoffset="-45" stroke-linecap="round" /></svg>Spark Lines
Section titled “Spark Lines”<svg width="200" height="100"> <polyline points="" fill="none" stroke="hotpink" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" /></svg>Hamburger Menu Icon
Section titled “Hamburger Menu Icon”<svg width="64" height="64" viewBox="0 0 24 24" stroke="#000000" stroke-width="2" stroke-linecap="round"> <line x1="5" y1="7" x2="19" y2="7" /> <line x1="5" y1="12" x2="19" y2="12" /> <line x1="5" y1="17" x2="19" y2="17" /></svg>Placeholder
Section titled “Placeholder”<svg width="300" height="200" viewBox="0 0 300 200"> <rect x="0" y="0" width="300" height="200" fill="gainsboro" /> <rect x="100" y="50" width="100" height="100" stroke-width="3" stroke="#FFFFFF" stroke-linecap="round" fill="none" /> <circle r="15" cx="127" cy="80" fill="#FFFFFF" /> <path d=" M 100,105 C 140,160 160,60 200,110 L 200,150 L 100,150 Z " stroke="#FFFFFF" stroke-width="3" fill="#FFFFFF" /></svg>
<svg width="300" height="200" viewBox="0 0 300 200"> <rect x="0" y="0" width="300" height="200" fill="var(--highlight-color)"/> <rect x="100" y="50" width="100" height="100" stroke-width="3" stroke="#FFFFFF" stroke-linecap="round" fill="none" /> <circle r="15" cx="127" cy="80" fill="#FFFFFF" /> <path d=" M 100,105 C 140,160 160,60 200,110 L 200,150 L 100,150 Z " stroke="#FFFFFF" stroke-width="3" fill="#FFFFFF" /></svg>
<svg width="300" height="200" viewBox="0 0 300 200"> <rect x="0" y="0" width="300" height="200" /> <rect x="100" y="50" width="100" height="100" stroke-width="3" stroke="#FFFFFF" stroke-linecap="round" fill="none" /> <circle r="15" cx="127" cy="80" fill="#FFFFFF" /> <path d=" M 100,105 C 140,160 160,60 200,110 L 200,150 L 100,150 Z " stroke="#FFFFFF" stroke-width="3" fill="#FFFFFF" /></svg>Aspect ratio
Section titled “Aspect ratio”Mit dem Attribut preserveAspectRatio können wir die fixen Proportionen (den default-Wert) aufheben. preserveAspectRatio="none" erlaubt, ein SVG zu strecken und zusammenzudrücken.
Non-Scaling Stroke
Section titled “Non-Scaling Stroke”Während preserveAspectRatio für gefüllte Formen gut funktioniert, passiert bei Linien etwas seltsames: Eine geschwungene Linie wird beim auseinanderziehen bzw. zusammenquetschen an manchen Stellen dicker, an manchen dünner. Warum tut sie das? An den Stellen, an denen die Linie waagrecht oder fast waagrecht verläuft, wird sie beim zusammenquetschen dicker, wo sie (annähernd) senkrecht verläuft, wird sie dünner. Das macht Sinn – denn wenn die Breite reduziert wird, wird eben auch die Breite der vertikalen Linie im Verhältnis dünner. Wir können das mit CSS fixen:
svg * { vector-effect: non-scaling-stroke;}Vermutlich verändert diese CSS-Eigenschaft die Reihenfolge, in der die Operationen innerhalb des SVG ausgeführt werden. Statt die Linie vor dem zusammenquetschen oder strecken zu zeichnen, wird sie nachher gezeichnet. So wird der Pfad verändert, aber nicht die Linie selbst.
Swoops-Wrapper
Section titled “Swoops-Wrapper”<div class="swoops-wrapper"> <svg class="swoops" preserveAspectRatio="none" viewBox="0 0 780 151" > <path d="M175 0.0551758C78 -1.94482 0 51.0553 0 51.0553V150.055H780V119.055C780 119.055 723 32.0551 585 38.0552C447 44.0553 429 84.0552 348 70.0553C267 56.0553 272 2.05518 175 0.0551758Z" /> </svg></div>