SVG Symbol
Alternatif untuk font-based icons — menggunakan SVG symbol sprites untuk menyematkan ikon scalable, multi-warna langsung di HTML.
Apa Itu SVG Symbol Sprites?
SVG symbol sprites menggabungkan beberapa ikon SVG menjadi satu file. Setiap ikon didefinisikan di dalam elemen <symbol> dengan id yang unik. Untuk menggunakan ikon, Anda mereferensikannya dengan <use href="#icon-id">. Sprite dimuat satu kali — inline atau sebagai file eksternal — dan ikon individual dirender di mana saja di halaman.
Ini adalah pendekatan yang berbeda secara fundamental dari icon fonts. Alih-alih memetakan Unicode code points ke font glyphs, Anda menggunakan elemen SVG asli. Setiap ikon mempertahankan kemampuan SVG penuh: berbagai warna, gradien, filter, dan atribut aksesibilitas yang terperinci. Komprominya adalah markup dan konvensi penataan yang sedikit lebih kompleks dibandingkan pendekatan CSS murni dari font icons.
Cara Kerjanya
File sprite adalah dokumen SVG biasa yang berisi satu atau lebih elemen <symbol>. Setiap symbol mendefinisikan ikon yang mandiri dengan viewBox-nya sendiri:
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
<symbol id="icon-home" viewBox="0 0 24 24">
<path d="M3 12l9-9 9 9M5 10v10a1 1 0 001 1h3a1 1 0 001-1v-4..."/>
</symbol>
<symbol id="icon-search" viewBox="0 0 24 24">
<path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
</symbol>
</svg>
<svg> luar disembunyikan dengan style="display:none" sehingga tidak memakan ruang di halaman. Symbol di dalamnya tidak terlihat hingga direferensikan. Untuk merender ikon, gunakan elemen <use>:
<svg class="icon"><use href="#icon-home"></use></svg>
<svg class="icon"><use href="#icon-search"></use></svg>
Beri gaya ikon dengan CSS, menggunakan fill dan stroke alih-alih properti color berbasis font:
.icon {
width: 24px;
height: 24px;
fill: currentColor;
stroke: none;
}
Menggunakan fill: currentColor membuat ikon mewarisi warna teks elemen induknya, mirip dengan cara font icons bekerja dengan properti color.
Symbol vs Font Icons
- Dukungan multi-warna — setiap path dapat memiliki fill dan stroke sendiri
- Setiap ikon adalah elemen SVG nyata dengan aksesibilitas lebih baik
- Tidak perlu pemetaan Unicode — referensikan ikon dengan nama yang dapat dibaca
- Rendering lebih tajam — tidak ada masalah font hinting atau subpixel artifacts
- Bagian ikon individual dapat dianimasikan secara independen
- Bekerja dengan fitur SVG apapun: gradien, filter, clip-path, mask
- Markup lebih verbose (
<svg><use>vs<i class="icon">) - Tidak mudah diberi gaya dengan CSS
color— memerlukanfill/stroke - External sprites memiliki implikasi CORS untuk pemuatan cross-origin
- Total ukuran file lebih besar dari format font terkompresi
- Lebih banyak HTML per penggunaan ikon
- Tidak ada dukungan pseudo-element
::before/::after
Strategi Pemuatan
Ada tiga cara utama untuk memuat SVG symbol sprite ke halaman, masing-masing dengan kompromi yang berbeda:
Inline sprite
Tempelkan seluruh sprite SVG langsung ke dalam <body> HTML. Ini adalah pendekatan paling sederhana — tidak ada masalah CORS, tidak ada permintaan HTTP ekstra. Symbol tersedia segera untuk referensi <use> apapun di halaman. Bekerja paling baik untuk single-page applications atau ketika Anda memiliki set ikon kecil (di bawah ~50 ikon).
External sprite
Muat sprite sebagai file eksternal melalui <use href="icons.svg#home">. Ini menjaga HTML tetap bersih dan membiarkan browser meng-cache sprite secara terpisah dari halaman. Namun, ini memiliki implikasi CORS: sprite harus disajikan dari origin yang sama, atau server harus menetapkan header Access-Control-Allow-Origin yang sesuai. Perlu diperhatikan bahwa Internet Explorer tidak mendukung referensi <use> eksternal — gunakan polyfill svg4everybody jika Anda memerlukan dukungan IE.
JS injection
Muat file sprite melalui fetch() dan inject ke DOM saat runtime. Ini menggabungkan kemampuan cache external sprites dengan keandalan inline sprites — SVG yang diinjeksi menjadi bagian dari dokumen, sehingga referensi <use> bekerja tanpa batasan CORS. Bobcorn menghasilkan pendekatan ini: file JS yang mengambil dan mendaftarkan semua symbol saat dimuat.
<!-- Load the generated JS sprite -->
<script src="icons-symbol.js"></script>
<!-- Then use normally: -->
<svg class="icon"><use href="#icon-home"></use></svg>
<svg class="icon"><use href="#icon-search"></use></svg>
File JS membuat elemen <svg> tersembunyi yang berisi semua definisi <symbol> dan menambahkannya ke document body. Setelah dimuat, ikon direferensikan secara identik dengan pendekatan inline.
Kapan Menggunakan SVG Symbols
SVG symbol sprites adalah pilihan yang tepat ketika proyek Anda memerlukan kemampuan yang tidak bisa disediakan font icons:
- Ikon multi-warna — ketika ikon menggunakan lebih dari satu warna, gradien, atau isian kompleks yang tidak bisa direpresentasikan oleh satu glyph font
- Aksesibilitas adalah prioritas utama — setiap ikon dapat menyertakan elemen
<title>dan atributaria-label, memberikan deskripsi bermakna kepada pembaca layar - Bagian ikon yang dianimasikan — Anda perlu menganimasikan path atau grup individual dalam ikon
- Proyek SVG berat — aplikasi Anda sudah menggunakan inline SVG secara ekstensif, sehingga symbol cocok secara alami ke dalam arsitektur yang ada
- Ketajaman rendering maksimal — font hinting dapat menyebabkan masalah perataan pada ukuran kecil; SVG symbols merender sempurna di dimensi apapun
Kapan Tetap Menggunakan Font Icons
Font icons tetap menjadi pilihan yang lebih baik dalam beberapa skenario umum:
- Set ikon besar (200+) — file font WOFF2 terkompresi jauh lebih kecil dari SVG sprite dengan jumlah ikon yang sama
- Semua ikon satu warna — jika setiap ikon satu warna, font icons memberikan integrasi paling sederhana tanpa kompromi
- Integrasi hanya CSS — font icons hanya memerlukan tautan stylesheet dan CSS classes, tanpa JavaScript atau markup ekstra
- Sistem lama — proyek yang sudah menggunakan icon fonts tidak mendapatkan manfaat cukup dari peralihan untuk membenarkan upaya migrasi
- Dukungan pseudo-element — Anda memerlukan ikon di pseudo-elements
::beforeatau::after, yang hanya berfungsi dengan font glyphs