Nehmen wir an, jemand bittet Sie, geometrischen SVG-Formen einen **doppelten** Rahmen hinzuzufügen. Aus irgendeinem Grund können Sie keinen Grafikeditor verwenden – sie müssen zur Laufzeit generiert werden –, sodass Sie das Problem mit CSS oder innerhalb der SVG-Syntax lösen müssen.
Ihre erste Frage könnte sein: „Gibt es in SVG so etwas wie stroke-style: double?“ Nun, die Antwort ist noch nicht und es ist nicht so einfach. Aber ich werde es trotzdem versuchen, um zu sehen, welche Methoden ich aufdecken kann. Ich werde die Möglichkeiten von drei verschiedenen Grundformen untersuchen: Kreis, Rechteck und Polygon. Dabei weise ich auf diejenigen hin, die in der Mitte der beiden Linien eine transparente Farbe beibehalten können.
Spoiler-Alarm: Alle Ergebnisse haben zumindest mit CSS und SVG ihre Nachteile, aber lassen Sie mich Sie durch meine Absichten führen.
Die einfachen Lösungen
Diese funktionieren nicht mit allen Formen, aber sie sind die einfachsten Lösungen.
outline und box-shadow
Die CSS-Eigenschaften outline und box-shadow gelten nur für den Begrenzungsrahmen der Form oder des SVG. Daher sind beide großartige Lösungen **nur für Quadrate und Rechtecke**. Sie ermöglichen auch flexible Farben mithilfe von benutzerdefinierten Eigenschaften.
Mit outline genügen zwei Zeilen CSS, und der Hintergrund bleibt durch die Form sichtbar.
- 🙁 Nur für eine Form
- ✅ Einfacher Code
- ✅ Glatte Ränder
- ✅ Transparenter Hintergrund
box-shadow benötigt nur eine Zeile CSS, aber wir müssen **sicherstellen, dass jede Form ihr eigenes SVG hat**, da wir box-shadow nicht direkt auf die Formen anwenden können. Eine weitere Überlegung ist, dass wir die Hintergrundfarbe in der Deklaration angeben müssen.
- 🙁 Nur für eine Form
- ✅ Einfacher Code
- ✅ Glatte Ränder
- 🙁 Kein transparenter Hintergrund
SVG-Verläufe
SVG-Radialverläufe funktionieren nur bei Kreisen ☺️. Wir können den Verlauf direkt auf den Rand anwenden, aber es ist besser, Variablen zu verwenden, da wir die Farben mehrmals im Code deklarieren müssen.
- 🙁 Nur für eine Form
- ✅ Einfacher Code
- 🙁 Glatte Ränder
- 🙁 Kein transparenter Hintergrund
Lösungen für alle Formen
Diese funktionieren mit allen Formen, aber der Code könnte aufgebläht oder komplex werden.
filter: drop-shadow()
Endlich eine Lösung für alle Formen! Wir müssen jede Form in ihrem eigenen <svg> haben, da der filter nicht direkt auf die Formen angewendet wird. Wir verwenden eine Deklaration in CSS und haben flexible Farben mit Variablen. Der Nachteil? Die Ränder sehen nicht sehr glatt aus.
- ✅ Eine Lösung für alle Formen
- ✅ Einfacher Code
- 🙁 Ränder sehen pixelig aus
- 🙁 Kein transparenter Hintergrund
SVG-Filter
Dies ist eine sehr flexible Lösung. Wir können einen Filter erstellen und ihn über das filter-Attribut von SVG auf die Formen anwenden. Der komplizierte Teil hier ist der Filter selbst. Wir benötigen drei Malereien, eine für den äußeren Rahmen, eine für die Hintergrundflutung und die letzte, um die Form vorne zu malen. Das Ergebnis sieht besser aus als mit drop-shadow, aber die Ränder sind immer noch pixelig.
- ✅ Eine Lösung für alle Formen
- 🙁 Komplexer Code
- 🙁 Ränder sehen pixelig aus
- 🙁 Kein transparenter Hintergrund
Formen wiederverwenden
Hier gibt es ein paar mögliche Optionen.
Option 1: Transformationen
Diese Lösung erfordert Transformationen. Wir platzieren eine Figur über der anderen, wobei die Hauptfigur eine Füllfarbe und eine Randfarbe hat, und die andere Figur keine Füllung, einen roten Rand hat und skaliert und im Zentrum positioniert wird. Wir definieren unsere Formen im <defs>. Der Trick besteht darin, **die Hälfte des** viewBox **in den negativen Raum zu verschieben**, damit wir sie von der Mitte der Figur aus skalieren können.
- ✅ Eine Lösung für alle Formen
- 🙁 Duplizierter Code
- ✅ Glatte Ränder
- ✅ Transparenter Hintergrund
Option 2: <use>
Ich habe eine clevere Lösung in der www-svg-Mailingliste von Doug Schepers gefunden, die SVG <use> verwendet. Auch hier müssen die Formen einmal definiert und zweimal mit <use> referenziert werden. Diesmal hat die Hauptform einen größeren Rand. Die zweite Form hat die halbe Randbreite der Hauptform, keine Füllung und einen Rand, der der Hintergrundfarbe entspricht.
- ✅ Eine Lösung für alle Formen
- 🙁 Duplizierter Code
- ✅ Glatte Ränder
- 🙁 Kein transparenter Hintergrund
Hier sind die vollständigen Ergebnisse!
Damit Sie sie alle an einem Ort haben. Lassen Sie mich wissen, ob Ihnen andere mögliche Lösungen einfallen!
| Lösung | Alle Formen | Einfacher Code | Glatte Ränder | Transparenter Hintergrund |
|---|---|---|---|---|
outline | 🙁 | ✅ | ✅ | ✅ |
box-shadow | 🙁 | ✅ | ✅ | 🙁 |
| SVG-Verläufe | 🙁 | ✅ | 🙁 | 🙁 |
filter: drop-shadow() | ✅ | ✅ | 🙁 | 🙁 |
| SVG-Filter | ✅ | 🙁 | 🙁 | 🙁 |
| Formen wiederverwenden Transformationen | ✅ | 🙁 | ✅ | ✅ |
Formen wiederverwenden<use> | ✅ | 🙁 | ✅ | 🙁 |
Es gibt einen weiteren Ansatz: „Wiederverwenden mit Maske“. Ich glaube, dieser würde mindestens drei grüne Haken nach Ihren Kriterien erhalten.
Übrigens bin ich nicht Ihrer Meinung, dass der Ansatz „Formen wiederverwenden“ kein „einfacher Code“ ist. Bewerten Sie ihn als komplex, weil er das
<use>-Element verwendet? Sie könnten immer einfach das Element wiederholen, wenn<use>zu verwirrend ist.Ich mag diesen Ansatz sehr, ich habe es mit ‚mask‘ versucht und bin nirgendwo hingekommen, jetzt sehe ich, was mir gefehlt hat :)
Mmm, ja, ich gebe zu, dass „einfacher Code“ ziemlich subjektiv ist. Ich dachte an die Art und Weise, wie man die Form zuerst deklarieren und dann die Verwendung von ‚use‘ duplizieren muss. Nur eine Form im SVG zu haben, war auf eine Weise einfacher für mich.
Ich kam hierher in die Kommentare, um die Lösung von Paul LeBeau zu geben – was ich jetzt nicht tun werde – und um auf ein Problem mit der Transformationsmethode hinzuweisen. Sie funktioniert tatsächlich nicht mit allen Formen. Beispiele folgen. Versuchen Sie es mit einem Rechteck oder einer Ellipse, die viel breiter als hoch ist, und Sie werden sehen, dass der zweite Rahmen oben und unten zu nah am Original ist. Komplexere Formen wie der Buchstabe P, eine Mondsichel oder der Bundesstaat Massachusetts haben sicher Stellen, an denen der zweite Rahmen auf der falschen Seite des Originals liegt.
Der Trugschluss, dass die Außenseite einer Form nur eine größere Kopie dieser Form ist, ist ziemlich verbreitet, und ich habe gesehen, dass er zu einigen schlecht aussehenden Grafiken geführt hat (einschließlich Straßenschildern, leider).
Guter Punkt, ich hatte diese Formen nicht im Sinn, die Transformationsoption funktioniert dort nicht. Danke für den Hinweis!