Sprite CSS: Kapan Masih Bermanfaat dan Cara Membuatnya
Kebanyakan tutorial sprite CSS masih membuka dengan kalimat sama seperti pada 2009: sprite mengurangi permintaan HTTP, sehingga mempercepat situs. Argumen itu dibangun berdasarkan batasan HTTP/1.1 yang tidak lagi ada pada server modern. Berikut versi jujur — alasan yang benar-benar masih mendukung sprite, yang tidak, dan perhitungan tepat background-position dan perhitungan retina untuk membuatnya bekerja.
Apa sebenarnya sprite CSS
Sprite CSS adalah satu berkas gambar berisi banyak grafis terpisah, ditambah CSS yang menampilkan satu grafis saja pada satu waktu. Tidak ada pemangkasan dan tidak melibatkan JavaScript. Elemen diberi nilai tetap untuk width dan height, seluruh lembar ditetapkan sebagai background-image, dan background-position menggeser sheet di belakang elemen agar ikon yang diinginkan berada dalam kotak terlihat. Kotak adalah jendela; sprite sheet adalah kertas besar yang diseret di belakangnya.
Satu detail yang menjebak saat pertama mencoba adalah offsetnya negatif. Anda bukan menggerakkan jendela menuju ikon, melainkan menggerakkan lembar agar ikon masuk ke jendela. Untuk menampilkan ikon yang sudut kiri atasnya berada 96 piksel dari tepi kiri lembar, geser lembar 96 piksel ke kiri, yaitu background-position: -96px 0.
Contoh konkret. Misalkan Anda mengemas lima ikon 24×24 dalam satu baris dengan celah 8 piksel di antaranya, mulai 8 piksel dari kiri dan 8 piksel dari atas. Ukuran lembar menjadi 160×32. Tepi kiri ikon ketiga berada pada 8 + 24 + 8 + 24 + 8 = 72 piksel, dan tepi atasnya pada 8 piksel. Aturannya adalah:
| Deklarasi | Fungsinya |
|---|---|
| background-image: url("/sprite.png") | Memuat seluruh lembar di belakang elemen |
| background-repeat: no-repeat | Menghentikan pengulangan lembar dan penampilan ikon lain di sekitar tepi |
| background-position: -72px -8px | Menggeser lembar 72px ke kiri dan 8px ke atas agar ikon ketiga berada di titik awal |
| width: 24px; height: 24px | Memotong jendela tepat menjadi satu ikon — inilah yang menyembunyikan sisanya |
| display: inline-block | Memungkinkan elemen sebaris seperti span mengikuti lebar dan tinggi |
Jangan ubah apa pun selain kedua angka dalam background-position dan Anda mendapatkan ikon berbeda dari file yang sama. Itulah keseluruhan mekanismenya.

Penjelasan jujur: HTTP/2 mengubah perhitungan
Sprite CSS diciptakan untuk mengatasi batasan tertentu. Pada HTTP/1.1, peramban membuka sejumlah kecil koneksi TCP per origin — umumnya enam — dan setiap koneksi hanya dapat menangani satu permintaan pada satu waktu. Empat puluh berkas ikon berarti empat puluh permintaan antre melalui enam jalur, masing-masing menanggung penyiapan koneksi dan latensi bolak-balik. Menggabungkannya dalam satu berkas mengubah empat puluh permintaan berurutan menjadi satu. Pada koneksi berlatensi tinggi, ini bukan optimasi kecil, melainkan sering merupakan peningkatan terbesar yang tersedia pada halaman.
HTTP/2 melakukan multiplexing. Banyak permintaan berbagi satu koneksi secara bersamaan, tanpa head-of-line blocking pada lapisan HTTP, dan header dipampatkan lintas permintaan. Masalah khusus yang awalnya diatasi sprite sebagian besar menghilang. Jika tutorial pada 2026 menyatakan sprite lebih cepat karena mengurangi jumlah permintaan, lalu berhenti di situ, tutorial itu ditulis untuk web yang sudah tidak ada.
Jadi mengapa artikel ini ada? Karena "alasan asli hilang" tidak sama dengan "tidak ada alasan". Beberapa keunggulan nyata tetap ada setelah multiplexing, dan itulah dasar keputusan yang layak:
- Overhead per permintaan tidak menjadi nol. Permintaan multiplex murah, tetapi tidak gratis. Masing-masing tetap membawa header, pencarian cache, dan slot dalam penjadwal sumber daya peramban. Pada lima ikon tidak berarti. Pada dua ratus ikon kecil dapat diukur, dan sprite merangkumnya menjadi satu entri.
- Pengelolaan cache menjadi lebih sederhana. Satu berkas berarti satu entri cache, satu Cache-Control kebijakan, satu nama file ber-hash untuk diperbarui. Dua ratus file ikon yang masing-masing memiliki versi adalah cakupan build dan deployment yang harus dikelola, tetapi biasanya tidak.
- Pemberian versi atomik. Semua ikon dikirim bersama, sehingga Anda tidak akan memperoleh kumpulan ikon yang hanya diperbarui sebagian, misalnya tiga ikon dari cache dengan gaya lama sementara sisanya baru. Untuk peluncuran sistem desain, ini merupakan jaminan konsistensi yang nyata, bukan sekadar kerapian.
- Tidak ada kilatan ikon yang hilang. Setelah lembar dimuat, setiap ikonnya langsung tersedia. Ikon dimuat individual muncul satu per satu saat permintaan selesai, paling terlihat pada tempat paling mengganggu: bilah alat atau kisi ikon di area awal halaman.
- Perubahan status tanpa latensi. Status hover atau aktif yang berada di bagian lain pada lembar yang sama sudah terunduh. Dengan berkas terpisah, gambar hover sering baru diminta ketika pengguna pertama kali mengarahkan kursor, sehingga muncul kilatan kosong saat pertama kali menyentuh tombol. Ini selalu menjadi salah satu alasan terkuat menggunakan sprite, dan HTTP/2 tidak mengurangi manfaatnya.
Kapan jangan menggunakan sprite CSS
Rekomendasi yang dapat dipercaya harus mencakup situasi ketika jawabannya tidak, dan untuk sprite CSS ada beberapa situasi seperti itu.
- Ikon monokrom yang dapat diskalakan sebaiknya menggunakan SVG. Elemen sebaris <svg> atau sprite SVG yang dibuat dari <symbol> dan <use> diskalakan ke ukuran apa pun tanpa perhitungan retina, dan mewarisi warna melalui currentColor. Untuk kumpulan ikon UI biasa, alat itu memang lebih baik, dan itulah alasan lembar sprite perlahan kehilangan sebagian besar pangsa pasarnya dalam sistem ikon.
- Satu ikon tidak pernah layak dijadikan sprite. Jika memiliki satu gambar, gunakan satu gambar. Sprite menambahkan pencatatan koordinat dan langkah build tanpa manfaat apa pun.
- Ikon yang berubah secara independen. Pemberian versi atomik memiliki dua sisi. Jika satu ikon berubah, entri cache seluruh lembar menjadi tidak valid dan setiap pengguna mengunduh ulang semuanya. Kumpulan ikon yang sering berubah kurang cocok untuk sprite.
- Apa pun yang membutuhkan pewarnaan ulang atau tema. Sprite raster menyimpan warna secara tetap. Mode gelap, tema merek, dan warna status semuanya memerlukan lembar kedua atau trik filter yang rapuh. Inilah keunggulan struktural SVG yang paling jelas.
- Ikon yang harus merespons ukuran font. Sprite terikat dimensi piksel. Jika ikon perlu diskalakan mengikuti em bersama teks, pendekatan vektor menanganinya, sementara sprite justru menyulitkan.
Sprite, sprite SVG, SVG sebaris, atau font ikon
| Pendekatan | Diskalakan dengan bersih | Warnai ulang melalui CSS | Permintaan | Cache | Aksesibilitas |
|---|---|---|---|---|---|
| Sprite CSS (raster) | Tidak — piksel tetap, memerlukan lembar 2x | Tidak, hanya trik filter | Satu untuk semua ikon | Sangat baik, satu berkas berumur panjang | Gambar latar tidak terlihat oleh teknologi bantu — memerlukan label teks |
| Sprite SVG (symbol + use) | Ya, ukuran apa pun | Ya, melalui currentColor | Satu untuk semua ikon | Sangat baik, satu berkas | Di DOM, mendukung title dan ARIA |
| SVG sebaris per ikon | Ya, ukuran apa pun | Ya, kontrol CSS penuh | Nol, tertanam dalam HTML | Tidak ada — dikirim ulang bersama setiap halaman | Terbaik, sepenuhnya berada di DOM |
| Font ikon | Ya, mengikuti font-size | Ya, melalui color | Satu berkas font | Baik | Buruk — glif dibacakan atau diganti font cadangan |
Baca tabel sebagai keputusan, bukan papan skor. Karya raster multicolor — bendera, logo, lencana ilustrasi, tangkapan layar ikon aplikasi — tidak dapat menjadi sprite SVG dengan cara masuk akal, dan itulah ruang tempat sprite CSS masih jawaban tepat, bukan sekadar warisan lama.
Membuat satu
Alur terdiri empat langkah, dan hanya ketiga rumit secara manual.
- Kumpulkan ikon. Ekspor pada ukuran tampilan akhir (atau dua kali lipat — lihat bagian retina). Pertahankan ukuran konsisten sebisa mungkin; kisi seragam membuat perhitungan koordinat mudah dan CSS teratur.
- Kemas menjadi satu lembar. Baris sederhana atau kisi tetap lebih mudah dipahami; pengemas memanfaatkan ruang lebih baik ketika ukuran bervariasi. Sisakan celah antarikonnya.
- Baca koordinatnya. Setiap ikon memerlukan x, y, lebar, dan tingginya dalam piksel lembar. Melakukannya manual dalam editor gambar adalah titik rawan pekerjaan sprite, karena salah baca satu piksel muncul sebagai sedikit ikon tetangga tanpa petunjuk penyebabnya.
- Tulis CSS-nya. Satu aturan dasar bersama ditambah satu aturan kecil per ikon.
Aturan dasar bersama lebih penting daripada kelihatannya. Setiap ikon memerlukan nilai sama untuk background-image, background-repeat: no-repeat, dan display: inline-block. Mengulangi background-image URL dalam lima puluh aturan bukan masalah kinerja — browser tetap hanya mengambilnya sekali — tetapi menjadi masalah pemeliharaan: saat nama sheet diubah untuk memperbarui cache, Anda perlu mengedit lima puluh tempat, bukan satu. Karena itu, polanya adalah kelas dasar yang memuat semua hal bersama, serta kelas per ikon yang hanya memuat posisi dan ukuran:
| Aturan | Isi |
|---|---|
| .sprite | background-image, background-repeat: no-repeat, display: inline-block |
| .sprite-search | background-position: -8px -8px; width: 24px; height: 24px |
| .sprite-settings | background-position: -40px -8px; width: 24px; height: 24px |
Dalam markup, bentuknya <span class="sprite sprite-search"></span>. Di Sass, gagasan yang sama biasanya dinyatakan sebagai placeholder, %sprite-base, yang disertakan ke setiap aturan ikon menggunakan @extend — yang menghasilkan satu selector gabungan dalam keluaran terkompilasi, bukan mengulang deklarasi, dan menjaga markup hanya satu kelas per ikon.
Retina dan HiDPI: trik background-size
Bagian yang dilewati atau salah pada kebanyakan panduan. Sprite raster 1x tampak lembut pada layar 2x, dan solusi bukan mengganti offset — kemas resolusi ganda lalu beri tahu CSS ukuran lembar separuh kenyataan.
Ambil contoh sebelumnya dan gandakan semuanya saat ekspor: ikon 48×48 piksel nyata, celah 16, dan lembar 320×64 piksel nyata. Sekarang atur background-size: 160px 32px — tepat setengah dimensi sebenarnya sheet. Browser memperkecil seluruh sheet ke ruang koordinat 160×32 piksel CSS dan memetakan detail tambahan ke piksel fisik perangkat pada layar HiDPI.
Manfaatnya setiap angka lain dalam CSS tetap pada sistem koordinat asli 1x. Ikon ketiga tetap background-position: -72px -8px dengan width: 24px; height: 24px, tanpa perubahan, meskipun piksel aslinya berada pada 144, 16 di dalam berkas. Anda menghitung offset sekali, dalam piksel CSS, dan satu background-size deklarasi pada kelas dasar menangani pemetaan kepadatan untuk semua ikon sekaligus.
Ada dua hal yang mengikuti ini dan perlu ditegaskan. Pertama, background-size berada pada aturan dasar bersama, bukan diulang per ikon. Kedua, jangan menyajikan dua sheet melalui media query tanpa alasan kuat: sheet 2x pada setengah ukuran juga tampak benar di layar 1x (browser hanya memperkecilnya), sehingga satu sheet dan satu aturan mencakup keduanya, dengan biaya file lebih besar. Karena sheet ikon yang dikompres baik biasanya kecil, kompromi itu umumnya layak — sekaligus menghindari kondisi sulit rasio piksel perangkat pecahan seperti 1.5 dan 2.5, ketika perpindahan media query harus memilih salah satu dan salah satunya akan keliru.
Varian hover dan status
Tata letak sprite klasik untuk elemen interaktif adalah kisi dengan setiap kolom satu ikon dan setiap baris satu status: bawaan baris pertama, hover kedua, aktif atau nonaktif ketiga. Karena kolom tidak bergerak, perubahan status hanya menggeser Y dan offset X tetap sama.
Dengan ikon 24px dan celah 8px, baris pertama berada pada y = 8 dan baris kedua pada y = 40. Aturan default ikon ketiga adalah background-position: -72px -8px dan aturan hover-nya adalah background-position: -72px -40px. Jika Anda menetapkan langkah vertikal sebagai variabel — misalnya --sprite-row: 32px — Anda dapat menyatakan status hover sekali pada kelas dasar menggunakan calc() terhadap variabel X per ikon, alih-alih menulis aturan kedua untuk setiap ikon.
Di sinilah sprite masih benar-benar lebih baik daripada berkas terpisah: piksel hover tiba bersama piksel bawaan, sehingga hover pertama seketika. Itulah alasan mempertahankan status pada lembar sama — lembar hover terpisah mengembalikan kilatan permintaan hover pertama yang ingin dicegah.
Ruang tambahan, dan alasan perembesan lebih ringan di sini daripada dalam game
Mengemas gambar berdampingan memungkinkan pengambil sampel melampaui batas ikon dan menarik warna tetangga. Dalam engine game, ini bahaya umum yang terus ada karena tekstur diperkecil, dibuat mipmap, difilter, dan digambar pada transformasi subpiksel sembarang.
Sprite CSS berada dalam lingkungan yang lebih ringan. Tidak ada mipmap, latar biasanya digabungkan pada posisi bilangan bulat, dan pada tepat 1:1 tanpa transformasi, tidak ada pengambilan sampel yang melewati batas sama sekali. Namun "lebih ringan" bukan "tidak pernah", dan masalah muncul pada tempat yang dapat diprediksi: rasio piksel perangkat pecahan (1.5, 2.25, 3), zoom halaman peramban pada persentase tidak lazim, setiap transform: scale() pada elemen leluhur, dan background-size perkecilan dari bagian retina — semuanya menempatkan tepi ikon pada batas piksel perangkat bukan bilangan bulat, sehingga kompositor harus melakukan interpolasi.
Perbaikannya sama dan murah: sisakan celah transparan kecil 2 hingga 4 piksel pada 1x (jadi 4 hingga 8 pada lembar 2x) di antara setiap ikon dan sekitar tepi luar lembar. Tambahan ukuran berkas sangat kecil dan menghilangkan seluruh kelompok laporan bug "ada garis samar di kiri ikon hanya pada laptop saya". Versi mendalam masalah ini — ekstrusi, perembesan mipmap, ukuran pangkat dua — dibahas untuk engine game dalam Pengemasan Atlas Sprite: Padding, Pangkat Dua, dan Rembesan Warna.
Pola kegagalan umum
- Ikon tetangga terlihat pada tepian. Kotak elemen lebih besar daripada ikon, sehingga jendela memperlihatkan konten lembar di luarnya. Lebar/tinggi salah atau padding elemen memperbesar kotak — periksa apakah box-sizing: border-box digunakan, karena mengubah apa yang tercakup dalam lebar yang dinyatakan.
- Lupa background-repeat: no-repeat. Nilai bawaan adalah repeat, sehingga lembar berulang dan potongan ikon lain memenuhi kotak. Hal ini mudah terlewat ketika ikon kebetulan berada dekat titik awal lembar dan tampak hampir benar.
- Span tanpa ukuran. Elemen sebaris mengabaikan width dan height sepenuhnya, sehingga <span> dengan kelas sprite menyusut menjadi ukuran nol dan tidak ada yang dirender. Atur display: inline-block (atau block, atau jadikan elemen flex) pada kelas dasar.
- Lembar lama setelah build ulang. Anda mengepak ulang sprite, koordinat bergeser, tetapi pengunjung lama masih memiliki sheet lama dalam cache bersama CSS baru — sehingga setiap ikon sedikit salah bagi mereka, tetapi sempurna bagi Anda. Perbarui cache dengan mengubah nama file pada setiap build ulang (hash konten, sprite.a1b2c3.png) alih-alih mengandalkan string kueri atau meminta pengguna memuat ulang tanpa cache.
- Offset setengah piksel. Ukuran ikon, celah, atau margin awal ganjil pada lembar 2x menghasilkan offset pecahan setelah dibagi dua, dan offset pecahan justru menyebabkan pinggiran. Pertahankan semua dimensi lembar 2x genap.
Pertanyaan yang sering diajukan
Apakah sprite CSS sudah usang pada 2026?
Alasan awal usang; tekniknya tidak. Pada HTTP/2 dan HTTP/3, mengurangi jumlah permintaan bukan alasan kuat sendiri. Yang bertahan adalah kumpulan banyak grafis raster kecil, dengan satu entri cache, versi atomik, tanpa kemunculan per ikon, dan hover seketika tetap bermanfaat. Namun untuk ikon UI monokrom, SVG benar-benar menggantikan sprite raster — menggunakannya pada 2026 berarti memilih alat lebih buruk.
Sprite CSS atau sprite SVG — mana yang sebaiknya digunakan?
Tentukan berdasarkan karya, bukan cara pengiriman. Jika ikon Anda datar, geometris, dan monokrom atau dua warna, gunakan sprite SVG: skalanya berubah tanpa lembar 2x, warnanya diubah melalui currentColor, dan berada di DOM sehingga dapat dijangkau teknologi bantu. Jika gambar Anda berupa foto, banyak menggunakan gradasi, atau memang merupakan seni raster multicolor — bendera, gambar mini produk, logo platform, seni piksel — SVG tidak memberikan manfaat, dan sprite CSS raster merupakan pilihan yang tepat.
Seberapa besar satu lembar sebelum menimbulkan masalah?
Ada dua batas terpisah. Secara praktis: sheet menahan rendering setiap ikon di dalamnya. Jika ukurannya sampai menunda tampilan pertama, sheet tersebut tidak lagi membantu — pertahankan ukurannya di kisaran beberapa ratus kilobyte rendah, dan pisahkan ikon yang jarang digunakan (layar admin, panel pengaturan) ke sheet kedua yang hanya dimuat saat diperlukan. Secara teknis: browser dan perangkat seluler membatasi dimensi gambar terdekode serta total memori kanvas. Sheet sangat besar dapat diperkecil diam-diam atau gagal didekode pada ponsel bermemori rendah. Sheet dengan sisi lebih dari sekitar 2000 piksel layak dipecah atas alasan itu saja. Ingat bahwa sheet 2x sudah memiliki dua kali dimensi yang Anda desain.
Bisakah saya mewarnai ulang ikon sprite dengan CSS?
Tidak sungguh-sungguh, dan inilah jawaban jujur, bukan yang nyaman. Warna tertanam dalam berkas raster. Anda dapat mendekatinya dengan filter — merangkai invert, sepia, saturate, dan hue-rotate untuk mengarahkan ikon hitam ke rona target — tetapi ini memang solusi tambalan: nilainya ditemukan melalui coba-coba atau solver, tidak menghasilkan warna merek yang tepat, gagal pada gambar beragam warna, dan sulit dipahami orang berikutnya yang menangani kode. Sheet kedua dengan warna alternatif lebih tepat daripada rangkaian filter. Jika pewarnaan ulang benar-benar diperlukan, kebutuhan itu menunjukkan bahwa Anda sebaiknya memakai SVG.
Kemas ikon Anda menjadi lembar sprite
Sprite Gen mengambil gambar yang dimasukkan, mengemasnya dalam satu lembar dengan ruang tambahan pilihan, dan menulis koordinat sehingga Anda tidak perlu membaca offset dari canvas manual. Pilih CSS untuk mendapatkan aturan dasar bersama yang memuat background-image, background-repeat: no-repeat dan display: inline-block, ditambah satu aturan per sprite dengan nilai negatif background-position dan lebar serta tinggi piksel — persis struktur yang dijelaskan di atas. Pilih SCSS dan keluaran yang sama hadir sebagai %sprite-base placeholder dengan setiap aturan ikon memasukkannya melalui @extend. Pilih JSON untuk mendapatkan koordinat bingkai mentah, yang dapat digunakan oleh alat Anda sendiri. Semuanya berjalan di peramban Anda — tidak ada yang diunggah ke mana pun.
Buka Pembuat Lembar Sprite