Mở đầu — vì sao bài này quan trọng
Hãy thử nhớ lại lần cuối bạn dùng một ứng dụng ngân hàng trên điện thoại. Bạn không đọc chữ "Chuyển khoản", "Lịch sử giao dịch", "Cài đặt" trước — mắt bạn quét qua các icon: một mũi tên, một đồng hồ, một bánh răng. Trong chưa đầy một giây, não bạn đã hiểu mình bấm vào đâu. Đó chính là sức mạnh thầm lặng của iconography: nó là ngôn ngữ hình ảnh giúp người dùng điều hướng giao diện mà không cần dừng lại để đọc.
Nhưng đây cũng là nơi rất nhiều designer Việt Nam mắc lỗi. Họ tải icon từ ba bộ khác nhau, mỗi cái một độ dày nét, một phong cách — kết quả là giao diện trông như chắp vá. Hoặc tệ hơn, họ dùng icon "đẹp" nhưng người dùng không hiểu nó nghĩa là gì. Một icon hình kính lúp ai cũng hiểu là tìm kiếm, nhưng một icon hình ba dấu chấm dọc thì không phải ai cũng biết là "menu thêm".
Bài này tập trung riêng vào icon trong UI: cách chọn bộ icon phù hợp, cách dùng chúng nhất quán, cách đảm bảo người dùng hiểu được, và cách triển khai chúng vào code một cách kỹ thuật. Đây là một kỹ năng nền — bạn sẽ dùng nó trong mọi component bạn thiết kế sau này: nút, form, navigation, card. Nắm vững icon, giao diện của bạn lập tức trông chuyên nghiệp hơn một bậc.
Khái niệm cốt lõi
Icon là gì và icon dùng để làm gì
Trong UI, một icon là một biểu tượng hình ảnh nhỏ truyền tải một khái niệm, một hành động hoặc một trạng thái. Icon phục vụ ba mục đích chính:
- Tăng tốc độ nhận diện: mắt người xử lý hình ảnh nhanh hơn chữ. Một icon quen thuộc giúp người dùng tìm đúng chức năng nhanh hơn.
- Tiết kiệm không gian: trên màn hình điện thoại chật hẹp, một icon thay được cả một cụm chữ.
- Tạo tính thẩm mỹ và thương hiệu: bộ icon nhất quán làm giao diện trông gọn gàng, có gu.
Ba phong cách icon phổ biến
Icon UI thường thuộc một trong ba phong cách chính, và bạn nên chọn một phong cách cho cả dự án:
- Outline (line / stroke): chỉ có đường viền, ruột rỗng. Nhẹ nhàng, hiện đại, hợp với giao diện sạch và nhiều khoảng trắng. Đây là phong cách phổ biến nhất hiện nay.
- Solid (filled): tô đặc. Đậm, dễ thấy, hợp cho các trạng thái "đang active" hoặc khi icon cần nổi bật ở kích thước nhỏ.
- Duotone / two-tone: hai sắc độ, một phần đậm một phần nhạt. Trang trí hơn, hợp cho marketing hoặc minh họa.
Các bộ icon đáng dùng (icon library)
Bạn gần như không bao giờ nên tự vẽ toàn bộ icon từ đầu — có những bộ miễn phí, chất lượng cao, được bảo trì tốt. Ba bộ đáng cân nhắc nhất:
- Heroicons — do chính team Tailwind CSS làm. Miễn phí, giấy phép MIT (dùng thoải mái cả thương mại). Có hai biến thể outline và solid khớp nhau hoàn hảo, kích thước gốc 24px. Nếu bạn dùng Tailwind, đây là lựa chọn ăn khớp nhất.
- Lucide — một bản fork của bộ Feather huyền thoại, nhưng được cộng đồng duy trì rất tích cực, có hơn 1000 icon. Nét mảnh, đồng đều, phong cách outline tối giản. Có sẵn package cho React, Vue, Svelte. Đây là lựa chọn "an toàn" cho hầu hết dự án web hiện đại.
- Font Awesome — bộ lâu đời và đầy đủ nhất, hàng nghìn icon ở nhiều phong cách (solid, regular, light, brands — logo các mạng xã hội). Có bản free và bản Pro trả phí. Mạnh ở chỗ độ phủ rộng và có sẵn icon thương hiệu (Facebook, Zalo-like, TikTok...). Lưu ý: trong dự án này, quy ước nội bộ là dùng Font Awesome cho UI chrome.
Định dạng kỹ thuật: vì sao SVG là vua
Icon ngày nay nên là SVG (Scalable Vector Graphics), không phải PNG. Lý do:
- Vô hạn độ nét: SVG là vector nên sắc nét ở mọi kích thước và mọi mật độ màn hình (Retina, màn 4K).
- Đổi màu bằng CSS: bạn điều khiển màu qua thuộc tính
fillhoặccurrentColor, không cần xuất nhiều file màu khác nhau. - Dung lượng nhỏ: một icon SVG thường chỉ vài trăm byte tới vài KB.
<svg> vào HTML, linh hoạt nhất), icon font (như Font Awesome dùng <i class="fa fa-search">), và sprite SVG (gộp nhiều icon vào một file rồi tham chiếu). Với dự án nhỏ và vừa, inline SVG hoặc dùng component icon (như lucide-react) là tiện nhất.Lưới căn icon (icon grid) và optical alignment
Mọi bộ icon tốt đều được vẽ trên một lưới chuẩn, thường là 24x24px với vùng an toàn (padding) bên trong. Điều này đảm bảo mọi icon có cùng "trọng lượng thị giác". Khi bạn tự thêm icon ngoài bộ, hãy giữ đúng kích thước khung này.
Một khái niệm tinh tế là optical alignment — căn chỉnh theo cảm nhận của mắt, không phải theo toán học. Một icon hình tam giác (nút Play) nếu căn giữa chính xác về mặt toán học sẽ trông như bị lệch trái, vì khối lượng của tam giác dồn về bên trái. Vì vậy ta phải đẩy nó sang phải một chút để mắt thấy nó "ở giữa". Đây là lý do nút Play trong mọi trình phát video đều được dịch nhẹ sang phải.
Tình huống thực tế
Ví dụ 1: Sàn TMĐT trộn ba bộ icon — bài học về tính nhất quán
Một startup thương mại điện tử ở TP.HCM (tạm gọi MuaSamViet) thuê freelancer làm giao diện app trong giai đoạn gấp rút. Mỗi freelancer tự chọn icon theo ý mình: phần giỏ hàng dùng Font Awesome solid, phần hồ sơ dùng Heroicons outline, phần tìm kiếm lấy đại một icon từ Flaticon. Kết quả: icon giỏ hàng đậm và to, icon hồ sơ mảnh và nhẹ, icon tìm kiếm lại có nét dày trung bình. Khi nhìn tổng thể thanh điều hướng, mọi thứ "lệch pha".
Đội ngũ nhận phản hồi từ một vòng test người dùng: 4/10 người nói giao diện trông "thiếu chuyên nghiệp" dù không chỉ ra được lý do cụ thể. Đó chính là tác động của sự thiếu nhất quán ở mức tiềm thức — người dùng cảm nhận được nhưng không gọi tên được.
Cách họ sửa: chọn Lucide làm bộ duy nhất, thay toàn bộ icon, chuẩn hóa kích thước 24px và độ dày nét 1.5px. Thời gian thay icon chỉ mất khoảng hai ngày, nhưng điểm "cảm nhận chuyên nghiệp" trong vòng test tiếp theo tăng rõ rệt.
Bài học rút ra: tính nhất quán của icon quan trọng hơn việc từng icon đẹp đến đâu. Một bộ icon "khá khá" nhưng đồng đều luôn thắng một mớ icon "đẹp" nhưng chỏi nhau.
Ví dụ 2: Icon "đĩa mềm" để lưu — bài học về ngữ cảnh văn hóa
Một công ty phần mềm kế toán dành cho doanh nghiệp nhỏ dùng icon đĩa mềm (floppy disk) cho nút "Lưu", theo thói quen từ thời Microsoft Office. Trong test với nhóm người dùng trẻ (sinh sau năm 2000) làm kế toán cho các shop online, một số bạn không nhận ra đó là cái gì — họ chưa từng thấy đĩa mềm ngoài đời.
Đây là một bài toán thú vị. Icon đĩa mềm vẫn là quy ước "lưu" được hiểu rộng rãi với người lớn tuổi, nhưng đang dần mất ý nghĩa với thế hệ mới. Giải pháp của công ty: giữ icon nhưng thêm nhãn chữ "Lưu" bên cạnh trong các màn hình quan trọng, và ở những nơi chật chỗ thì dùng tooltip hiện chữ khi rê chuột.
Bài học rút ra: một icon "kinh điển" không có nghĩa là phổ quát mãi mãi. Khi nghi ngờ, hãy kèm nhãn chữ. Icon đứng một mình chỉ an toàn khi nó thực sự là chuẩn chung mà nhóm người dùng của bạn đều hiểu.
Ví dụ 3: Tab bar của app gọi xe — outline vs solid cho trạng thái
Một nhóm sinh viên làm đồ án một app gọi xe (mô phỏng kiểu Grab/Be) thiết kế thanh tab dưới với 4 mục: Trang chủ, Hoạt động, Tin nhắn, Tài khoản. Ban đầu họ dùng toàn bộ icon outline cùng màu xám. Vấn đề: người dùng test không biết mình đang ở tab nào, vì tab đang chọn nhìn không khác gì các tab còn lại — họ chỉ đổi màu chữ nhẹ mà mắt khó bắt được.
Giải pháp: với tab đang active, họ chuyển icon sang biến thể solid (tô đặc) và đổi sang màu thương hiệu (xanh lá); các tab còn lại giữ outline màu xám. Lập tức, người dùng nhận ra ngay vị trí hiện tại chỉ trong nửa giây. Vì họ dùng Heroicons — vốn có cặp outline/solid khớp nhau — việc đổi này chỉ là thay tên file icon, không cần vẽ lại gì.
Bài học rút ra: dùng cặp outline/solid để biểu thị trạng thái là một kỹ thuật mạnh và rẻ. Đây là lý do nên chọn bộ icon có đủ cả hai biến thể ngay từ đầu.
Hướng dẫn từng bước
Đây là quy trình thực dụng để dùng icon trong một dự án mới:
- Chọn một bộ icon chính. Nếu bạn dùng Tailwind, hãy chọn Heroicons. Nếu cần một bộ outline đầy đủ và linh hoạt, chọn Lucide. Nếu cần độ phủ rộng và logo thương hiệu, chọn Font Awesome. Ghi quyết định này vào tài liệu thiết kế để cả team theo.
- Chốt một kích thước chuẩn và một độ dày nét. Ví dụ: icon mặc định 24px, độ dày nét 1.5px (hoặc 2px). Định nghĩa thêm vài cỡ phụ nếu cần (16px cho icon nhỏ trong nhãn, 20px, 24px). Đừng để mỗi nơi một kích thước ngẫu nhiên.
- Quyết định cách nhúng kỹ thuật. Dùng inline SVG, component icon (
lucide-react,@heroicons/react), hay icon font. Với React/Vue, dùng package component là gọn nhất:
import { Search, ShoppingCart } from 'lucide-react'; <Search size={24} strokeWidth={1.5} />
- Dùng
currentColorđể điều khiển màu. Đặt thuộc tính màu của SVG làcurrentColorđể icon tự lấy màu chữ của phần tử cha. Khi đó bạn chỉ cần đổicolortrong CSS là icon đổi theo, rất tiện cho hover và dark mode:
<svg fill="none" stroke="currentColor" stroke-width="1.5">...</svg>
.nav-link { color: #6b7280; }
.nav-link:hover { color: #16a34a; }
- Căn icon với chữ bằng flexbox. Khi icon đứng cạnh nhãn (ví dụ trong nút), dùng
display: inline-flex; align-items: center; gap: 8px;để chúng thẳng hàng và có khoảng cách đều.
- Thêm nhãn cho khả năng tiếp cận (accessibility). Nếu icon chỉ trang trí, ẩn nó khỏi trình đọc màn hình bằng
aria-hidden="true". Nếu icon mang nghĩa và đứng một mình (như nút chỉ có icon), thêmaria-labelmô tả hành động:
<button aria-label="Tìm kiếm">
<svg aria-hidden="true">...</svg>
</button>
- Kiểm tra trên nền tối và kích thước nhỏ. Xem icon có còn rõ ở 16px không, có đủ tương phản với nền không. Một số icon nhiều chi tiết sẽ bị "bết" lại khi thu nhỏ.
Lỗi thường gặp & mẹo
Trộn nhiều bộ icon. Như đã nói ở ví dụ 1 — đây là lỗi phổ biến nhất. Mẹo: nếu buộc phải lấy một icon từ bộ khác (vì bộ chính không có), hãy chỉnh lại độ dày nét và kích thước cho khớp, hoặc tìm icon thay thế cùng phong cách.
Icon đứng một mình mơ hồ. Icon ba dấu chấm, icon hamburger, icon đĩa mềm... không phải ai cũng hiểu. Mẹo: với hành động không phổ biến, kèm nhãn chữ hoặc ít nhất là tooltip.
Vùng bấm quá nhỏ. Một icon 24px có vùng bấm chỉ 24x24px là quá nhỏ cho ngón tay trên điện thoại. Theo khuyến nghị, vùng chạm tối thiểu nên khoảng 44x44px. Mẹo: thêm padding quanh icon để mở rộng vùng bấm dù icon vẫn nhỏ.
Dùng PNG thay vì SVG. PNG bị vỡ nét trên màn Retina và không đổi màu được bằng CSS. Mẹo: luôn ưu tiên SVG; chỉ dùng raster cho ảnh thật, không phải icon.
Quên trạng thái và dark mode. Icon hardcode màu đen sẽ tàng hình trên nền tối. Mẹo: dùng currentColor để icon tự thích nghi theo theme.
Icon quá nhiều chi tiết ở kích thước nhỏ. Một icon đẹp ở 48px có thể thành một đốm mờ ở 16px. Mẹo: chọn icon đơn giản, ít nét cho các vị trí nhỏ.
Bỏ qua optical alignment. Icon mũi tên, tam giác, hình lệch tâm cần căn theo mắt. Mẹo: nếu icon trông lệch dù căn giữa "đúng", hãy dịch nó vài pixel cho cân.
Bài tập thực hành
- Khảo sát một bộ icon: vào trang Lucide hoặc Heroicons, tìm 8 icon cho các chức năng sau: tìm kiếm, trang chủ, thông báo, giỏ hàng, cài đặt, người dùng, lưu, xóa. Ghi lại tên chính xác của từng icon trong bộ đó.
- Phát hiện sự thiếu nhất quán: mở hai app trên điện thoại của bạn (ví dụ một app ngân hàng và một app mua sắm). Chụp màn hình thanh điều hướng. Quan sát: chúng dùng outline hay solid? Tab active được phân biệt thế nào? Có icon nào bạn không đoán được nghĩa không?
- Dựng một thanh tab: dùng HTML/CSS, tạo thanh tab dưới với 4 mục, mỗi mục có icon + nhãn. Dùng icon outline cho mục thường, solid cho mục đang chọn, và
currentColorđể đổi màu khi active. Đảm bảo vùng bấm mỗi tab tối thiểu 44px chiều cao.
- Sửa accessibility: lấy một nút chỉ có icon (ví dụ nút đóng hình chữ X). Thêm
aria-labelđúng vàaria-hidden="true"cho SVG bên trong. Kiểm tra bằng cách bật trình đọc màn hình (VoiceOver trên Mac).
Tóm tắt
Iconography là ngôn ngữ hình ảnh giúp người dùng điều hướng giao diện nhanh, gọn và đẹp — nhưng chỉ khi bạn dùng nó có kỷ luật. Những điểm cốt lõi cần nhớ:
- Chọn một bộ icon chính (Heroicons, Lucide, hoặc Font Awesome) và bám lấy nó. Tính nhất quán quan trọng hơn vẻ đẹp của từng icon.
- Hiểu ba phong cách outline, solid, duotone — và dùng cặp outline/solid để biểu thị trạng thái active một cách rẻ và hiệu quả.
- Dùng SVG, điều khiển màu bằng
currentColor, để icon sắc nét và tự thích nghi với theme. - Icon hỗ trợ chứ không thay thế chữ: với hành động không phổ biến, hãy kèm nhãn hoặc tooltip.
- Đừng quên accessibility và vùng bấm:
aria-labelcho nút icon, vùng chạm tối thiểu 44px, và kiểm tra ở kích thước nhỏ.