Gộp bộ icon SVG thành một file sprite symbol sạch, không trùng id
Khi website dùng vài chục đến vài trăm icon, nhúng từng file SVG riêng lẻ vừa tốn request vừa khó quản lý. SVG Sprite Generator gộp nhiều file SVG thành một sprite dùng thẻ symbol, giữ đúng viewBox của từng icon, tự làm sạch mã có thể chạy script, đổi tên id nội bộ để các icon không giẫm lên nhau, và xuất sprite.svg kèm mã use để gọi icon cùng trang xem trước toàn bộ bộ icon.
Tính năng nổi bật
- Thêm icon bằng cách chọn nhiều file SVG cùng lúc hoặc dán nhiều thẻ svg liền nhau, xử lý được hàng trăm icon mà trang không bị đơ
- Làm sạch bảo mật: xóa script, foreignObject, iframe, thuộc tính sự kiện on*, liên kết javascript:, href và url() trỏ ra ngoài
- Mỗi icon thành một thẻ symbol có id riêng, giữ nguyên viewBox, tự tính viewBox từ width/height (px, pt, mm, cm, in) khi file thiếu
- Đổi tên mọi id bên trong icon theo dạng id-icon-id-cũ và sửa lại tham chiếu url(#...), href="#...", aria-labelledby để không trùng giữa các icon
- Chuyển CSS trong thẻ style (hay gặp ở file xuất từ Illustrator) thành style nội tuyến, tránh CSS của icon áp lên cả trang
- Tùy chọn đổi fill và stroke sang currentColor để icon đổi màu theo chữ, có cảnh báo khi icon nhiều màu
- Đặt tiền tố id, sửa id từng icon, xem cảnh báo và lỗi của từng file
- Tải sprite.svg, trang xem trước HTML có lưới toàn bộ icon, chép sprite nhúng và mã <svg><use href="#id"/></svg>
Vì sao dùng SVG sprite thay vì từng file icon riêng
Mỗi icon là một file riêng nghĩa là mỗi icon một request, hoặc phải dán nguyên mã SVG dài vào từng chỗ trong HTML khiến mã trang phình to và khó sửa. Sprite gom toàn bộ icon vào một file, mỗi icon nằm trong một thẻ symbol có id; chỗ nào cần icon chỉ cần một thẻ svg ngắn với use href trỏ tới id đó. Icon vẫn là vector nên sắc nét ở mọi kích thước, đổi màu được bằng CSS khi dùng currentColor, và cả bộ icon được trình duyệt cache một lần. Cái khó là gộp tay dễ sai: hai icon cùng có gradient id="a" sẽ dùng nhầm gradient của nhau, file thiếu viewBox sẽ hiển thị sai tỷ lệ, còn file SVG tải từ nguồn lạ có thể chứa script. Công cụ này làm các bước đó tự động và báo rõ những gì đã thay đổi.
Lợi ích khi sử dụng
- Một file cho cả bộ icon, trình duyệt tải và cache một lần
- HTML gọn hơn vì mỗi chỗ dùng icon chỉ còn một dòng use
- Loại bỏ mã nguy hiểm trong file SVG tải từ nguồn bên ngoài trước khi đưa lên website
- Không còn lỗi gradient, clipPath dùng nhầm của icon khác do trùng id
- Có trang xem trước HTML để gửi đồng đội hoặc khách hàng duyệt cả bộ icon
Cách tạo SVG sprite từ nhiều icon
- 1Bấm chọn file và chọn một hoặc nhiều file .svg, hoặc dán mã của nhiều thẻ svg vào ô dán rồi bấm Thêm từ ô dán.
- 2Đặt tiền tố id (mặc định icon-), id của mỗi icon sẽ là tiền tố cộng tên file đã bỏ dấu, ví dụ Mũi tên phải.svg thành icon-mui-ten-phai.
- 3Chọn giữ màu gốc hoặc đổi fill/stroke sang currentColor nếu muốn icon lấy màu theo chữ xung quanh.
- 4Xem lưới xem trước, mở Danh sách chi tiết để sửa id từng icon, đọc cảnh báo và xử lý các file bị lỗi.
- 5Bấm Tải sprite.svg để lấy file sprite, hoặc Chép sprite nhúng HTML để dán thẳng vào đầu thẻ body.
- 6Chọn một icon để lấy mã use tương ứng, dán vào chỗ cần hiển thị icon, thêm CSS gợi ý để icon có kích thước và màu đúng.
Sprite symbol hoạt động như thế nào
File sprite là một thẻ svg chứa nhiều thẻ symbol. Symbol giống một khuôn mẫu: nó không tự hiển thị, chỉ hiện ra khi được gọi bằng thẻ use. Mỗi symbol mang viewBox riêng của icon gốc, nên khi bạn đặt thẻ svg bên ngoài rộng 24 px hay 64 px, icon tự co giãn đúng tỷ lệ. Nếu sprite được nhúng ngay trong trang HTML, thẻ use trỏ tới id bằng dấu thăng, ví dụ href="#icon-home". Nếu sprite là một file riêng, thẻ use trỏ tới đường dẫn file kèm id, ví dụ href="/sprite.svg#icon-home". Bản nhúng HTML do công cụ xuất ra được ẩn bằng kích thước 0 và overflow hidden thay vì display:none, vì display:none có thể làm gradient, mask và clipPath bên trong symbol không hiển thị ở một số trình duyệt.
Công cụ làm sạch những gì trong file SVG
SVG là định dạng văn bản có thể chứa mã chạy được, nên file tải từ nguồn không rõ có thể gây lỗi bảo mật khi dán thẳng vào trang. Công cụ đọc từng file bằng trình phân tích XML của trình duyệt rồi xóa thẻ script, foreignObject (có thể chứa HTML tùy ý), iframe, embed, object, xóa mọi thuộc tính bắt đầu bằng on như onload, onclick, xóa giá trị chứa javascript:, xóa thẻ set hoặc animate nhằm đổi thuộc tính sự kiện hay đường dẫn. Liên kết ra ngoài cũng bị bỏ: href của use hay image trỏ tới địa chỉ khác, url() trong thuộc tính và style trỏ ra ngoài. Riêng ảnh nhúng dạng data:image PNG, JPEG, GIF, WebP được giữ lại. Thẻ a được gỡ nhưng giữ nội dung bên trong. Metadata và phần tử riêng của Inkscape, Illustrator, Sketch cũng bị bỏ cho gọn. Mọi thay đổi được liệt kê trong phần cảnh báo của từng icon.
Vì sao phải đổi tên id bên trong icon
Trong một trang HTML, id phải là duy nhất. Nhiều công cụ thiết kế đặt id rất ngắn và giống nhau như a, b, clip0, paint0_linear, nên khi gộp hai icon cùng dùng gradient id="paint0_linear" vào một sprite, trình duyệt chỉ nhận định nghĩa đầu tiên và icon thứ hai sẽ hiện sai màu. Công cụ đổi mọi id bên trong icon thành id của symbol nối với id cũ, ví dụ icon-home-paint0_linear, rồi sửa lại toàn bộ chỗ tham chiếu: url(#...) trong fill, stroke, clip-path, mask, filter, trong style nội tuyến, href="#..." của use, và danh sách id trong aria-labelledby, aria-describedby. Bộ kiểm thử của công cụ gộp 250 icon có cùng id nội bộ và xác nhận không còn id nào bị trùng trong sprite.
Chuyển thẻ style thành style nội tuyến
File SVG xuất từ Illustrator thường khai báo màu qua thẻ style với các class như cls-1, cls-2. Nếu giữ nguyên thẻ style trong sprite nhúng vào trang, các quy tắc CSS đó áp lên toàn bộ trang, và icon này có thể đổi màu icon khác chỉ vì cùng tên class. Công cụ đọc các quy tắc CSS, tìm phần tử khớp với từng bộ chọn và ghi khai báo vào thuộc tính style của phần tử đó, style nội tuyến sẵn có vẫn được ưu tiên. Sau đó thẻ style và thuộc tính class được bỏ đi. Các khối @media, @font-face, @keyframes và @import bị bỏ qua vì không thể chuyển thành style nội tuyến; công cụ báo lại khi gặp chúng. Thứ tự ưu tiên theo độ cụ thể của bộ chọn không được tính lại đầy đủ, nên với CSS phức tạp hãy xem kỹ phần xem trước.
currentColor: icon đổi màu theo chữ
Khi chọn đổi sang currentColor, mọi giá trị màu của fill và stroke, trong thuộc tính lẫn trong style, được thay bằng currentColor. Các giá trị none, url(#gradient), inherit, transparent được giữ nguyên, nên icon dạng nét có fill="none" vẫn giữ phần rỗng. Khi dùng, icon sẽ lấy màu từ thuộc tính color của CSS ở phần tử chứa nó, ví dụ nút màu trắng thì icon trắng, liên kết khi rê chuột đổi màu thì icon đổi theo. Những icon không khai báo màu nào sẽ lấy fill từ thẻ svg bên ngoài, vì vậy CSS gợi ý có dòng fill: currentColor. Icon nhiều màu sẽ bị gộp thành một màu, công cụ cảnh báo khi phát hiện icon có từ hai màu trở lên để bạn cân nhắc giữ màu gốc.
Sprite nhúng trong trang hay file riêng
Sprite nhúng ngay đầu thẻ body hoạt động ở mọi trình duyệt hiện đại, không cần thêm request, nhưng làm HTML của mọi trang nặng thêm đúng bằng dung lượng sprite và không được cache riêng. Sprite là file riêng được cache một lần cho mọi trang, hợp với bộ icon lớn. Lưu ý thẻ use chỉ tải được file sprite cùng tên miền với trang; nếu đặt sprite trên CDN khác tên miền, trình duyệt sẽ chặn vì chính sách bảo mật. Với các framework như React, Vue, bạn có thể nhúng sprite một lần ở layout gốc rồi dùng component nhỏ bọc thẻ use. Luôn thêm aria-hidden="true" cho icon trang trí, còn icon mang ý nghĩa riêng như nút chỉ có icon thì cần aria-label trên nút.
Giới hạn cần biết
Công cụ không nén hay đơn giản hóa đường path, không gộp đường, không bỏ số thập phân thừa; hãy tối ưu từng icon bằng SVG Optimizer trước khi gộp nếu cần file nhỏ nhất. File thiếu viewBox mà width, height dùng phần trăm hoặc em sẽ bị báo lỗi vì không thể biết kích thước thật. Việc làm sạch dựa trên danh sách phần tử và thuộc tính nguy hiểm đã biết, giúp giảm rủi ro đáng kể nhưng không thay thế cho việc chỉ dùng icon từ nguồn tin cậy. CSS trong thẻ style được chuyển đổi ở mức cơ bản, không tính lại độ ưu tiên bộ chọn và bỏ qua @media. Mỗi file tối đa 1 MB. Icon dùng font chữ riêng trong thẻ text sẽ hiển thị bằng font của trang nếu máy người xem không có font đó.
Câu hỏi thường gặp (FAQ)
SVG sprite là gì?
Là một file SVG chứa nhiều icon, mỗi icon nằm trong một thẻ symbol có id riêng. Muốn hiển thị icon nào, bạn dùng thẻ svg với use href trỏ tới id đó thay vì chèn lại toàn bộ mã icon.
Cách dùng icon trong sprite như thế nào?
Nếu sprite nhúng trong trang, dùng <svg class="icon" aria-hidden="true"><use href="#icon-home"/></svg>. Nếu sprite là file riêng, thay href bằng đường dẫn file kèm id, ví dụ /sprite.svg#icon-home.
Vì sao icon không hiện khi dùng sprite từ tên miền khác?
Thẻ use chỉ tải tài nguyên cùng nguồn gốc với trang. Sprite đặt trên CDN hay tên miền khác sẽ bị trình duyệt chặn, hãy đặt file sprite cùng tên miền hoặc nhúng trực tiếp vào HTML.
Công cụ có xử lý được 200 icon trở lên không?
Có. Icon được xử lý theo từng lô và trang nhường luồng giữa các lô nên không bị treo. Thời gian phụ thuộc vào độ phức tạp của file, với icon thông thường chỉ mất vài giây.
File SVG của tôi thiếu viewBox thì sao?
Công cụ tự tính viewBox từ width và height nếu chúng là số đo tuyệt đối như px, pt, mm, cm, in. Nếu width, height dùng phần trăm hoặc không có, icon được báo lỗi để bạn thêm viewBox vào file gốc.
Tại sao icon bị đổi màu hoặc mất gradient sau khi gộp thủ công?
Thường do trùng id: hai icon dùng cùng id cho gradient hay clipPath, trình duyệt chỉ nhận cái đầu tiên. Công cụ này đổi mọi id nội bộ thành id riêng theo tên icon và sửa lại các tham chiếu nên không còn trùng.
Có nên đổi màu icon sang currentColor không?
Nên, với icon một màu dùng trong giao diện, vì icon sẽ tự lấy màu chữ và đổi màu khi rê chuột mà không cần sửa file. Với icon nhiều màu như logo hay hình minh họa, hãy giữ màu gốc.
Công cụ có nén file SVG không?
Không. Công cụ chỉ làm sạch, bỏ khoảng trắng thừa giữa các thẻ và gộp icon. Để nén đường path và bỏ số thập phân thừa, dùng SVG Optimizer cho từng icon trước khi gộp.
Vì sao không dùng display:none để ẩn sprite nhúng?
Với display:none, một số trình duyệt không vẽ gradient, mask, clipPath hay filter nằm trong sprite. Ẩn bằng kích thước 0 và overflow hidden an toàn hơn, bản nhúng do công cụ xuất ra dùng cách này.
Tên file tiếng Việt có dấu thì id là gì?
Tên file được bỏ dấu, chữ đ thành d, chuyển chữ thường và thay khoảng trắng, ký tự đặc biệt bằng gạch nối. Ví dụ Giỏ hàng.svg với tiền tố icon- thành icon-gio-hang. Bạn có thể sửa id từng icon trong danh sách chi tiết.
File SVG có bị gửi lên máy chủ không?
Không. File được đọc và xử lý ngay trong trình duyệt bằng trình phân tích XML có sẵn, sprite được tạo tại chỗ, không có dữ liệu nào rời khỏi máy của bạn.
Làm sao để icon đọc được bởi trình đọc màn hình?
Icon trang trí nên có aria-hidden="true". Nếu icon là nội dung duy nhất của nút hay liên kết, đặt aria-label mô tả hành động lên nút hoặc liên kết đó. Thẻ title bên trong file gốc được giữ lại trong symbol.
Icon trong sprite hiển thị bị méo hoặc bị cắt?
Hãy kiểm tra viewBox của icon trong danh sách chi tiết. Icon bị cắt thường do file gốc có viewBox sai hoặc nội dung vẽ tràn ra ngoài khung. Icon bị méo khi thẻ svg bên ngoài có tỷ lệ khác viewBox, hãy đặt width và height đúng tỷ lệ.
Từ khóa liên quan
- svg sprite generator
- tạo svg sprite
- gộp icon svg
- svg symbol sprite
- svg use href
- sprite icon online
- svg icon sprite
- tạo sprite.svg
- gộp nhiều file svg
- svg sanitize
- làm sạch file svg
- svg currentcolor
- đổi màu icon svg bằng css
- svg symbol viewbox
- icon system svg
- svg sprite react
- svg duplicate id
- svg icon cho website
- xóa script trong svg