SVG Symbol

Giải pháp thay thế cho font-based icons — sử dụng SVG symbol sprites để nhúng các biểu tượng có thể mở rộng, đa màu trực tiếp vào HTML.

SVG Symbol Sprites Là Gì?

SVG symbol sprites gộp nhiều icon SVG vào một tệp duy nhất. Mỗi biểu tượng được định nghĩa bên trong phần tử <symbol> với id duy nhất. Để sử dụng biểu tượng, bạn tham chiếu nó bằng <use href="#icon-id">. Sprite được tải một lần — inline hoặc dưới dạng tệp ngoài — và các biểu tượng riêng lẻ được hiển thị ở bất kỳ đâu trên trang.

Đây là cách tiếp cận khác về cơ bản so với icon fonts. Thay vì ánh xạ Unicode code points tới font glyphs, bạn đang sử dụng các phần tử SVG gốc. Mỗi biểu tượng giữ lại đầy đủ khả năng SVG: nhiều màu, gradient, filter và các thuộc tính accessibility chi tiết. Sự đánh đổi là markup và styling conventions phức tạp hơn một chút so với cách tiếp cận CSS thuần túy của font icons.

Cách Hoạt Động

Tệp sprite là tài liệu SVG thông thường chứa một hoặc nhiều phần tử <symbol>. Mỗi symbol định nghĩa một biểu tượng tự chứa với viewBox riêng:

icons.svg (tệp sprite)
<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> ngoài được ẩn với style="display:none" để không chiếm không gian trên trang. Các symbol bên trong vô hình cho đến khi được tham chiếu. Để hiển thị biểu tượng, sử dụng phần tử <use>:

Sử dụng symbols trong HTML
<svg class="icon"><use href="#icon-home"></use></svg>
<svg class="icon"><use href="#icon-search"></use></svg>

Tạo kiểu biểu tượng bằng CSS, sử dụng fillstroke thay vì thuộc tính color dựa trên font:

CSS cho SVG icons
.icon {
  width: 24px;
  height: 24px;
  fill: currentColor;
  stroke: none;
}

Sử dụng fill: currentColor cho phép biểu tượng kế thừa màu văn bản của phần tử cha, tương tự như cách font icons hoạt động với thuộc tính color.

Symbol vs Font Icons

    Ưu điểm của Symbols
  • Hỗ trợ đa màu — mỗi đường có thể có màu tô và stroke riêng
  • Mỗi biểu tượng là SVG element thực với accessibility tốt hơn
  • Không cần ánh xạ Unicode — tham chiếu biểu tượng bằng tên đọc được
  • Hiển thị sắc nét hơn — không có vấn đề font hinting hay subpixel artifacts
  • Các phần biểu tượng riêng lẻ có thể được tạo hoạt ảnh độc lập
  • Hoạt động với bất kỳ tính năng SVG nào: gradient, filter, clip-path, mask
    Nhược điểm của Symbols
  • Markup nhiều hơn (<svg><use> so với <i class="icon">)
  • Khó tạo kiểu với CSS color — cần fill/stroke
  • External sprites có hàm ý CORS khi tải từ cross-origin
  • Tổng kích thước tệp lớn hơn các định dạng font nén
  • Nhiều HTML hơn mỗi lần sử dụng biểu tượng
  • Không hỗ trợ pseudo-element ::before/::after

Chiến Lược Tải

Có ba cách chính để tải SVG symbol sprite vào trang, mỗi cách có sự đánh đổi khác nhau:

Inline sprite

Dán toàn bộ sprite SVG trực tiếp vào <body> HTML. Đây là cách tiếp cận đơn giản nhất — không có vấn đề CORS, không có yêu cầu HTTP thêm. Các symbol sẵn sàng ngay lập tức cho bất kỳ tham chiếu <use> nào trên trang. Hoạt động tốt nhất cho single-page applications hoặc khi bạn có bộ biểu tượng nhỏ (dưới ~50 biểu tượng).

External sprite

Tải sprite dưới dạng tệp ngoài qua <use href="icons.svg#home">. Điều này giữ HTML sạch và cho phép trình duyệt cache sprite riêng với trang. Tuy nhiên, nó có hàm ý CORS: sprite phải được phục vụ từ cùng origin, hoặc máy chủ phải đặt header Access-Control-Allow-Origin phù hợp. Lưu ý rằng Internet Explorer không hỗ trợ tham chiếu <use> ngoài — sử dụng polyfill svg4everybody nếu cần hỗ trợ IE.

JS injection

Tải tệp sprite qua fetch() và inject vào DOM ở runtime. Điều này kết hợp khả năng cache của external sprites với độ tin cậy của inline sprites — SVG được inject trở thành một phần của document, vì vậy các tham chiếu <use> hoạt động mà không có hạn chế CORS. Bobcorn tạo ra cách tiếp cận này: một tệp JS tải và đăng ký tất cả symbol khi tải.

Phương pháp JS injection (output của Bobcorn)
<!-- 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>

Tệp JS tạo một phần tử <svg> ẩn chứa tất cả các định nghĩa <symbol> và thêm nó vào document body. Sau khi tải, các biểu tượng được tham chiếu giống hệt cách inline.

Khi Nào Sử Dụng SVG Symbols

SVG symbol sprites là lựa chọn đúng khi dự án của bạn cần khả năng mà font icons không thể cung cấp:

  • Biểu tượng đa màu — khi biểu tượng sử dụng nhiều hơn một màu, gradient hoặc các màu tô phức tạp mà font glyph đơn không thể biểu diễn
  • Accessibility là ưu tiên hàng đầu — mỗi biểu tượng có thể bao gồm phần tử <title> và thuộc tính aria-label, cung cấp mô tả có ý nghĩa cho trình đọc màn hình
  • Phần biểu tượng có hoạt ảnh — bạn cần tạo hoạt ảnh cho các đường hoặc nhóm riêng lẻ trong biểu tượng
  • Dự án SVG nặng — ứng dụng của bạn đã sử dụng inline SVG rộng rãi, vì vậy symbols phù hợp tự nhiên với kiến trúc hiện có
  • Độ sắc nét hiển thị tối đa — font hinting có thể gây ra vấn đề căn chỉnh ở kích thước nhỏ; SVG symbols hiển thị hoàn hảo ở mọi kích thước

Khi Nào Nên Giữ Font Icons

Font icons vẫn là lựa chọn tốt hơn trong một số tình huống phổ biến:

  • Bộ biểu tượng lớn (200+) — tệp font WOFF2 nén nhỏ hơn đáng kể so với SVG sprite với cùng số lượng biểu tượng
  • Tất cả biểu tượng màu đơn — nếu mọi biểu tượng là một màu, font icons cho bạn tích hợp đơn giản nhất mà không có sự đánh đổi
  • Tích hợp chỉ CSS — font icons chỉ yêu cầu liên kết stylesheet và CSS classes, không cần JavaScript hay markup thêm
  • Hệ thống cũ — các dự án đã sử dụng icon fonts không đạt được đủ lợi ích từ việc chuyển đổi để biện minh cho nỗ lực migration
  • Hỗ trợ pseudo-element — bạn cần biểu tượng trong pseudo-elements ::before hoặc ::after, chỉ hoạt động với font glyphs
Trong Bobcorn
Bobcorn có thể xuất biểu tượng của bạn dưới dạng tệp JS symbol sprite cùng với các tệp font. Bật tùy chọn JS trong hộp thoại xuất. Tệp được tạo sẽ tạo inline SVG sprite và đăng ký tất cả symbol khi tải. Bạn có thể sử dụng cả hai cách tiếp cận trong cùng một dự án — fonts cho UI icons đơn giản, symbols cho illustrations màu phức tạp.
Mẹo
Bạn không phải chọn một hay cái kia. Nhiều hệ thống thiết kế sử dụng font icons cho phần lớn UI icons màu đơn (nút, điều hướng, form) và SVG symbols cho một số illustrations đa màu hoặc biểu tượng có hoạt ảnh. Hộp thoại xuất của Bobcorn cho phép bạn tạo cả hai trong một lần xuất duy nhất.