Ich habe kürzlich an einem ReactJS Training von Michael Jackson und Ryan Florence teilgenommen. Ich war wirklich aufgeregt, teilzunehmen, teilweise weil ich so viele Fragen zu SVG und React hatte. Es gibt viele Aspekte der Arbeit mit React und SVG, und insbesondere deren Manipulation, die noch nicht vollständig unterstützt werden. Eine der größten Lücken für mich war das <use>-Element, da die meisten SVG-Icon-Systeme mit <use> erstellt werden.
Ich fragte Michael, ob er dachte, dass eine bessere Unterstützung für einige dieser Funktionen kommen würde, aber er zeigte mir einen viel besseren Weg, damit zu arbeiten, und umging diese Methode vollständig. Wir werden diese Technik durchgehen, damit Sie mit der Erstellung skalierbarer SVG-Icon-Systeme in React beginnen können, sowie einige Tricks, die meiner Meinung nach auch gut funktionieren könnten.
Hinweis: Es ist erwähnenswert, dass die Unterstützung für `use` kürzlich verbessert wurde, aber ich habe festgestellt, dass sie bestenfalls sporadisch ist und es andere Routing- und XML-Probleme gibt. Wir zeigen Ihnen hier einen anderen, saubereren Weg.
Was ist <use>?
Für diejenigen, die nicht vertraut sind, wie SVG-Icon-Systeme typischerweise aufgebaut sind, funktioniert es ungefähr so. Das <use>-Element klont eine Kopie eines beliebigen anderen SVG-Formelement mit der ID, auf die Sie im xlink:href-Attribut verweisen, und ermöglicht es Ihnen, es zu manipulieren, ohne alle Pfaddaten wiederholen zu müssen. Sie fragen sich vielleicht, warum man nicht einfach ein SVG als <img>-Tag verwenden würde. Das könnten Sie, aber dann wäre jedes Icon eine einzelne Anfrage und Sie hätten keinen Zugriff auf die Änderung von Teilen des SVG, wie z. B. die fill-Farbe.
Die Verwendung von <use> ermöglicht es uns, die Pfaddaten und das grundlegende Erscheinungsbild unserer Icons an einem Ort zu definieren, sodass sie einmal aktualisiert und überall geändert werden können, während wir immer noch den Vorteil haben, sie im laufenden Betrieb zu aktualisieren.
Joni Trythall hat einen großartigen Artikel über `use` und SVG-Icons, und Chris Coyier hat hier auf CSS-Tricks ebenfalls einen fantastischen Artikel geschrieben.
Hier ist ein kleines Beispiel, wenn Sie sehen möchten, wie der Markup aussieht
Siehe den Pen bc5441283414ae5085f3c19e2fd3f7f2 von Sarah Drasner (@sdras) auf CodePen.
Warum sich die Mühe mit SVG-Icons machen?
Manche von Ihnen fragen sich vielleicht an diesem Punkt, warum wir ein SVG-Icon-System anstelle eines Icon-Fonts verwenden würden. Wir haben unseren eigenen Vergleich zu diesem Thema. Außerdem schreiben und reden viele Leute gerade darüber.
Hier sind einige der überzeugendsten Gründe meiner Meinung nach:
- Icon-Fonts sind schwer zugänglich zu machen. SVG hat die Fähigkeit, Titel- und ARIA-Tags hinzuzufügen, was einen enormen Vorteil für die Barrierefreiheit bietet, insbesondere in Fällen, in denen das Icon allein steht und die einzige Informationsquelle für die Navigation ist. Denken Sie an blinde Menschen, Menschen mit Legasthenie, ältere Menschen (Sie werden auch irgendwann alt sein, hoffentlich, also wenn Sie nicht der Typ Entwickler sind, der sich um diese Untergruppe kümmert, tun Sie es für das Karma! Aber im Ernst, kümmern Sie sich um ältere Menschen.)
- Icon-Fonts sind auf einigen Displays nicht so scharf. Sie können dies vermeiden, indem Sie eine ausgefallene Font-Glättung in CSS durchführen, aber hier ist eine Einschränkung, die ich bemerkt habe: Es ist schwierig, sie zu überschreiben, ohne die Font-Glättung vollständig auszuschalten. SVGs sind generell schärfer, Zeichnen ist das, wofür sie gebaut wurden.
- Icon-Fonts schlagen oft fehl. Die meisten Entwickler, die ich kenne, sind auf Szenarien gestoßen, in denen das Glyph X in einem Feld fehlt. Es gibt viele Möglichkeiten, wie Icon-Fonts fehlschlagen können, wo SVGs dies nicht tun. Sei es CORS-Probleme oder Opera Mini, es ist ein Kopfschmerz.
- Icon-Fonts sind schwer zu positionieren. Sie sind ein Bild, das Sie mit Schriftartenstilen positionieren. Genug gesagt. Sie können keine Teile davon ohne hacky Stapelung animieren. SVGs bieten ein navigierbares DOM, um Teile eines Icons zu animieren oder Abschnitte zu kolorieren. Nicht jeder würde das wollen, aber es ist schön, die Option zu haben.
Wenn Sie wie ich sind und eine riesige Codebasis aktualisieren, bei der Sie, um von einem Icon-Font zu SVG zu wechseln, buchstäblich Hunderte von Markup-Instanzen aktualisieren müssten, dann verstehe ich das. Ich verstehe es. Es ist in diesem Fall vielleicht nicht die Zeit wert. Aber wenn Sie Ihre Ansichten neu schreiben und sie mit React aktualisieren, lohnt es sich, diese Gelegenheit zu überdenken.
Tl;dr: Sie brauchen <use> in React nicht
Nachdem Michael geduldig zugehört hatte, wie ich erklärte, wie wir <use> verwenden, und ich ihm ein Beispiel für ein Icon-System gezeigt hatte, war seine Lösung einfach: Es ist nicht wirklich notwendig.
Betrachten Sie dies: Der einzige Grund, warum wir Icons definierten, um sie dann wiederzuverwenden (normalerweise als <symbol>s in <defs>), war, damit wir uns nicht wiederholen mussten und die SVG-Pfade einfach an einer Stelle aktualisieren konnten. Aber React ermöglicht das bereits. Wir erstellen einfach die Komponente
// Icon
const IconUmbrella = React.createClass({
render() {
return (
<svg className="umbrella" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" aria-labelledby="title">
<title id="title">Umbrella Icon</title>
<path d="M27 14h5c0-1.105-1.119-2-2.5-2s-2.5 0.895-2.5 2v0zM27 14c0-1.105-1.119-2-2.5-2s-2.5 0.895-2.5 2c0-1.105-1.119-2-2.5-2s-2.5 0.895-2.5 2v0 14c0 1.112-0.895 2-2 2-1.112 0-2-0.896-2-2.001v-1.494c0-0.291 0.224-0.505 0.5-0.505 0.268 0 0.5 0.226 0.5 0.505v1.505c0 0.547 0.444 0.991 1 0.991 0.552 0 1-0.451 1-0.991v-14.009c0-1.105-1.119-2-2.5-2s-2.5 0.895-2.5 2c0-1.105-1.119-2-2.5-2s-2.5 0.895-2.5 2c0-1.105-1.119-2-2.5-2s-2.5 0.895-2.5 2c0-5.415 6.671-9.825 15-9.995v-1.506c0-0.283 0.224-0.499 0.5-0.499 0.268 0 0.5 0.224 0.5 0.499v1.506c8.329 0.17 15 4.58 15 9.995h-5z"/>
</svg>
)
}
});
// which makes this reusable component for other views
<IconUmbrella />
Siehe den Pen SVG-Icon in React von Sarah Drasner (@sdras) auf CodePen.
Und wir können sie immer wieder verwenden, aber im Gegensatz zur älteren <use>-Methode haben wir keine zusätzliche HTTP-Anfrage.
Zwei SVG-ähnliche Dinge, die Ihnen im obigen Beispiel auffallen könnten. Erstens, ich habe nicht diese Art von Ausgabe
<?xml version="1.0" encoding="utf-8"?>
<!-- Generated by IcoMoon.io -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
Oder sogar diese am SVG-Tag selbst
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" …
Das liegt daran, dass ich sichergestellt habe, meine SVGs mit SVGOMG oder SVGO zu optimieren, bevor ich das Markup überall hinzufüge. Ich empfehle Ihnen dringend, dies ebenfalls zu tun, da Sie die Größe Ihres SVG um einen beträchtlichen Betrag reduzieren können. Ich sehe normalerweise Prozentsätze um die 30 %, können aber bis zu 60 % oder mehr erreichen.
Eine weitere Sache, die Ihnen vielleicht auffällt, ist, dass ich einen Titel und ein ARIA-Tag hinzufüge. Dies wird Bildschirmsprachausgaben für Menschen, die assistierende Technologien verwenden, helfen, das Icon vorzulesen.
<svg className="umbrella" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" aria-labelledby="title">
<title id="title">Umbrella Icon</title>
Da diese ID eindeutig sein muss, können wir Instanzen des Icons mit Props übergeben und diese werden sowohl für den Titel als auch für das Aria-Tag übernommen, wie hier gezeigt
// App
const App = React.createClass({
render() {
return (
<div>
<div className="switcher">
<IconOffice iconTitle="animatedOffice" />
</div>
<IconOffice iconTitle="orangeBook" bookfill="orange" bookside="#39B39B" bookfront="#76CEBD"/>
<IconOffice iconTitle="biggerOffice" width="200" height="200"/>
</div>
)
}
});
// Icon
const IconOffice = React.createClass({
...
render() {
return (
<svg className="office" xmlns="http://www.w3.org/2000/svg" width={this.props.width} height={this.props.height} viewBox="0 0 188.5 188.5" aria-labelledby={this.props.iconTitle}>
<title id={this.props.iconTitle}>Office With a Lamp</title>
...
</svg>
)
}
});
ReactDOM.render(<App/>, document.querySelector("#main"));
Der beste Teil, vielleicht
Hier ist ein wirklich cooler Teil dieses Ganzen: Abgesehen von der Notwendigkeit zusätzlicher HTTP-Anfragen kann ich die Form des SVG in Zukunft vollständig aktualisieren, ohne Änderungen am Markup vornehmen zu müssen, da die Komponente in sich abgeschlossen ist. Noch besser ist, dass ich nicht die gesamte Icon-Schriftart (oder SVG-Sprite) auf jeder Seite laden muss. Da alle Icons als Komponenten vorliegen, kann ich etwas wie webpack verwenden, um für die jeweilige Ansicht zu "opt-in", welche Icons ich benötige. Angesichts des Gewichts von Schriften und insbesondere von schwergewichtigen Icon-Font-Glyphen ist dies eine enorme Möglichkeit für eine Leistungssteigerung.
All das, plus: Wir können Teile des Icons im laufenden Betrieb mit Farbe oder Animation auf sehr einfache Weise mit SVG und Props verändern.
Dynamische Veränderung im laufenden Betrieb
Eine Sache hier, die Ihnen vielleicht aufgefallen ist, ist, dass wir sie noch nicht im laufenden Betrieb anpassen, was ein Grund dafür ist, dass wir SVG überhaupt verwenden, oder? Wir können einige Standard-Props für das Icon deklarieren und sie dann ändern, wie hier
// App
const App = React.createClass({
render() {
return (
<div>
<IconOffice />
<IconOffice width="200" height="200"/>
</div>
)
}
});
// Icon
const IconOffice = React.createClass({
getDefaultProps() {
return {
width: '100',
height: '200'
};
},
render() {
return (
<svg className="office" width={this.props.width} height={this.props.height} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 188.5 188.5" aria-labelledby="title">
<title id="title">Office Icon</title>
...
</svg>
)
}
});
ReactDOM.render(<App />, document.querySelector("#main"));
Siehe den Pen SVG-Icon in React mit Standard-Props von Sarah Drasner (@sdras) auf CodePen.
Nehmen wir es noch einen Schritt weiter und ändern Sie einige der Erscheinungsbilder basierend auf der Instanz. Wir können Props dafür verwenden und einige Standard-Props deklarieren.
Ich liebe SVG, weil wir jetzt ein navigierbares DOM haben. Im Folgenden ändern wir die Farbe mehrerer Formen im laufenden Betrieb mit fill. Beachten Sie, dass Sie, wenn Sie es gewohnt sind, mit Icon-Fonts zu arbeiten, die Farbe nicht mehr mit color, sondern mit fill ändern. Sie können das zweite Beispiel unten überprüfen, um dies in Aktion zu sehen, die Bücher haben ihre Farbe geändert. Ich liebe auch die Möglichkeit, diese Teile im laufenden Betrieb zu animieren. Unten haben wir es in einen Div eingebettet, um es sehr einfach mit CSS zu animieren (möglicherweise müssen Sie auf "Wiederholen" klicken, um die Animation zu sehen).
Siehe den Pen SVG-Icon in React mit Standard-Props und Animation von Sarah Drasner (@sdras) auf CodePen.
// App
const App = React.createClass({
render() {
return (
<div>
<div className="switcher">
<IconOffice />
</div>
<IconOffice bookfill="orange" bookside="#39B39B" bookfront="#76CEBD" />
<IconOffice width="200" height="200" />
</div>
)
}
});
// Icon
const IconOffice = React.createClass({
getDefaultProps() {
return {
width: '100',
height: '200',
bookfill: '#f77b55',
bookside: '#353f49',
bookfront: '#474f59'
};
},
render() {
return (
<svg className="office" xmlns="http://www.w3.org/2000/svg" width={this.props.width} height={this.props.height} viewBox="0 0 188.5 188.5" aria-labelledby="title">
<title id="title">Office Icon</title>
<g className="cls-2">
<circle id="background" className="cls-3" cx="94.2" cy="94.2" r="94.2"/>
<path className="cls-4" d="M50.3 69.8h10.4v72.51H50.3z"/>
<path fill={this.props.bookside} d="M50.3 77.5h10.4v57.18H50.3z"/>
<path fill={this.props.bookfront} d="M60.7 77.5h38.9v57.19H60.7z"/>
<path className="cls-7" d="M60.7 69.8h38.9v7.66H60.7z"/>
<path className="cls-5" d="M60.7 134.7h38.9v7.66H60.7z"/>
...
</svg>
)
}
});
ReactDOM.render(<App />, document.querySelector("#main"));
.switcher .office {
#bulb { animation: switch 3s 4 ease both; }
#background { animation: fillChange 3s 4 ease both; }
}
@keyframes switch {
50% {
opacity: 1;
}
}
@keyframes fillChange {
50% {
fill: #FFDB79;
}
}
Einer meiner fantastischen Kollegen bei Trulia, Mattia Toso, hat auch eine wirklich schöne, viel schlankere Methode zur Deklaration all dieser Props empfohlen. Wir können die Wiederholung von this.props reduzieren, indem wir Konstanten für all unsere Verwendungen deklarieren und dann einfach die Variable anwenden.
render() {
const { height, width, bookfill, bookside, bookfront } = this.props;
return (
<svg className="office" xmlns="http://www.w3.org/2000/svg" width={width} height={height} viewBox="0 0 188.5 188.5" aria-labelledby="title">
<title id="title">Office Icon</title>
<g className="cls-2">
<circle id="background" className="cls-3" cx="94.2" cy="94.2" r="94.2"/>
<path className="cls-4" d="M50.3 69.8h10.4v72.51H50.3z"/>
<path fill={bookside} d="M50.3 77.5h10.4v57.18H50.3z"/>
<path fill={bookfront} d="M60.7 77.5h38.9v57.19H60.7z"/>
Wir können dies auch *noch* besser machen, indem wir propTypes für die verwendeten Props deklarieren. PropTypes sind äußerst hilfreich, da sie wie lebende Dokumente für die wiederverwendeten Props sind.
propTypes: {
width: string,
height: string,
bookfill: string,
bookside: string,
bookfront: string
},
Auf diese Weise erhalten wir, wenn wir sie falsch verwenden, wie im folgenden Beispiel, einen Konsolenfehler, der unseren Code nicht stoppt, sondern andere Personen, mit denen wir zusammenarbeiten könnten (oder uns selbst), darauf aufmerksam macht, dass wir Props falsch verwenden. Hier verwende ich eine Zahl anstelle einer Zeichenkette für meine Props.
<IconOffice bookfill={200} bookside="#39B39B" bookfront="#76CEBD" />
Und ich erhalte folgenden Fehler

Siehe den Pen SVG-Icon in React mit Spread mit Fehler von Sarah Drasner (@sdras) auf CodePen.
Noch schlanker mit React 0.14+
In neueren Versionen von React können wir einen Teil dieses unnötigen Codes reduzieren und unseren Code noch weiter vereinfachen, aber nur, wenn es sich um eine sehr "dumme" Komponente handelt, d.h. sie nimmt keine Lifecycle-Methoden an. Icons sind dafür ein ziemlich guter Anwendungsfall, da wir hauptsächlich rendern. Versuchen wir es also. Wir können uns von React.createClass verabschieden und unsere Komponenten als einfache Funktionen schreiben. Das ist ziemlich genial, wenn Sie schon lange JavaScript verwenden, aber mit React weniger vertraut sind – es liest sich wie die Funktionen, an die wir alle gewöhnt sind. Lassen Sie uns unsere Props noch weiter aufräumen und das Regenschirmsymbol wie auf einer Website wiederverwenden.
// App
function App() {
return (
<div>
<Header />
<IconUmbrella />
<IconUmbrella umbrellafill="#333" />
<IconUmbrella umbrellafill="#ccc" />
</div>
)
}
// Header
function Header() {
return (
<h3>Hello, world!</h3>
)
}
// Icon
function IconUmbrella(props) {
const umbrellafill = props.umbrellafill || 'orangered'
return (
<svg className="umbrella" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" aria-labelledby="title">
<title id="title">Umbrella</title>
<path fill={umbrellafill} d="M27 14h5c0-1.105-1.119-2-2.5-2s-2.5 0.895-2.5 2v0zM27 14c0-1.105-1.119-2-2.5-2s-2.5 0.895-2.5 2c0-1.105-1.119-2-2.5-2s-2.5 0.895-2.5 2v0 14c0 1.112-0.895 2-2 2-1.112 0-2-0.896-2-2.001v-1.494c0-0.291 0.224-0.505 0.5-0.505 0.268 0 0.5 0.226 0.5 0.505v1.505c0 0.547 0.444 0.991 1 0.991 0.552 0 1-0.451 1-0.991v-14.009c0-1.105-1.119-2-2.5-2s-2.5 0.895-2.5 2c0-1.105-1.119-2-2.5-2s-2.5 0.895-2.5 2c0-1.105-1.119-2-2.5-2s-2.5 0.895-2.5 2c0-5.415 6.671-9.825 15-9.995v-1.506c0-0.283 0.224-0.499 0.5-0.499 0.268 0 0.5 0.224 0.5 0.499v1.506c8.329 0.17 15 4.58 15 9.995h-5z"/>
</svg>
)
}
ReactDOM.render(<App />, document.querySelector("#main"));
Siehe den Pen SVG-Icon in React von Sarah Drasner (@sdras) auf CodePen.
SVG-Icon-Systeme sind in React wunderschön einfach und leicht erweiterbar, haben weniger HTTP-Anfragen und sind zukünftig leicht zu warten, da wir den Output vollständig aktualisieren können, ohne wiederholte Markup-Änderungen. Wir können die Leistung steigern, indem wir genau das auswählen, was wir brauchen. Wir können sie im laufenden Betrieb mit Props für Farbe ändern und sogar CSS-Animationen hinzufügen. All das und wir können sie auch für Bildschirmsprachausgaben zugänglich machen, was React und SVG-Icon-Systeme zu einer wirklich schönen Möglichkeit macht, Icons zu Ansichten im Web hinzuzufügen.
Ähm, Sie empfehlen also, JavaScript zu verwenden, um jedes Mal, wenn ein Icon verwendet wird, ein vollständiges SVG einzufügen? Wenn Sie also eine Tabelle mit 100 Datensätzen haben und jeder Datensatz ein Bleistiftsymbol, ein Mülleimersymbol und ein Status-Symbol hat, werden Sie JavaScript verwenden, um buchstäblich 300 SVGs einzufügen, jedes komplett mit allen Pfadinformationen für dieses Symbol?
Und wie genau ist das besser als
<use>(lassen Sie den Browser die Duplizierung intern durchführen, anstatt sie mit JS zu emulieren) oder sogar ein altmodisches Hintergrundbild-SVG-Sprite (vergessen Sie die Duplizierung von irgendetwas, rendern Sie einfach ein Bild, das bereits im Speicher ist, nur mit einem anderen Offset)?Ich meine, ich verstehe, es macht Sprites einfach anzupassen, aber ich sehe einfach nicht, wie das für irgendeinen wirklichen Gebrauch skalierbar ist. Ich hoffe, ich muss niemals eine Codebasis warten, die sich entschieden hat, ihre individuellen Sprites in JavaScript-Komponenten zu verpacken.
Nein, das ist es nicht, was ich empfehle. Ich zeige Ihnen, wie Sie SVG-Icon-Systeme verwenden, wenn Sie bereits React verwenden. Nicht, um eine Ansicht, die nicht in React ist, in React zu konvertieren, um SVG-Icons zu verwenden.
Ich erkläre auch, warum wir `use` in diesem Fall nicht verwenden, in dem Artikel. Und auch, warum Sie, wenn Sie React so verwenden, wie ich es beschreibe, nicht jede Instanz für jedes SVG-Icon auf die Seite laden müssen.
Nachdem ich die von Agop vorgebrachten Kritikpunkte etwa 15 Mal erneut gelesen habe, bin ich mir nicht sicher, ob Sarah sie tatsächlich angesprochen hat.
So wie ich es verstehe, fragt Agop, wie gültig diese Art von Mechanismus auf einer realen Website wäre. Das bereitgestellte Beispiel, das wir sicher alle schon einmal entworfen haben, ist eine tabellarische Liste von Datensätzen mit Symbolen zur Anzeige von Aktionen (Bearbeiten, Löschen usw.).
Dies ist ein Anwendungsfall, bei dem Sprites oder sogar Schriftart-Icons glänzen. Wie gut würde die Lösung dieses Artikels hier funktionieren? Es scheint, dass diese Methode erfordern würde, dass das SVG für jede Iteration eindeutig gerendert wird ... daher scheint es ein Skalierungsproblem zu geben, wenn Ihre Website / App / was auch immer stark auf SVG-generierte Icons als UI/UX-Element angewiesen wäre.
Oder ist das Argument, dass man React für eine Situation wie die von Agop präsentierte einfach nicht verwenden würde?
Nur als Denkanstoß: GitHub hat kürzlich auf SVG-Icons umgestellt.
Und nebenbei bemerkt, bin ich etwas besorgt über den Ton hier. Es gibt Wege, Bedenken ohne unhöflichen Ton anzusprechen. Ich habe Freunde, die großartige Dinge über die Verwendung einer Sonnenlicht-Schreibtischlampe gesagt haben, wie sie ihre Stimmung während des Tages beeinflussen kann.
Es geht hier wirklich um
<svg><use>vs<svg><path>Es wäre interessant, einige TESTSEITEN zu erstellen! 300 Icons klingt nach einer angemessenen Anzahl zum Testen. Vielleicht 10 eindeutige Icons, jeweils 30 Mal verwendet.
Seite 1: SVG-Sprite mit
<symbol>s für jedes eindeutige Icon und<use>, das alle 300 Mal verwendet wird, um sie zu zeichnenSeite 2: Alle 300 Icons einzeln gezeichnet mit
<svg><path> ...Aber was sind dann die Fragen? Vielleicht…
Ähm, warum würde jemand empfehlen, das zu tun?
Okay, nehmen wir an, Sie haben unterschiedliche Icons für Bearbeiten, Posten, Löschen. Wenn Sie `use` in SVG-Icons verwenden, rendern Sie immer noch die Pfaddaten im Shadow-DOM, auch mit `use`. Wenn Sie eine Icon-Schriftart verwenden, rendern Sie alle Glyphen für das gesamte Set in dieser Ansicht, egal ob Sie sie benötigen oder nicht. Dies sind typischerweise viel mehr Icons, als Sie normalerweise benötigen, um diese Tabelle zu rendern.
Jede Technik hat ihre richtigen Einsatzbereiche und ihren Overhead, und es ist die Aufgabe des Entwicklers, das Werkzeug entsprechend auszuwählen. Es hängt davon ab, wie viele Icons Ihre Website hat und wie groß diese Icon-Schriftart wäre. Es hängt auch davon ab, wie oft Sie die Icons in einer bestimmten Ansicht verwenden. Ich würde sagen, die Tabelle ist tatsächlich ein kleinerer Anwendungsfall im gesamten Web als die Verwendung von Icons in einem Menü oder einer Ansicht, und jede dieser würde unterschiedliche Techniken erfordern. Im Fall der Tabelle könnte ein SVG-Sprite besser sein, wenn Sie die Farbe nicht ändern müssen. Wenn Sie die Farbe ändern oder sie animieren möchten, wäre das keine großartige Anwendung mehr. Wir als Webentwickler sollten das richtige Werkzeug für die Aufgabe verwenden, aber wir sollten die Parameter darum herum verstehen, bevor wir entscheiden.
Agop erwähnt: "Und wie genau ist das besser als `use` (lassen Sie den Browser die Duplizierung intern durchführen, anstatt sie mit JS zu emulieren)" – was in erster Linie im Artikel behandelt wird, weshalb ich hier nicht ins Detail gegangen bin – es ist bereits abgedeckt. Ich erkläre auch, dass Sie mit etwas wie webpack nicht alle SVG- und JS-Daten in jede Ansicht laden müssen, wie im Artikel beschrieben.
Eines muss hier verstanden werden: Der Artikel schreibt nicht vor, dass wir Icon-Fonts oder SVG `use` wegwerfen, um neue SVGs in React zu erstellen – er schlägt eine Lösung für den Mangel an Unterstützung für `use` in React vor und wie man dies überwinden kann, um ein Icon-System zu erstellen.
Das ist nicht mehr gültig. Ich glaube, ab 0.14 oder so. Siehe meine JSPerf-Tests unten zur Verwendung von
<use>innerhalb von React.Ago, ich verstehe Ihre Bedenken bezüglich der Verwendung von JavaScript zur Erstellung von Ansichten, die bereits in HTML erstellt werden konnten und sollten. Eine Sache, die an JS (und React) großartig ist, ist, dass all dies mit JS auf dem Server gerendert werden kann. Das ist ein Gewinn für wiederverwendbaren Code und schnelles Server-Rendering. Die Verwendung der in diesem Artikel beschriebenen Technik hindert Sie nicht am Server-Rendering.
Ich habe kürzlich etwas sehr Ähnliches getan. Aber das SVG nicht in JS verpackt, sondern React das SVG-Datei importieren lassen. Dies erfordert mehr "webpack"-Setup (SVG-inline-loader), bedeutet aber, dass das SVG innerhalb einer .svg-Datei bleibt.
Diese Kombination bedeutet, dass wir die Vorteile von Inline-SVG (Stil- und Übergangsänderungen), Server-Side Rendering und Client-seitigem Caching erhalten, was meiner Meinung nach bisher nicht so eloquent möglich war.
Wenn Sie
<svg><use>mit svg4everybody verwenden, um Ihre SVG-Sprites von einem CDN per AJAX abzurufen und CORS-Probleme zu umgehen (wie hier empfohlen: https://github.com/jonathantneal/svg4everybody/issues/21), schreiben Sie am Ende sowieso eine Menge SVGs in das DOM. Ich mag den Vorschlag, dies in die JS-Payload zu integrieren und svg4everybody aus der Gleichung zu nehmen.Wenn Sie zufällig Browserify verwenden… https://github.com/coma/svg-reactify
Ich stimme Agop teilweise zu, dass dies eine bessere Lösung für komplexere, einzelne Illustrationen zu sein scheint, anstatt für Icons, die überall auf einer Seite verwendet werden.
In einem React-Projekt, an dem ich arbeite, verwenden wir eine generischere Icon-Komponente, die einen Icon-Namen und eine Größe als Props entgegennimmt (wie hier:
<Icon name="umbrella" size="big" />) und intern dasuse-Tag verwendet, was in React 0.14 (und davor mitdangerouslySetInnerHTML, Hust Hust) kein Problem ist. Für Fälle, die mehr Kontrolle erfordern, sieht Ihre Lösung wie ein großartiger Ansatz aus.Außerdem ein kleiner Hinweis: Die Standardwerte für `width` & `height` in Ihrer
getDefaultProps()-Funktion enthalten die CSS-Einheit "px", die ungültig ist, wenn Sie sie in einem HTML-Attribut verwenden.Hallo diondiondion,
Guter Punkt wegen des px! Danke, aktualisiert.
Abgesehen von etwaigen `use`-Problemen ist der interessante Punkt hier `use` vs. `path`, ob `use` wirklich notwendig ist. Es scheint mir, dass, wenn Sie immer noch das Shadow-DOM mit `use` rendern, um zu unterscheiden, ob es nicht mehr Arbeit für dasselbe ist. Betrachten Sie dies: Wenn Sie ein SVG-Sprite laden und dann auch das SVG-Icon beschreiben, laden Sie möglicherweise mehr als nötig. Wenn Sie nur die SVG-Icon-Komponente laden, können Sie theoretisch die Icons auswählen, die Sie für eine bestimmte Ansicht benötigen.
Falls Sie neugierig sind, ob andere Leute SVGs auf diese Weise inline verwenden, GitHub hat kürzlich einen Artikel veröffentlicht, der detailliert beschreibt, wie sie das gemacht haben: https://github.com/blog/2112-delivering-octicons-with-svg.
Ich glaube sicherlich, dass es Fälle gibt, in denen dieser Ansatz nicht ideal ist, aber ich bin mir nicht sicher, ob die hier genannten Gründe die üblichen Vor- und Nachteile berücksichtigen, und ich denke immer noch, dass dies in den Fällen von React und Ihrer typischen Website einen Leistungs- und Workflow-Schub bieten könnte. Aber vor allem: Testen Sie Ihren Anwendungsfall! Testen Sie alles!
Hallo Sarah,
Es stimmt, dass Sie in einigen Fällen Ressourcen effizienter laden könnten, indem Sie den Pfad direkt einfügen. In der Praxis bezweifle ich, dass einer der beiden Ansätze in Bezug auf die Leistung viel besser oder schlechter ist als der andere. Ein potenzieller großer Vorteil von
useist, dass moderne Browser externe SVG-Sprites für zukünftige Seitenaufrufe cachen können. In Browsern, die dies nicht unterstützen (am bekanntesten IE & frühes Edge), können sie mithilfe eines Polyfills wie svgxuse in die Seite eingefügt werden.Aber das erinnert mich tatsächlich an das, was vielleicht der größte Vorteil der Verwendung von
pathist: seine Einfachheit. Es funktioniert einfach in allen einigermaßen fähigen Browsern, ohne dass Polyfills oder andere Workarounds erforderlich sind, was ziemlich genial ist.Es gibt einen weiteren Vorteil der Verwendung von
usemit externen Sprites, der spezifisch für das Produkt ist, an dem ich arbeite, aber ich erwähne ihn trotzdem: Die Möglichkeit, einfach auf eine andere SVG-Datei zu verweisen, um alle Icons zu ändern, ohne die Anwendung neu kompilieren zu müssen. Unsere App hat für jeden Kunden ein anderes Thema, Logo & manchmal Icon-Set, daher ist es für uns sinnvoll, diese Dinge getrennt & "abstrahiert" zu halten, aber offensichtlich ist das keine Anforderung, die von vielen Produkten geteilt wird.Es scheint wirklich hauptsächlich eine Frage der persönlichen Präferenz für den Workflow und davon abzuhängen, wie eng Sie Ihre Icons & React-Komponenten koppeln möchten.
Hey diondiondion,
Sicher, Caching ist wahrscheinlich das stärkste Argument für `use`. Das ist definitiv eine gute Sache, die man erwähnen sollte. Ist es besser als nur ein paar Icons pro Ansicht inline laden zu müssen, die typischerweise jeweils >1kb kosten? Ich bin mir nicht sicher. Das, scheint es, würde völlig vom jeweiligen System abhängen.
Ihr Anwendungsfall klingt ziemlich interessant! Bei ansonsten gleichen Bedingungen ist ein Workflow und eine Abstraktion, die beim Laden eines komplett anderen Sets pro Kunde von Vorteil sind, absolut angebracht. Ich kann mir ein Szenario vorstellen, in dem Sie Komponenten für jeden Kunden bündeln könnten, aber das würde mehr Konfiguration erfordern, als sinnvoll wäre. In Ihrem Fall ist die Sprite-Sheet-Variante möglicherweise insgesamt wartungsärmer, daher stimme ich zu, dass dies die bessere Wahl wäre.
Ich liebe diesen Beitrag, Sarah!
Einer der Gründe, warum ich von SVG-Icons so begeistert bin, ist ihre Vielseitigkeit. Ich finde es großartig (und sehr gesund) für Entwickler, eine Fülle von Optionen zu haben ... clientseitig über
use, serverseitig (à la GitHubs neueste Iteration von Octicons) oder integriert in das JavaScript-Framework eines Projekts (wie Sie es so hilfreich detailliert haben). Selbst Projekte mit bescheidenen Icon-Anforderungen könnten mitimggut auskommen!Es ist leicht, bei *irgendeiner* dieser Lösungen aus dem einen oder anderen Grund Löcher zu finden. Beiträge wie dieser helfen Teams wie meinem, das Beste für ein bestimmtes Projekt zu ermitteln. SVG ist einfach zu komplex, leistungsfähig und *lustig*, um sich mit einer "Einheitslösung" zufriedenzugeben!
Danke, Tyler! Ich könnte nicht mehr zustimmen.
Ich denke, das ist es, was Sie beabsichtigt haben. Das
id-Attribut fehlte; ich bin ziemlich sicher, dass es erforderlich ist (https://www.paciellogroup.com/blog/2013/12/using-aria-enhance-svg-accessibility/)Oh, interessant. Danke, das wusste ich nicht. Aktualisiert.
Toller Artikel, aber der Barrierefreiheits-Teil ist gerade etwas verhunzt.
Sie verwenden
aria-labelledby, aber es ist nicht notwendig und Sie verwenden es auf fehlerhafte Weise: Sie verwenden einenid-Wert ("title") und React ändert ihn nicht für jede Verwendung der Komponente, so dass Sie doppelteids auf Ihrer Seite erhalten (wenn Sie diese Icon-Komponente mehr als einmal verwenden und/oder wenn Sie dieselbe ID in anderen Icon-Komponenten verwenden).Mein Rat: Entfernen Sie das
id-Attribut und dasaria-labelledby-Attribut ganz, da aktuelle Screenreader es nicht benötigen, um das<title>-Element für Inline-SVG zu lesen.Außerdem dient das Hinzufügen eines
<title>-Elements zu Ihrem SVG-Icon nicht der Barrierefreiheit. Ihre Icon-Komponente sollte zwei Dinge tun können:Das Icon komplett ausblenden, da die Bedeutung bereits im benachbarten Text erläutert wird. Das wäre:
<svg aria-hidden="true"><path /></svg>Zugänglichen Text für das Icon bereitstellen, *mit der Möglichkeit, diesen Text für jede Verwendung zu ändern und Internationalisierung zu ermöglichen*:
<svg><title>[Dieser Text darf nicht immer derselbe sein]</title></svg>.Dies kann geschehen, indem die Elemente
aria-hiddenund<title>bedingt ausgegeben werden, je nachdem, ob der Code, der die Komponente verwendet, zugänglichen Text bereitstellt oder nicht (kein zugänglicher Text bereitgestellt:aria-hidden="true").Als allgemeine Regel gilt: zugänglicher Text ist *keine* Beschreibung der Grafik, daher funktioniert "Schirmsymbol" nicht gut als *relevanter* zugänglicher Text. Er sollte stattdessen die Bedeutung zusammenfassen, die Sie vermitteln möchten. Wenn Sie zum Beispiel
<button><IconUmbrella/></button>haben, was ist die Rolle dieses Icon-Only-Buttons? Zeigt er eine Wettervorhersage an? Dann sollten Sie haben:<button aria-label="Wettervorhersage anzeigen"><IconUmbrella/></button>oder<button><IconUmbrella customthingforalttext="Wettervorhersage anzeigen" /></button>. Sie möchten, dass ein Screenreader "Wettervorhersage anzeigen, Schaltfläche" sagt, nicht "Schirmsymbol, Schaltfläche".Da Sie auch den Alt-Text aus dem *grafischen Element* entfernt haben, können Sie ihn bei Bedarf übersetzen oder ändern, wenn Sie dasselbe grafische Element an verschiedenen Stellen mit unterschiedlichen Bedeutungen verwenden. Sie möchten nicht, dass ein Screenreader "Schirmsymbol" liest, wenn Sie tatsächlich "Afficher les prévisions météo" vermitteln müssen.
Das meiste, was @fvsch sagt, ist wahr. Leider ist dies (noch) nicht der Fall
Deshalb verwenden die meisten Barrierefreiheits-orientierten SVG-Beispiele ein redundantes
aria-labelledby-Attribut. Der Wert dieses Attributs muss eine oder mehrere gültige ID-Referenzen zu anderen Elementen sein, und natürlich muss die ID jedes Elements auf der Seite eindeutig sein. Für ein Icon ohne sinnvollen Kind-Inhalt möchten Sie ihm normalerweise auch eine expliziterole="img"geben, damit der Browser es als einzelnes Blockelement behandelt und das Markup der Kinder ausblendet.Weitere Informationen zu den anderen Punkten
SVG 2 erlaubt es Ihnen, Internationalisierung in Ihren SVG-Code mit mehreren
<title>-Elementen zu integrieren, die durch ihrlang-Attribut unterschieden werden. Soweit ich weiß, ist dies jedoch noch in keinem Browser implementiert, daher müssen Autoren immer noch die richtige Sprachvariante selbst auswählen.Selbst wenn mehrsprachige SVG-Alternativtexte unterstützt würden, würde dies nicht das andere Problem lösen, das fvsch anspricht: Der richtige zugängliche Text für ein Icon hängt davon ab, wie dieses Icon auf der Seite verwendet wird. Wenn das Icon sich in einer Schaltfläche/einem Link befindet, ist es wichtiger, die Funktion dieses Elements zu beschreiben als das Icon selbst.
Danke euch beiden! Ich lerne hier eine Menge. Ok, hier ist, was ich tun werde: Ich habe den Codepen mit eindeutigen Props für den Titel und aria-labelledby aktualisiert und werde den Artikel ebenfalls aktualisieren. Ich werde diesen Kommentar-Thread wahrscheinlich bald schließen und dann einen neuen Artikel schreiben, der auf diesen zurückverweist, mit allem, was ich hier durch die Kommentare gelernt habe.
Ich schätze das Feedback sehr.
Amelia, weißt du, welche Screenreader das
aria-labelledby-Attribut benötigen, um das<title>-Element vorzulesen? In meinen Tests mit JAWS, NVDA und VoiceOver vom Herbst 2015 war es nicht notwendig? Vielleicht Windows-Eyes oder ZoomText, oder ältere Versionen von JAWS, NVDA oder VoiceOver?Da die
<title>-Unterstützung in meinen Tests für *Inline-SVG-Elemente* gut war (getrennte SVG-Dokumente sind eine andere Sache), vermeide ich es, zusätzlichesaria-labelledbyhinzuzufügen, das in der Praxis schnell falsche oder veraltete Werte erhält.Wenn man das zusätzliche
aria-labelledbyundidhinzufügen möchte, ist es wahrscheinlich besser, incomponentWillMounteine zufällige UUID zu generieren und diese zu verwenden, damit jede Instanz ein funktionierendesaria-labelledbyhat.Weiter so mit den React-Posts, Sarah! Dein Artikel 'Ich habe gelernt, wie ich in React in einer Woche produktiv werde und Sie können das auch' hat mich dazu gebracht, die Bibliothek zu lernen.
Danke, Marc! Freut mich, dass er nützlich war :)
Leute, lasst uns einen Schritt zurücktreten und wirklich sehen, was wir tun.
Wenn Sie die SVGs direkt auf der Seite rendern, sagen wir, serverseitig (wie GitHub, yay!), dann ja – es gibt möglicherweise nicht viel Unterschied. Der Browser ist möglicherweise effizienter, wenn er seine eigenen Dinge mit Shadow DOM und
<use>macht, oder er ist schneller, wenn die vollständigen SVGs bereits vorhanden sind. Ich wette, es ist effizienter mit<use>, weil er die Struktur des SVG als gleich erkennt und so die Wiederverwendung vorhandener Ressourcen für Parsen und Rendering ermöglicht. Aber lassen wir uns nicht ablenken...In diesem Artikel geht es darum, SVGs *mit React* zu verwenden, weshalb mein anderer Kommentar so begann:
Die Verwendung von JavaScript ist hier das Problem. React ist nur eine Möglichkeit, dies mit JavaScript zu tun. Und tatsächlich ist es eine besonders *schreckliche* Möglichkeit. Warum ist es eine schreckliche Möglichkeit?
Es ist eine schreckliche Möglichkeit, weil die Verwendung von React als eine Art SVG-Vorlagensystem sehr langsam ist, besonders bei komplexen SVGs! Hier habe ich schnell einen kleinen Test auf jsperf zusammengestellt: http://jsperf.com/react-icons-vs-use/2
Beachten Sie, wie die
<use>-Methode viel, viel schneller ist (wie 500% schneller). Das sollte keine Überraschung sein. Die<use>-Methode erstellt ein Element. Die vollständige SVG-Methode erstellt, nun ja, *viele*.Auch hier geht es nicht unbedingt um die Verwendung eines vollständigen SVG im Vergleich zur Verwendung von
<use>beim Schreiben von HTML – es geht einfach darum, *React* zu verwenden, um ein SVG zu erstellen. Das macht Sinn, wenn Sie hier und da ein stark angepasstes SVG benötigen (behandeln Sie es einfach wie eine Komponente, duh!), aber nicht, wenn es um die allgemeine Verwendung von SVG-Icons geht, unabhängig davon, ob Sie auch React verwenden oder nicht.Dies ist hauptsächlich eine Antwort auf diesen Teil des Artikels, der impliziert: "Hey, wenn Sie React verwenden, brauchen Sie
<use>nicht, verwenden Sie einfach React-Komponenten!"Entschuldigung, falls der Ton meiner Kommentare unhöflich wirkt. Er ist nicht so geschrieben, sondern einfach eine starke Erinnerung daran, dass
Nur weil man es *kann*, heißt das nicht, dass man es *sollte*.
:)
Tolle Tests, danke für Ihre harte Arbeit, die sind in der Tat interessant!
Ok, das ergibt viel mehr Sinn als das, was Sie mir vorher gesagt haben. Und es wirft einen anständigen und durchdachten Punkt auf.
Das ist sicherlich schneller. Aber hier habe ich eine Bedenken, und ich werde nur über meinen Anwendungsfall sprechen, damit Sie sehen, woher ich komme. Nehmen wir an, Sie verwalten eine riesige Website mit etwa 50 Icons. Nehmen wir an, Sie haben eine Ansicht, die nur 3 dieser Icons benötigt. Ich sehe hier einen Fall, in dem das Nicht-Laden aller 50 Icons, entweder in einer SVG-Spritesheet oder in einer Icon-Schriftart, von Vorteil wäre, und die Einsparungen könnten es lohnenswert machen.
Ich sehe auch einen Fall, in dem ich, wie oben, eine komplexere SVG habe, die ich ändern möchte, entweder mit Animation oder nur um Teile davon zu aktualisieren. Nehmen wir an, alle meine Ansichten sind in React. Ich denke, in diesem Fall könnte dieser Ansatz immer noch gut funktionieren.
Ihre Tests demonstrieren jedoch wirklich gut, warum wir es nicht so machen sollten. Ich denke, Sie machen hier einen großartigen und soliden Punkt.
Ich sehe es von beiden Seiten und würde immer noch sagen: Wählen Sie das richtige Werkzeug für den Job.
Sarah, ich glaube, wir sind uns ziemlich einig :)
Wie Sie sagten, wenn Sie eine spezielle SVG haben – keine "Feuer und vergessen"-Icons, die Hunderte von Male auf der Seite sein könnten – machen Sie sie auf jeden Fall zu einer Komponente. Das befürworte ich.
Was den anderen Anwendungsfall angeht
Ja, das könnte durchaus sinnvoll sein. Denken Sie daran, dass eine SVG-Spritesheet mit etwa 50 Icons nach GZIP-Komprimierung nur wenige Kilobytes groß sein könnte. Und mit Fingerprinting könnten Sie diese Spritesheet nur einmal mit einem Ablaufdatum in ferner Zukunft ausliefern. Der Browser würde sie im Grunde ewig cachen, oder bis Sie sie ändern (und somit der Dateiname sich ändert). Dann stellt sich die Frage: Was ist schneller, das serverseitige Rendern von vollständigen Inline-SVGs und das Parsen jedes einzelnen durch den Browser, oder die Verwendung einer einzelnen SVG, die der Browser bereits im Cache hat?
Auch hier gilt, wie Sie sagten: Verwenden Sie das richtige Werkzeug für den Job :)
Ich denke, Sie machen solide Punkte über das Caching, und wir könnten wahrscheinlich ewig darüber diskutieren, aber wenn Sie Ihre Seiten und Ansichten richtig cachen und gzippen, bin ich immer noch nicht überzeugt. Es ist schwer, eine 50-SVG-Spritesheet als nur wenige Kilobytes darzustellen, ohne auch zu erwähnen, dass ein typisches Inline-SVG-Icon, selbst wenn es mit React gerendert wird, wahrscheinlich weniger als 1 KB groß ist. Wenn Sie eine Website haben, die zwischen einer Suchansicht und einer Detailansicht wechselt, ohne normalerweise alle anderen Icons zu benötigen, bin ich mir immer noch nicht sicher :) Zu diesem Zeitpunkt debattieren wir vielleicht auch einen sehr geringen Leistungsunterschied.
@Sarah
Hier ist meine Frage zum Lazy Web. Gibt es Tools, die Sie empfehlen können, um die einzelnen Icon-Komponenten automatisch zu generieren (vorzugsweise mit Webpack)?
Ich habe es vermieden, mich seit einer Weile mit React zu beschäftigen, daher ist dieser Beitrag perfekt! Danke
https://github.com/morlay/svg-simplify
https://github.com/morlay/svg2jsx
Kürzlich habe ich gerade einen Weg gefunden, das zu tun.
Demo: https://github.com/morlay/svg2jsx/blob/master/examples/entry.js
svgo-loaderodersvg-simplifykönnten das SVG bereinigen, bevor Sie den Transformer verwenden.Für ein einfarbiges Icon ist die Verwendung einfach.
Aber für farbige Icons wie in diesem Beitrag gezeigt, müssen Sie möglicherweise Formen selbst zusammensetzen.
DAS IST GROSSARTIG…. :)
Tolle Infos!
Das ist der beste React-zentrierte Artikel, den ich bisher gelesen habe!
Das sage ich, weil ich ein Frontend-Entwickler bin, der an React interessiert ist, aber noch nicht viel damit herumgespielt hat. Auch wenn ich mein Icon-System nicht so einrichten werde, glaube ich, dass dieser Blogbeitrag sehr hoch rangiert, was die Vermittlung einiger grundlegender React-Konzepte angeht, die mich tatsächlich für React begeistern. Das Schreiben hat mir die Augen für die Bibliothek geöffnet ... Danke, Sarah ;)
Hey, bitte schauen Sie sich unseren React SVG Icon Live Generator https://react-svg-icon-live-generator.herokuapp.com/ an, den ein Kollege von mir erstellt hat. Jedes Feedback ist willkommen
Der oben erwähnte GitHub-Artikel hat eine Diskussion ausgelöst, in der unser Team ebenfalls die Verwendung von SVG in Betracht zieht.
Aus meinen ersten Tests ist die direkte SVG-Darstellung so viel besser als Icon-Schriftarten. Was ich in unserem Fall mache, ist einfach, das vollständige SVG auf der Seite einzubinden, ohne JavaScript. Wir verwenden einen "Include" in der von uns verwendeten Vorlagensprache (Jade), daher sehen wir syntaktisch nicht den vollständigen SVG-Code auf der Seite. Es sieht ein wenig so aus:
Ich bin damit zufrieden, denn wenn Sie ein 16x16 SVG aus Sketch exportieren und sicherstellen, dass es mit CSS als 16x16 Block gerendert wird, sind Sie sich 100% sicher, dass es scharf ist. Während Sie, wenn Sie ein 16x16 SVG exportieren und es dann durch einen Icon-Schriftarten-Generator verhunzen, nie wirklich sicher sind, dass es scharf ist.
Ich denke, ich und mein Team haben Stunden damit verbracht, Icon-Schriftarten zu beherrschen. Das reicht von der Fehlersuche bei der Ausgabe von Icon-Schriftarten über die Anleitung von Leuten, wie sie ihr System einrichten, um Fontforge/Fontcustom einzubinden, bis hin zum Optimieren von SVG-Code, um als Icon-Schriftart gut dargestellt zu werden. Ich hoffe, diese Probleme sind mit dieser neuen Lösung nun vorbei.
Einige Tipps: Am besten exportieren Sie Ihre SVG-Icons in einer bestimmten Größe und definieren diese explizit.
Sie können SVGs dann wie folgt mit CSS "färben":
Tolle Zusammenfassung, Sarah! Ich verwende einen ähnlichen Ansatz in einigen Rails-Projekten mit https://github.com/jamesmartin/inline_svg
Ich habe kürzlich ein SVG-Icon-System erstellt, das mit React und Plain JavaScript kompatibel sein musste (React wird für mehrere SPAs verwendet, die in Seiten eingebettet sind, es gibt auch älteren JS-Code). Ich habe den webpack-svgstore-plugin zum Erstellen des SVG-Bundles verwendet und es dann aus React wie folgt konsumiert:
<SvgSymbol name={‘icon-name-is-the-src-file-name’} />
oder von Serverseiten-Vorlagen (Jinja2-basiert) wie
{% svg_symbol(‘icon-name’) %}
Hilfs-Tags geben einfach <svg><use…>-Sachen aus und referenzieren das Icon wie "/path/to/bundle.svg#icon-name".
Dies kann leicht erweitert werden, um mehrere Bundles über einen optionalen Parameter bundle={‘bundle-name’} zu unterstützen.
Ein Problem bei der direkten Einbindung von SVGs in React und der Abhängigkeit von Webpack oder Ähnlichem, um sie in JS zu bündeln, ist, dass das resultierende Icon-System nur aus dem React-Land verwendbar ist. Ich sehe Vendor-Lock-in für etwas so Triviales als größeres Problem als die oben genannten Performance-Probleme.
Ich glaube, all meine Pure Components hatten ihre Gefühle verletzt, als Sie sie " *dumm* " nannten ;(
Hallo Sarah,
Danke für den Beitrag und die Diskussionen mit Agop.
Ein kleiner Punkt zu #a11y hier. Im beschriebenen Szenario bringen Sie mehrere SVG-Elemente ein, die alle ein title-Element mit der ID "title" enthalten.
Ich habe es gerade mit VoiceOver ausprobiert. Angenommen, Sie haben mehrere verschiedene Icons auf einer Seite wie diese eingebunden und alle enthalten
VoiceOver liest den Titel des ersten erscheinenden Icons für alle, da IDs nur einmal innerhalb eines Dokuments vorkommen dürfen. Das Setzen eindeutiger IDs ist dafür in Kombination mit
aria-labelledbyerforderlich, um richtig zu funktionieren.Danke. :)
Hallo Stephan,
Ja, wenn Sie in den Kommentaren und im Beitrag nachsehen, wurde dies alles behandelt und der Beitrag wurde aktualisiert. Ich kann jedoch alle anderen Codepens aktualisieren, um zukünftige Verwirrung zu vermeiden. Ich habe nur diejenige aktualisiert, die als Referenz für die Barrierefreiheit diente.
Danke für deine Aufmerksamkeit!
Hallo Sarah, danke für den Share