Creating & Using Icons — UI/UX

Ikon dalam UI — Kecil tapi Penting Ikon membantu user memahami fungsi elemen dengan cepat tanpa membaca teks. Tapi ikon yang buruk justru membingungkan…

Ikon adalah gambar kecil yang mewakili satu hal: wifi, sarapan, air panas. Ikon yang baik dikenali sekilas, tapi dia gak bekerja sendirian: tetap butuh teks, warna yang terlihat, dan nama untuk pembaca layar. Bayangin papan fasilitas di depan homestay Bu Sri. Kalau tiap simbol digambar orang yang beda, satu garis tipis, satu kotak hitam tebal, satu lagi pakai spidol besar, papannya terlihat seperti tempelan. Kalau semuanya digambar dengan spidol yang sama di kotak yang sama, papannya rapi walaupun simbolnya beda-beda. Dan tamu yang gak bisa melihat papan itu butuh orang yang membacakannya dengan benar.

🧪 Tebakan cepat: Tombol simpan di kartu Kamar Teras berisi ikon hati dan teks "Simpan". Ikonnya hasil ekspor dari aplikasi desain, lengkap dengan <title>ikon-hati</title> di dalam <svg>-nya. Pembaca layar membacakan tombol ini sebagai apa? Jawabannya ada di bagian "Ikon di samping teks: aria-hidden".

Satu set: grid, garis, dan gaya yang sama

Icon set adalah sekumpulan ikon yang digambar dengan aturan yang sama. Ikon fasilitas halaman Bu Sri digambar di grid 24 × 24 (viewBox="0 0 24 24"), garis setebal 2, ujung garis bulat, dan semuanya outline (garis tanpa isian):

<ul class="amenities">
  <li><svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M2 9a15 15 0 0 1 20 0"/><path d="M5 12.5a10 10 0 0 1 14 0"/><path d="M8.5 16a5 5 0 0 1 7 0"/><path d="M12 19.5h.01"/></svg> Wifi</li>
  <li><svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M4 9h12v5a5 5 0 0 1-5 5H9a5 5 0 0 1-5-5z"/><path d="M16 11h1.5a2.5 2.5 0 0 1 0 5H16"/><path d="M8 2.5v3M12 2.5v3"/></svg> Sarapan</li>
  <li><svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 3c3 4 6 7.5 6 11a6 6 0 0 1-12 0c0-3.5 3-7 6-11z"/><path d="M9.5 14.5a2.5 2.5 0 0 0 2.5 2.5"/></svg> Air panas</li>
</ul>

<style>
  .amenities li { display: flex; align-items: center; gap: 6px; }
  .icon {
    width: 20px; height: 20px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round; stroke-linejoin: round;
  }
</style>
Ukuran tampil Garis 2 di grid 24 Garis 2 di grid 16
16px 1,33px 2px
20px 1,67px 2,5px
24px 2px 3px

Jangan campur outline dan filled (terisi penuh) di satu deretan, dan pakai sedikit ukuran: 16, 20, atau 24px. Di halaman Bu Sri, ikon 20px duduk di samping teks 14px dengan jarak 6px.

currentColor: ikon ikut warna teks

stroke: currentColor artinya garis ikon memakai nilai color dari elemennya. Ikon wifi di samping teks "Wifi" otomatis sewarna teksnya. Di mode gelap, teks jadi #f1f5f9, ikon ikut, dan kontrasnya di kartu #1f2937 13,40:1.

Ikon yang warnanya ditanam di file-nya, misalnya style="fill: #1f2937" dari hasil ekspor, gak ikut. Di kartu terang dia terlihat (14,68:1), tapi di kartu gelap #1f2937 kontrasnya 1:1: ikonnya hilang.

Ikon di samping teks: aria-hidden

<svg> di dalam halaman dibaca pembaca layar sebagai gambar, dan <title> di dalamnya jadi namanya. Nama tombol diambil dari isinya, jadi untuk tombol simpan tadi, Chrome menghitung namanya "ikon-hati Simpan". Itu jawaban tebakannya: tamu yang memakai pembaca layar mendengar "ikon-hati Simpan, tombol". Kalau <svg>-nya gak punya <title>, dia tetap muncul sebagai gambar tanpa nama, dan sebagian pembaca layar menyebutnya "gambar".

Ikon di samping teks cuma hiasan, karena teksnya sudah bilang semuanya. Sembunyikan dari pembaca layar:

<button class="save">
  <svg class="icon" viewBox="0 0 24 24" aria-hidden="true">...</svg>
  Simpan
</button>

aria-hidden="true" membuat pembaca layar melewati ikonnya, walaupun mata tetap melihatnya. Namanya jadi "Simpan". Ini juga yang dipakai di daftar fasilitas: ikonnya disembunyikan, teks "Wifi" yang dibacakan.

Tombol yang isinya cuma ikon: aria-label

Tombol tutup di galeri foto cuma berisi ikon silang. Gak ada teks, jadi tanpa bantuan namanya kosong, dan pembaca layar cuma bilang "tombol". Beri nama dengan aria-label:

<button class="close" aria-label="Tutup galeri foto">
  <svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18"/></svg>
</button>

Area tekan 44 × 44px

Ikonnya boleh 20px, tapi area yang bisa ditekan harus cukup untuk jari. Panduan yang umum 44 × 44px: itu angka WCAG 2.5.5 (Target Size, tingkat AAA), dan Apple memakai 44pt di panduan desainnya. Batas minimum WCAG 2.2 di tingkat AA (2.5.8) adalah 24 × 24px.

.close {
  display: grid; place-items: center;
  width: 44px; height: 44px;   /* ikon 20px + 12px di tiap sisi */
  padding: 0; border: 0; border-radius: 9999px;
  color: #1f2937; background: #ffffff;
}

⚠️ Jebakan yang sering ketemu

TL;DR: Pakai satu icon set: satu grid (viewBox="0 0 24 24"), satu tebal garis (stroke-width: 2, tampil 1,67px di ukuran 20px), satu gaya (outline, jangan campur filled), sedikit ukuran (16, 20, 24px). Ikon dari grid 16 dengan garis 2 tampil 2,5px dan terlihat terlalu tebal. stroke: currentColor membuat ikon ikut warna teks, termasuk di mode gelap; warna yang ditanam bisa jadi 1:1. Ikon di samping teks adalah hiasan: aria-hidden="true", supaya <title> atau "gambar" gak ikut dibacakan. Tombol yang isinya cuma ikon butuh aria-label, misalnya aria-label="Tutup galeri foto", dan ikonnya butuh kontras 3:1. Area tekan minimal 44 × 44px (WCAG 2.5.5, juga panduan Apple), walaupun ikonnya cuma 20px.

Yang akan kamu pelajari