Transformasi menggeser, menskalakan, memutar, dan memiringkan elemen melalui properti transform tanpa menyentuh alur dokumen di sekelilingnya. Topik ini membahas fungsi transformasi yang paling sering digunakan, titik poros melalui transform-origin, alasan transformasi tidak memicu perhitungan ulang layout, perbedaan ringkas transformasi 2D dan 3D, serta pengenalan compositing yang menjadikan transformasi murah bagi browser. Setelah membacanya, elemen dapat digerakkan secara visual dengan biaya yang dapat diprediksi.
Properti transform dan urutan fungsinya#
Properti transform menerima satu atau lebih fungsi transformasi yang ditulis berurutan dalam satu deklarasi. Nilai bawaannya adalah none, dan keseluruhan nilai dihitung menjadi satu matriks sebelum diterapkan pada elemen. Urutan penulisannya menentukan hasil akhir, karena fungsi yang ditulis paling kanan diterapkan pada elemen lebih dahulu, kemudian fungsi di sebelah kirinya bekerja pada hasilnya.
Perbedaan urutan paling mudah terlihat pada kombinasi putaran dan geseran. Contoh berikut memuat fungsi yang sama pada dua kartu dengan urutan yang dibalik:
/* Elemen digeser sepanjang sumbunya terlebih dahulu,
kemudian seluruh hasil geseran diputar 45 derajat */
.kartu-a {
transform: rotate(45deg) translateX(80px);
}
/* Elemen diputar pada tempatnya,
kemudian digeser sejajar sumbu aslinya */
.kartu-b {
transform: translateX(80px) rotate(45deg);
}Kedua deklarasi memuat fungsi yang sama, tetapi hasil visualnya berbeda. Pada deklarasi pertama, arah geseran ikut diputar sehingga kartu berpindah menyudut, sedangkan pada deklarasi kedua kartu berpindah lurus ke kanan lalu berputar di posisi barunya. Kaidah praktisnya, urutan fungsi dibaca sebagai proses dari kanan ke kiri, sehingga penulisannya perlu direncanakan sebagaimana urutan perubahan yang diinginkan.
Fungsi translate, scale, rotate, dan skew#
Fungsi translate(x, y) menggeser elemen sepanjang sumbu horizontal dan vertikal, dengan varian translateX() dan translateY() untuk satu sumbu saja. Persentase pada translate dihitung dari ukuran elemen itu sendiri, sehingga translateX(50%) berarti setengah lebar elemen tersebut, bukan setengah lebar induknya. Fungsi scale(x, y) mengubah skala dengan nilai 1 sebagai ukuran semula. Fungsi rotate(sudut) memutar dengan satuan deg, dan sudut positif berputar searah jarum jam, sedangkan skew(x, y) memiringkan sumbu elemen sesuai sudut yang diberikan.
.tergeser { transform: translate(24px, -8px); }
.terperbesar { transform: scale(1.2); }
.terputar { transform: rotate(10deg); }
.termiring { transform: skew(-6deg, 2deg); }Tiga fungsi pertama adalah tulang punggung gerak antarmuka, sedangkan skew lebih jarang digunakan karena kemiringannya sulit dipadukan dengan tipografi. Diagram berikut memperlihatkan hasil translate, scale, dan rotate pada kotak yang sama, dengan kotak putus-putus sebagai keadaan semula:
Satu deklarasi transform boleh menggabungkan fungsi-fungsi di atas, misalnya transform: translate(0, -2px) scale(1.05) untuk kartu yang disorot. Penggabungan seperti ini diperlukan karena properti transform hanya menyimpan satu nilai, sehingga deklarasi berikutnya menimpa deklarasi sebelumnya dan bukan menambahkannya.
Titik poros dengan transform-origin#
Fungsi rotate dan scale bekerja mengelilingi titik poros yang ditetapkan transform-origin. Nilai bawaannya adalah tengah elemen, yaitu 50% 50%, sehingga rotasi terlihat berputar pada tempatnya dan penskalaan melebar ke segala arah. Titik poros dapat dipindahkan menggunakan kata kunci seperti top left, panjang seperti 0 0, atau persentase, dan perubahan ini mengubah hasil visual rotate serta scale tanpa perlu mengubah nilai transformasinya. Fungsi skew juga berporos pada titik yang sama, sehingga arah kemiringannya mengikuti poros yang dipilih.
.stiker-tanggal {
transform-origin: top left;
transform: rotate(6deg);
}Pada contoh di atas, stiker tanggal berputar mengelilingi sudut kiri atasnya, sehingga ujung kanannya bergeser lebih jauh daripada apabila porosnya berada di tengah. Fungsi translate tidak terpengaruh titik poros karena geseran tidak melibatkan putaran. Ketika elemen dianimasikan dari rotate(0deg) ke rotate(10deg), posisi poros menentukan lintasan visualnya, sehingga poros ditetapkan bersamaan dengan perancangan geraknya. Untuk kasus dua dimensi, dua nilai poros sudah mencakup seluruh kebutuhan, sedangkan nilai ketiga menyertai transformasi 3D.
Transformasi tidak memicu reflow#
Perubahan pada properti seperti margin atau top mengubah geometri elemen dan memaksa browser menghitung ulang posisi tetangganya, yaitu proses yang disebut reflow. Transformasi berbeda, karena elemen digambar secara visual pada tempat barunya, sedangkan kotak aslinya tetap menempati tempat yang sama dalam layout. Tetangga tidak bergeser, teks tidak terbungkus ulang, dan tinggi halaman tidak berubah sama sekali.
Sifat ini menjadikan transformasi pilihan alami untuk gerak seperti sorotan hover dan pemberitahuan yang masuk. Elemen yang digeser dengan translate() juga dapat menutupi elemen lain karena bergerak di atasnya secara visual, berbeda dari margin yang mendorong tetangganya. Akibat sampingnya ada satu, dan catatan berikut menjelaskannya:
Transformasi 2D dan 3D secara singkat#
Seluruh fungsi di atas bekerja pada bidang dua dimensi, yaitu sumbu horizontal dan vertikal. CSS juga menyediakan fungsi 3D seperti translateZ(), rotateX(), dan rotateY(), yang menggerakkan elemen pada sumbu kedalaman. Efek perspektifnya baru terlihat apabila dipadukan dengan properti perspective atau fungsi perspective(), yang menetapkan jarak mata pengamat ke bidang elemen.
Di balik layar, browser menghitung seluruh kombinasi fungsi tersebut menjadi satu matriks, sehingga performa deklarasi yang panjang tidak berbeda dari yang pendek. Struktur elemen bersarang yang bertransformasi 3D diatur oleh properti transform-style, dengan nilai bawaan flat yang meratakan keturunannya ke bidang, sedangkan preserve-3d menjaga kedalaman struktur bersarangnya. Untuk kebutuhan antarmuka umum, fungsi 2D sudah mencakup hampir semua kasus. Transformasi 3D biasanya digunakan untuk flip kartu, karosel, atau efek kedalaman yang memang dirancang khusus, dan efek semacam itu perlu diuji pada perangkat nyata karena pada layar kecil mudah terasa berlebihan.
Compositing dan peran GPU#
Browser membagi halaman menjadi lapisan yang masing-masing digambar secara terpisah, kemudian proses yang disebut compositing menyusun lapisan-lapisan itu menjadi satu gambar akhir. Penyusunan ini didelegasikan ke GPU, yaitu unit pemrosesan grafis yang dirancang untuk memindahkan dan menumpuk gambar dengan sangat cepat. Elemen yang dianimasikan dengan transform atau opacity umumnya diberi lapisan tersendiri, sehingga perubahan nilainya tidak mengulang layout maupun paint, yaitu pengisian ulang piksel lapisan.
Akibatnya, menggerakkan elemen dengan transformasi hanya mengubah posisi lapisan yang sudah digambar, dan biayanya hampir tidak terpengaruh ukuran halaman. Inilah alasan gerak antarmuka sebaiknya dibangun di atas transform dan opacity selama mungkin, karena keduanya ditangani tanpa menyentuh perhitungan layout maupun pengisian piksel. Keputusan yang sama menjadi tolok ukur ketika membandingkan properti mana pun yang ingin dianimasikan.
Kesalahan umum#
Kesalahan pertama adalah memberi transformasi pada elemen inline seperti span atau a. Transformasi hanya berlaku pada elemen yang kotaknya dapat ditransformasikan, antara lain elemen block, inline-block, elemen pengganti (replaced element) seperti img, serta item flex dan grid. Perbaikannya, ubah display elemen inline menjadi inline-block terlebih dahulu agar transformasinya berlaku.
Kesalahan kedua adalah mengharapkan dua deklarasi transform terpisah saling menambah. Properti transform menyimpan satu nilai saja, sehingga deklarasi berikutnya menimpa yang sebelumnya dan salah satu gerakannya hilang. Perbaikannya, gabungkan seluruh fungsi dalam satu deklarasi, misalnya transform: translate(12px, 0) rotate(8deg).
Kesalahan ketiga adalah salah membaca persentase pada translate. Nilai translateX(50%) dihitung dari lebar elemen itu sendiri, bukan dari lebar induknya, sehingga elemen sempit bergeser lebih pendek daripada elemen lebar dengan deklarasi yang sama. Perbaikannya, gunakan satuan piksel atau satuan viewport seperti vw bila perpindahan yang diinginkan relatif terhadap lingkungannya.
Ringkasan#
- Properti
transformmenerima deretan fungsi yang diterapkan dari kanan ke kiri, sehingga urutan penulisannya memengaruhi hasil visual. - Fungsi
translate(),scale(),rotate(), danskew()mengubah tampilan elemen tanpa menggeser tetangganya dan tanpa memicu reflow. transform-originmenetapkan titik poros rotate dan scale dengan nilai bawaan tengah elemen, sedangkan translate tidak terpengaruh.- Transformasi dan opacity ditangani melalui compositing yang didelegasikan ke GPU, sehingga keduanya menjadi dasar gerak yang murah.
Referensi#
- CSS transforms — MDN — Ikhtisar modul transformasi CSS beserta daftar fungsinya.
- transform — MDN — Rujukan resmi properti transform dan urutan penggabungan fungsinya.
- transform-origin — MDN — Rujukan resmi titik poros transformasi beserta nilai yang diterimanya.
- Learn CSS — web.dev — Kursus resmi yang membahas transformasi dalam konteks CSS menyeluruh.