Sebuah situs klien yang saya pegang baru saja menerima satu batch ikon SVG baru dari pipeline desain. Begitu dipasang, hasilnya bikin saya mengerutkan dahi: sebagian ikon tampil terdistorsi. Lingkaran jadi elips. Ikon ceklis gepeng melebar seperti ditarik ke samping. Dan yang paling mengganggu, distorsinya terasa acak. Ikon yang sama tampil sempurna di sidebar, lalu penyok di dalam tombol. Saya buka file sumbernya di editor desain, dan semuanya proporsional. Artwork-nya tidak ada masalah.
Refleks pertama saya menyalahkan CSS. Saya cek flexbox di slot yang bermasalah, cek ada tidaknya transform nyasar, cek object-fit. Semuanya bersih. Baru setelah itu saya melakukan hal yang seharusnya jadi langkah pertama: membuka file SVG hasil export di text editor, bukan cuma memandangi sumbernya di tool desain. Di root svg, satu atribut langsung menghentikan investigasi:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
width="24" height="24" preserveAspectRatio="none">
<path d="M20 6L9 17l-5-5" fill="none" stroke="currentColor" stroke-width="2"/>
</svg>preserveAspectRatio="none". Di situ pelakunya.
Kenapa ini terjadi
SVG punya dua konsep ukuran yang terpisah. viewBox mendefinisikan sistem koordinat internal artwork, alias proporsinya. Ukuran render final ditentukan oleh box CSS tempat SVG itu duduk. Nah, preserveAspectRatio adalah aturan yang menjembatani keduanya: bagaimana viewBox dipetakan ke box. Default-nya, kalau atributnya tidak ditulis, adalah xMidYMid meet: skala uniform, di-center, muat di dalam box. Proporsi selalu aman.
none mematikan semua itu. Artinya: regangkan viewBox sampai memenuhi box, di kedua sumbu secara independen. Non-uniform, dan itu by design, bukan bug browser. Konsekuensinya, setiap slot yang box CSS-nya tidak persis sama rasionya dengan viewBox akan mendeformasi artwork. Ikon 24x24 di slot 24x24: aman. Ikon yang sama di slot tombol 32x24: melebar sepertiga. Di wrapper width: 100%: terserah lebar wrapper-nya hari itu. Itulah kenapa distorsinya terasa acak. Padahal tidak acak sama sekali; dia cuma bergantung pada aspect ratio box-nya, dan sebagian slot kebetulan pas.
Lalu dari mana atribut itu datang? Tidak ada yang menulisnya dengan sengaja untuk ikon. Ternyata dulu pernah ada divider dekoratif yang memang sengaja di-stretch non-uniform, kasus yang sah untuk none, dan setting itu nempel di template export. Sejak itu, setiap ikon yang keluar dari pipeline yang sama ikut membawa atributnya. Satu keputusan untuk satu asset, bocor ke seluruh armada.
Perbaikannya
Tiga langkah, dari satu file sampai seluruh folder.
Pertama, hapus preserveAspectRatio="none" dari root. Tanpa atribut itu, browser jatuh ke default xMidYMid meet: skala uniform dan ter-center, apa pun bentuk box-nya. Kedua, berhenti mengunci width dan height dengan angka fixed yang nantinya bertengkar dengan CSS. Set keduanya ke 100%, dan biarkan viewBox jadi satu-satunya sumber kebenaran untuk proporsi:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
width="100%" height="100%">
<path d="M20 6L9 17l-5-5" fill="none" stroke="currentColor" stroke-width="2"/>
</svg>Kalau lebih suka sizing sepenuhnya di CSS, buang atribut width dan height sekalian dan atur dari stylesheet:
.icon-slot svg {
width: 100%;
height: 100%;
}Ketiga, dan ini yang penting karena file yang terinfeksi ada puluhan: jangan perbaiki satu-satu di editor. Satu one-liner menyapu seluruh folder ikon:
grep -rl 'preserveAspectRatio="none"' assets/icons/ | \
xargs sed -i 's/ preserveAspectRatio="none"//g'Di mesin Windows, versi PowerShell-nya:
Get-ChildItem assets/icons -Recurse -Filter *.svg | ForEach-Object {
(Get-Content $_.FullName -Raw) -replace ' preserveAspectRatio="none"', '' |
Set-Content $_.FullName -NoNewline
}Verifikasinya cepat: render ikon di slot dengan berbagai ukuran dan rasio, kotak, melebar, width: 100%, lalu resize sesuka hati. Kalau lingkaran tetap lingkaran di semua ukuran container, selesai. Dan satu langkah lagi yang jangan sampai lewat: perbaiki template export-nya juga. Kalau tidak, batch ikon berikutnya datang membawa penyakit yang sama.
Pelajaran
- Kalau SVG tampil terdistorsi, cek
preserveAspectRatiolebih dulu, sebelum menyalahkan CSS. noneartinya stretch non-uniform, by design. Itu bukan browser yang rusak; itu instruksi yang dituruti dengan patuh.viewBoxmenentukan proporsi, CSS menentukan ukuran. Jangan biarkan atribut fixed ikut campur di antaranya.- Pipeline export bisa meracuni semua asset downstream. Perbaiki template-nya dulu, baru batch-fix seluruh armada.
Yang paling saya ingat dari kasus ini bukan atributnya, tapi rasa "acak" itu. Bug yang muncul di sebagian tempat dan tidak di tempat lain hampir tidak pernah acak; dia cuma bergantung pada variabel yang belum kamu lihat. Di sini, variabelnya sesederhana bentuk sebuah kotak.
