{"id":15380754,"url":"https://github.com/bitstarr/svg-workflow","last_synced_at":"2025-07-04T00:34:17.689Z","repository":{"id":79321770,"uuid":"86824911","full_name":"bitstarr/svg-workflow","owner":"bitstarr","description":"a bunch of code and text to show my SVG icon workflow in web projects","archived":false,"fork":false,"pushed_at":"2017-12-12T14:16:26.000Z","size":18,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-13T11:54:10.652Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bitstarr.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-03-31T13:57:52.000Z","updated_at":"2024-11-06T13:45:56.000Z","dependencies_parsed_at":"2023-07-07T05:00:59.728Z","dependency_job_id":null,"html_url":"https://github.com/bitstarr/svg-workflow","commit_stats":{"total_commits":6,"total_committers":3,"mean_commits":2.0,"dds":"0.33333333333333337","last_synced_commit":"e3ceef95db84751c3cdb6168ba7b88d864b74324"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bitstarr/svg-workflow","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitstarr%2Fsvg-workflow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitstarr%2Fsvg-workflow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitstarr%2Fsvg-workflow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitstarr%2Fsvg-workflow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bitstarr","download_url":"https://codeload.github.com/bitstarr/svg-workflow/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitstarr%2Fsvg-workflow/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263426379,"owners_count":23464795,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-01T14:24:31.674Z","updated_at":"2025-07-04T00:34:17.657Z","avatar_url":"https://github.com/bitstarr.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SVG Icon Workflow\n\n## Icons lagern und verarbeiten\nWenn ich nicht gezwungen bin Icons selbst zu gestalten (oder gestalten zu lassen), greife ich auf einige Projekte zurück.\n\n* [Nova Icons](http://www.webalys.com/nova/) habe ich vor einer Weile mal günstig geschossen. Umfangreich, und simpel im Stil.\n* [Geomicons](https://github.com/jxnblk/geomicons-open) ist eine Sammlung von simplen SVG-Icons die wenige Pfadpunkte besitzen und so den Traffic klein halten.\n* [Bytesize Icons](https://github.com/danklammer/bytesize-icons) ist ähnlich wie Geomicons, nur mit einem anderen Stil.\n* Icons von [FontAwesome](https://github.com/FortAwesome/Font-Awesome) verwende ich immer als letzte Wahl, da dieses aktuell Set quasi der Standard im Web ist. Ich bin als Backer der Kickstarter-Kampagne sehr gespannt auf Font Awesome 5 (Pro).\n\nWenn ich das richtige Icon gefunden habe, erzeuge ich im Illustrator eine neue Datei mit den Maßen 128×128 Pixel und platziere das Icon. Ich stelle die Farbe des Icons (oder von einzelnen Teilen) auf schwarz (#000 - das ist später noch wichtig) und speichere es.\n\nDabei verwende ich in meinen Projekten eine Ordnerstruktur wie die Folgende.\n\n````\n.\n+-- assets/                 Arbeitsdateien\n|   +-- icons/                  SVG Icons\n|   +-- img/                    Bilder\n|   +-- js/                     Magic\n|   +-- less/                   Styling\n+-- dist/                   Build Dateien\n|   +-- css/                    Kompilierte CSS Dateien\n|   +-- img/                    Optimierte Bilder\n|   +-- js/                     JS Dateien und Polyfills\n|   +-- sprite/                 SVG Sprite und Übersicht\n````\n\nFür Viele ist es sicher gängige Praxis optimierte und kompilierte Ressourcen in einem ``dist`` Ordner zu lagern und den ``assets`` Ordner nicht auf den Live-Server zu kopieren.\n\nDas Icon wird von ``Grunt`` mittels [grunt-svg-sprite](https://github.com/jkphl/grunt-svg-sprite) ins Sprite integriert und das Sprite anschließend mit [grunt-svgmin](https://github.com/sindresorhus/grunt-svgmin) optimiert.\n\n``grunt-svg-sprite`` erzeugt auch eine [HTML-Datei](http://svg.sebastianlaube.de/dist/sprite/sprite.html) in der z.B. Redakteure die IDs nachschlagen können. Die Vorlage dazu liegt in ``assets/icons``.\n\nAußerdem wird an dem selben Ort auch eine PHP-Datei erzeugt, die einen Array enthält. Den nutzen wir um zu prüfen, ob eine übergebene ID (Icon-Datei-Name) auch wirklich im Sprite zu finden sein wird.\n\n## Der Code\n````php\nfunction get_svg_icon( $id, $atts = array() ) {\n    // 1. do we have the reuired parameter?\n    if ( empty( $id ) ) {\n        if ( WP_DEBUG == true ) {\n            return 'Icon ID fehlt.';\n        }\n\n        return;\n    }\n\n    // 2. get some attributes\n    extract( shortcode_atts(\n        array(\n            'class' =\u003e null,\n            'title' =\u003e null\n            // maybe we want to add desc (\u003cdesc\u003e) for even more a11y\n        ),\n        $atts\n    ));\n\n    // 3. check if this ID will be in the sprite\n    require TEMPLATEPATH . '/dist/sprite/sprite.php';\n    if ( ! in_array( $id, $valid_icons ) ) {\n        if ( WP_DEBUG == true ) {\n            return 'Icon nicht vorhanden.';\n        }\n\n        return;\n    }\n\n    // 4. will we add extra CSS classes?\n    $att_class = ( empty( $class ) ) ? '' : ' ' . $class;\n\n    // 5. create a unique ID\n    $att_id = uniqid( 'icon__title--' );\n\n    // 6. additional markup attributes for a11y\n    // is this icon only decorative (hidden) or descriptive (title)\n    $att_a11y = ( empty( $title ) ) ? ' aria-hidden=\"true\" role=\"presentation\"' : ' aria-labelledby=\"' . $att_id . '\" role=\"img\"';\n    $title = ( empty( $title ) ) ? '' : '\u003ctitle id=\"' . $att_id . '\"\u003e' . $title . '\u003c/title\u003e';\n\n    // 7. puzzle the URL together\n    $url = get_template_directory_uri() . '/dist/sprite/sprite.svg#' . $id;\n\n    // 8. let's roll!\n    return '\u003csvg class=\"icon' . $att_class . '\"' . $att_a11y . '\u003e' . $title . '\u003cuse xlink:href=\"' . $url . '\"\u003e\u003c/use\u003e\u003c/svg\u003e';\n}\n\nfunction svg_icon( $id, $atts = array() ) {\n    echo get_svg_icon( $id, $atts );\n}\n````\n\nWie sich für ein geübtes Auge sofort erkennen lässt, befinden wir uns im Kontext von WordPress. Prinzipiell lässt sich das aber auch ohne WordPress machen, dazu ändert man die Verarbeitung der Attribute, die Konstanten und  die Erzeugung der URL.\n\n1. Prüfen, ob eine ID übergeben wurde. Wenn nicht brechen wir ab.\n2. Extrahieren die Attribute\n3. Prüfen, ob es ein Icon mit der ID gibt. Wenn nicht brechen wir ab.\n4. Extra CSS-Klassen vorbereiten\n5. Vorsorglich eine eindeutige ID erzeugen\n6. Ist ein Titel in den Attributen definiert, wird dieser dem SVG hinzugefügt und als Label referenziert (für Screenreader/Tooltip). Andernfalls wird das SVG als dekorativ gekennzeichnet.\n7. Die URL setzt sich auf der URL des Theme-Ordners, dem Pfad zum Sprite und der ID zusammen.\n8. Zum Schluss wird alles zusammengefügt und übergeben.\n\nVerwendet wird das Ganze dann recht simpel:\n````html\n    \u003cdiv class=\"contact\"\u003e\n        \u003c?php svg_icon( 'phone', array( 'title' =\u003e 'Telefon' ) ) ?\u003e 0123 456 78 90\n\n        \u003c?php svg_icon( 'mail', array( 'title' =\u003e 'E-Mail', 'class' =\u003e 'icon--blue' ) ) ?\u003e foo@bar.foo\n    \u003c/div\u003e\n\n````\n\nAlternativ geht das auch als WordPress-Shortcode\n````\n    [icon phone title=\"Telefon\"] 0123 456 78 90\n````\n\nDie Ausgabe sieht dann etwa so aus:\n````html\n    \u003csvg class=\"icon\" aria-labelledby=\"icon__title--58de43ac12ead\" role=\"img\"\u003e\n        \u003ctitle id=\"icon__title--58de43ac12ead\"\u003eTelefon\u003c/title\u003e\n        \u003cuse xlink:href=\"http://foo.bar/wp-content/themes/mytheme/dist/sprite/sprite.svg#phone\"\u003e\u003c/use\u003e\n    \u003c/svg\u003e\n````\n\nModerne Browser unterstützen die Referenzierung einer SVG-Datei via ``xlink:href`` und es ist nicht nötig das Sprite irgendwo im Dokument zu \u003cq\u003eincluden\u003c/q\u003e (ideal fürs Caching). …Außer beim Problemkind von Microsoft (IE 9+), hier wird der Polyfill [svgxuse](https://github.com/Keyamoon/svgxuse) benötigt. Der Polyfill holt sich das Sprite, schreibt es in den DOM und löscht den URL-Teil aus den ``\u003cuse\u003e``-Tags.\n\n## Styling\nJetzt haben wir zwar die Icons elegant eingebunden, aber sie müssen noch elegant gestylt werden.\n\n````css\n/* 1 */\n.icon {\n    fill: currentColor;\n    height: 1em;\n    width: 1em;\n    overflow: hidden;\n    vertical-align: -.15em;\n    /* vertical align to deal with the line height of the text */\n}\n\n/* 2 */\n.icon--blue {\n    color:#07f;\n}\n/* 3 */\n.icon--logo rect {\n    fill: rebeccapurple;\n}\n````\n\nIst bei einem SVG-Element kein ``fill``-Attribut gesetzt, verwendet der Browser Schwarz als Fallback. ``imagemin`` entfernt das ``fill``-Attribut, wenn es als Schwarz (``#000`` oder ``#000000``) definiert ist aus diesem Grund. \n\nDas machen wir uns nun zu nutze und sagen dem Icon es soll die Schriftfarbe (``color``) des Elternelements nutzen (1).\n\nWollen wir es einfärben, können wir es direkt ansprechen und eine Farbe definieren (2). Obwohl die SVG-Grafik nur mit einer URL referenziert ist, können wir die darin enthaltenen Elemente auch via CSS ansprechen, als wäre es fester Teil des DOM (3).\n\nDie Icons sind quadratisch angelegt. Wenn man aber z. B. ein Logo mit speziellem Seitenverhältnis einbinden möchte, regelt man das am Besten über die zusätzliche CSS Klasse. Gegebenenfalls könnte man die ``get_svg_icon``-Funktion manipulieren um bei bestimmten IDs automatisch eine bestimmte Klasse mit einzufügen.\n\nDas Endergebnis gibts natürlich auch als [Demo](http://svg.sebastianlaube.de).\n\nIch freue mich auf Feedback. Wer Rechtschreibfehler findet, kann sie behalten.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitstarr%2Fsvg-workflow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbitstarr%2Fsvg-workflow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitstarr%2Fsvg-workflow/lists"}