D
P
0

WordPress & Elementor

Ikon `20×20` Malah Render `11×20` di Elementor? SVG Tanpa `width`/`height` Ketemu `flex-shrink`

19 Juli 2026·4 menit baca
Ikon `20×20` Malah Render `11×20` di Elementor? SVG Tanpa `width`/`height` Ketemu `flex-shrink`

Saya baru selesai membangun ulang sembilan halaman sebuah situs klien di Elementor. Salah satu komponen yang berulang di hampir semua halaman adalah pill: kotak kecil membulat berisi satu ikon di kiri dan satu baris heading di kanannya, semacam baris integrasi ala tombol Google Meet. Ikonnya seharusnya 20×20. Begitu halaman live, saya perhatikan ikon-ikon itu tampak aneh: bukan 20×20, tapi 11×20, 14×20, kadang 17×20. Tingginya selalu pas di 20, tapi lebarnya menciut. Gepeng ke arah horizontal.

Yang bikin saya mengernyit: derajat gepengnya tidak seragam. Pill dengan heading pendek, ikonnya nyaris normal. Pill dengan heading panjang, ikonnya paling kurus. Ada korelasi jelas antara panjang teks tetangga dan seberapa ciut ikonnya. Itu petunjuk pertama, walau waktu itu belum saya baca dengan benar.

Jalan buntu yang saya coba

Refleks pertama saya menyalahkan artwork-nya. Saya buka beberapa file SVG di editor, ukur ulang, semuanya proporsional. Lingkaran tetap lingkaran, kotak tetap kotak. Artwork bersih.

Karena baru saja menuntaskan kasus ikon gepeng yang lain, saya langsung curiga ke preserveAspectRatio="none". Saya cek root tiap SVG. Ternyata bukan itu: tidak ada preserveAspectRatio yang nyasar, dan lagipula pola distorsinya beda. none meregangkan ikon melebar mengikuti box; ini justru kebalikannya, ikonnya menciut, dan menciutnya cuma di satu sumbu sambil menyesuaikan panjang tetangga. Beda gejala, beda pelaku.

Lalu saya kejar CSS. Saya inspect elemen image di pill yang bermasalah, cari transform, object-fit, max-width yang nyasar. Bersih semua. Saya coba paksa lebar lewat CSS, set width: 20px di elemen img. Sesaat membaik, lalu ciut lagi begitu heading tetangganya panjang. Di titik itu saya sadar ada sesuatu yang lebih kuat dari deklarasi lebar saya, sesuatu yang menarik ikon itu keluar.

Akar masalahnya: dua sebab yang menumpuk

Sebab pertama ada di file SVG-nya. Ikon-ikon ini punya viewBox tapi tidak punya atribut width dan height sama sekali. Buat elemen svg inline itu tidak masalah, tapi Elementor memasang ikon lewat widget image, artinya ikon ditaruh di dalam <img>. Sebuah <img> butuh dimensi intrinsik untuk tahu ukuran naturalnya. Kalau SVG-nya tidak menyediakan width/height, browser menurunkan aspek intrinsik dari bounding box konten, dan lebar natural <img> bisa runtuh jadi kecil. Jadi ikon sudah masuk halaman tanpa lebar yang kokoh untuk dipertahankan.

Sebab kedua ada di layout pill-nya. Widget image itu adalah flex child di dalam pill: kontainer pill-nya flex row, isinya ikon lalu heading. Secara default setiap flex child punya flex-shrink: 1. Artinya kalau ruang di main axis sempit, flexbox berhak menciutkan anak-anaknya. Ketika heading tetangga panjang, ia menuntut ruang lebih, dan flexbox mengambilnya dari mana? Dari ikon, karena ikon tadi tidak punya lebar intrinsik yang kokoh. Tingginya aman karena itu cross axis; yang diciutkan cuma lebar. Hasilnya 11×20.

Sendiri-sendiri, dua hal ini halus. <img> tanpa dimensi intrinsik saja mungkin cuma tampil agak kecil. flex-shrink default saja pada gambar yang dimensinya jelas biasanya aman. Tapi digabung, keduanya saling memperparah: tidak ada lebar untuk ditahan, plus ada gaya yang menariknya keluar. Ikon pun kolaps horizontal, dan derajatnya bergantung pada panjang heading tetangga. Itu sebabnya distorsinya terasa acak padahal sama sekali tidak.

Perbaikannya

Kabar baiknya, semua perbaikan pakai kontrol native Elementor, tanpa CSS hack. Kuncinya set tiga hal sekaligus di setiap widget image berukuran ikon.

Pertama, paksa dimensi eksak. Ganti image_size dari full ke custom, lalu isi image_custom_dimension dengan lebar dan tinggi yang kamu mau. Ini memberi <img> ukuran pasti, bukan menebak dari intrinsik.

Kedua, matikan flex-shrink. Di panel Advanced lalu Flex lalu Size, pilih None. Di data Elementor ini tersimpan sebagai _flex_size: "none". Dengan ini flexbox berhenti menciutkan ikon walau heading tetangga sepanjang apa pun.

Ketiga, pastikan keduanya benar-benar terpasang bareng. Salah satu saja tidak cukup. Custom dimension tanpa _flex_size: none masih bisa diciutkan flexbox; _flex_size: none tanpa dimensi eksak masih bisa tampil kecil karena tidak ada lebar intrinsik. Digabung di JSON settings widget, kombinasinya seperti ini:

{"image_size":"custom","image_custom_dimension":{"width":"20","height":"20"},"_flex_size":"none"}

Karena kesembilan halaman punya ratusan ikon, saya tidak mengedit satu per satu di UI. Saya jalankan skrip fix global yang menyapu setiap widget image berukuran ikon, saya batasi ke yang ≤64×64 supaya tidak menyentuh gambar konten besar, lalu menuliskan trio setting itu. Sekali jalan, skrip itu memperbaiki 385 ikon di sembilan halaman.

Terakhir, saya perbaiki sumbernya. Helper PHP kanonik yang membangun widget image, W_image(), dulu memancarkan image_size: full. Sekarang ia selalu memancarkan trio yang sama, jadi ikon berikutnya lahir sudah benar:

function W_image($id, $url, $w, $h) {
  return ['id'=>newId(),'elType'=>'widget','widgetType'=>'image','settings'=>['image'=>['id'=>$id,'url'=>$url],'image_size'=>'custom','image_custom_dimension'=>['width'=>(string)$w,'height'=>(string)$h],'width'=>['unit'=>'px','size'=>$w],'height'=>['unit'=>'px','size'=>$h],'_flex_size'=>'none']];
}

Pelajaran

  • Ikon yang gepeng horizontal tapi tingginya pas sering bukan soal artwork, tapi soal lebar yang diciutkan flexbox.
  • SVG yang dipakai lewat <img> sebaiknya punya width/height eksplisit, atau kamu paksa ukurannya dari sisi yang memasang. Tanpa dimensi intrinsik, <img> gampang runtuh.
  • flex-shrink: 1 adalah default tiap flex child. Kalau derajat distorsi ikut panjang tetangganya, curigai flexbox lebih dulu.
  • Di Elementor obatnya native: image_size: custom plus image_custom_dimension untuk dimensi eksak, dan Flex Size None (_flex_size: none) untuk menahan shrink. Pasang keduanya, jangan salah satu.
  • Kalau bug menyebar ke ratusan instance, perbaiki generator-nya (di sini helper W_image()), bukan cuma instance-nya. Kalau tidak, batch berikutnya lahir sakit lagi.