Transisi menganimasikan perubahan gaya secara bertahap, sehingga elemen berpindah dari satu keadaan (state) ke keadaan lainnya melalui deretan nilai perantara alih-alih melompat seketika. Topik ini membahas empat properti transisi beserta penulisan ringkasnya, pilihan fungsi easing, cakupan properti yang dapat ditransisikan, dan penerapannya pada umpan balik hover tombol. Setelah membacanya, perubahan gaya pada antarmuka dapat diberi durasi dan kurva kecepatan yang sesuai dengan perannya.
Konsep interpolasi antara dua keadaan#
Transisi bekerja dengan menginterpolasi nilai properti yang berubah, yaitu menghitung nilai-nilai perantara secara bertahap sepanjang durasi yang ditetapkan. Tanpa transisi, browser menggambar hasil akhirnya begitu nilai baru berlaku, sehingga tampilan melompat dalam satu langkah. Dengan transisi, browser menggambar keadaan perantara pada setiap frame, yaitu satu gambar tunggal yang disusun berurutan sehingga membentuk gerakan. Penggambaran ini berlangsung hingga nilai akhir tercapai, sehingga perubahan warna, ukuran, atau posisi terasa bergerak dan tidak mendadak.
Pemicu transisi adalah perubahan nilai yang terjadi setelah elemen dirender pertama kali. Perubahan itu dapat berasal dari pseudo-class seperti :hover dan :focus, penambahan atau penghapusan class dari JavaScript, maupun perubahan atribut seperti checked. Deklarasi transisi ditulis pada keadaan dasar elemen, bukan hanya pada keadaan hover, karena browser membaca aturan transisi dari gaya yang berlaku setelah perubahan terjadi. Konsekuensi pembacaan ini muncul pada kesalahan umum di akhir topik.
Empat properti transisi#
Empat properti dalam bentuk panjang mengendalikan aspek transisi secara terpisah, sedangkan shorthand transition merangkum keempatnya dalam satu deklarasi. Shorthand berarti penulisan ringkas yang menyatakan beberapa properti sekaligus dalam satu baris. Tabel berikut merangkum peran masing-masing properti:
| Properti | Peran |
|---|---|
transition-property | Menentukan properti yang dianimasikan |
transition-duration | Menetapkan lama interpolasi berlangsung |
transition-timing-function | Memilih kurva kecepatan interpolasi |
transition-delay | Menunda mulainya interpolasi |
Pada shorthand, nilai waktu pertama dibaca sebagai durasi dan nilai waktu kedua sebagai delay, sehingga urutannya tidak dapat ditukar. Beberapa properti dianimasikan sekaligus dengan memisahkan tiap kelompok nilai menggunakan koma, sedangkan kata kunci all menyasar seluruh properti yang berubah. Contoh berikut menyatakan konfigurasi transisi yang identik untuk dua tombol, satu dengan bentuk panjang dan satu dengan shorthand:
/* Bentuk panjang: setiap aspek transisi dinyatakan pada propertinya sendiri */
.tombol-simpan {
transition-property: background-color, border-color;
transition-duration: 200ms;
transition-timing-function: ease-out;
}
/* Bentuk shorthand yang setara dengan tiga deklarasi di atas */
.tombol-batal {
transition: background-color 200ms ease-out, border-color 200ms ease-out;
}Properti transition-delay jarang diperlukan untuk umpan balik langsung, tetapi berguna ketika satu perubahan perlu menunggu perubahan lain, misalnya ikon yang baru muncul setelah panel selesai membuka. Nilai delay juga menerima angka negatif, yang menggeser titik mulai interpolasi ke tengah rentang waktunya sehingga animasi terasa sudah berjalan ketika pertama kali terlihat. Pasangan durasi dan delay inilah yang menjadikan urutan penulisan waktu pada shorthand perlu diperhatikan.
Pilihan fungsi easing#
Fungsi easing menentukan laju interpolasi di sepanjang durasinya, yaitu kapan perubahan bergerak cepat dan kapan melambat. Nilai bawaannya adalah ease, sedangkan linear mempertahankan kecepatan yang tetap dari awal hingga akhir. Kecepatan yang tetap terasa kaku untuk perubahan gaya biasa, sehingga linear lebih sering digunakan pada gerakan yang berulang seperti indikator pemuatan. Tabel berikut merangkum karakter setiap nilai:
| Nilai | Karakter gerak |
|---|---|
ease | Kurva bawaan, mirip ease-out dengan awal yang sedikit lebih landai |
linear | Kecepatan tetap dari awal hingga akhir |
ease-in | Lambat di awal, mempercepat mendekati akhir |
ease-out | Cepat di awal, melambat mendekati akhir |
ease-in-out | Lambat pada kedua ujung, cepat di tengah |
cubic-bezier(0.25, 0.1, 0.25, 1) | Kurva kustom melalui dua titik kendali |
Fungsi cubic-bezier(x1, y1, x2, y2) mendefinisikan kurva melalui dua titik kendali, dan kelima kata kunci lainnya sebenarnya merupakan singkatan dari kurva cubic-bezier tertentu. Nilai y pada titik kendali boleh melebihi 1 atau kurang dari 0, sehingga interpolasi dapat melewati nilai akhirnya sejenak dan menghasilkan gerak yang memantul lembut. Terdapat pula fungsi steps(n) yang memecah interpolasi menjadi n lompatan diskrit, tetapi penggunaannya lebih sempit karena hasilnya tidak bergerak mulus. Untuk umpan balik hover, ease-out biasanya dipilih karena perubahan mulai terasa segera setelah kursor tiba, sedangkan ease-in yang lambat di awal membuat tombol terasa tertunda.
Properti yang dapat ditransisikan#
Hanya properti yang nilainya dapat diinterpolasi yang akan beranimasi. Kelompok yang memenuhi syarat itu mencakup panjang dan persentase seperti width, padding, dan border-radius, warna seperti color dan background-color, angka seperti opacity dan z-index, serta transform yang diinterpolasi sebagai satu kesatuan. Daftar lengkap properti yang dapat dianimasikan tercantum pada dokumentasi MDN yang dirujuk di bagian Referensi.
Sebaliknya, properti yang nilainya berupa kata kunci tanpa rentang perantara berpindah seketika. Properti display tidak memiliki nilai antara, sehingga elemen yang disembunyikan dengan display: none muncul tanpa transisi ketika nilainya berubah. Nilai auto juga tidak dapat diinterpolasi, sehingga transisi height dari atau ke auto tidak bergerak dan perlu diganti dengan nilai tetap atau pendekatan lain.
Umpan balik hover yang halus#
Umpan balik hover adalah penerapan transisi yang paling sering ditemui. Tombol formulir yang warnanya berubah seketika terasa kasar, sedangkan tombol yang warnanya mengalir dalam dua ratus milidetik terasa menyala berangsur. Prinsipnya, transisi hanya dideklarasikan untuk properti yang benar-benar berubah saat hover, misalnya warna latar dan warna teks, dengan kurva yang konsisten di seluruh antarmuka.
Demo berikut menampilkan tiga tombol dengan konfigurasi transisi yang berbeda. Tombol pertama menggunakan durasi pendek dengan ease-out, tombol kedua menggunakan durasi panjang dengan ease, dan tombol ketiga menggunakan durasi pendek dengan kurva cubic-bezier kustom. Ketiga tombol sengaja diberi label dan ukuran yang sama agar satu-satunya variabel adalah konfigurasi transisinya. Arahkan kursor ke ketiganya bergantian, lalu amati perbedaan kecepatan dan karakter perubahannya:
Kode sumber demo
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Demo transisi hover tiga tombol</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<main>
<h1>Demo transisi hover</h1>
<p>Ketiga tombol identik, satu-satunya perbedaan adalah konfigurasi transisinya.</p>
<div class="baris">
<section class="sel">
<h2>150 ms, ease-out</h2>
<button type="button" class="tombol cepat">Simpan</button>
</section>
<section class="sel">
<h2>600 ms, ease</h2>
<button type="button" class="tombol lambat">Simpan</button>
</section>
<section class="sel">
<h2>200 ms, cubic-bezier</h2>
<button type="button" class="tombol lentur">Simpan</button>
</section>
</div>
</main>
<style>
/* Gaya demo transisi hover tiga tombol */
body {
font-family: sans-serif;
background-color: #eef2f7;
color: #1f2937;
margin: 0;
padding: 16px;
}
h1 { font-size: 20px; margin: 0 0 6px; }
p { font-size: 13px; margin: 0 0 14px; }
h2 { font-size: 13px; margin: 0 0 8px; font-weight: 700; }
.sel {
display: inline-block;
margin-right: 18px;
}
/* Gaya dasar yang sama untuk ketiga tombol */
.tombol {
padding: 10px 22px;
font-size: 14px;
color: #ffffff;
background-color: #2563eb;
border: none;
border-radius: 8px;
cursor: pointer;
}
/* Durasi pendek: umpan balik yang terasa langsung */
.cepat {
transition: background-color 150ms ease-out;
}
.cepat:hover {
background-color: #1d4ed8;
}
/* Durasi panjang: perubahan yang terasa tertinggal */
.lambat {
transition: background-color 600ms ease;
}
.lambat:hover {
background-color: #1d4ed8;
}
/* Durasi pendek dengan kurva kustom: kecepatan menumpuk di tengah */
.lentur {
transition: background-color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.lentur:hover {
background-color: #1d4ed8;
}
</style>
<style>
/* Gaya demo transisi hover tiga tombol */
body {
font-family: sans-serif;
background-color: #eef2f7;
color: #1f2937;
margin: 0;
padding: 16px;
}
h1 { font-size: 20px; margin: 0 0 6px; }
p { font-size: 13px; margin: 0 0 14px; }
h2 { font-size: 13px; margin: 0 0 8px; font-weight: 700; }
.sel {
display: inline-block;
margin-right: 18px;
}
/* Gaya dasar yang sama untuk ketiga tombol */
.tombol {
padding: 10px 22px;
font-size: 14px;
color: #ffffff;
background-color: #2563eb;
border: none;
border-radius: 8px;
cursor: pointer;
}
/* Durasi pendek: umpan balik yang terasa langsung */
.cepat {
transition: background-color 150ms ease-out;
}
.cepat:hover {
background-color: #1d4ed8;
}
/* Durasi panjang: perubahan yang terasa tertinggal */
.lambat {
transition: background-color 600ms ease;
}
.lambat:hover {
background-color: #1d4ed8;
}
/* Durasi pendek dengan kurva kustom: kecepatan menumpuk di tengah */
.lentur {
transition: background-color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.lentur:hover {
background-color: #1d4ed8;
}
</style></body>
</html>Tombol dengan durasi 150 milidetik terasa langsung menjawab, sedangkan tombol dengan durasi 600 milidetik terasa tertinggal dari gerakan kursor. Tombol ketiga berdurasi sama pendek dengan tombol pertama, tetapi kurvanya menumpuk kecepatan di tengah, sehingga perubahannya terasa lebih lunak. Ketiganya menunjukkan bahwa kode yang hampir sama dapat memberi kesan berbeda hanya melalui durasi dan easing.
Kesalahan umum#
Kesalahan pertama adalah menuliskan transisi hanya di dalam aturan :hover. Perubahan saat kursor masuk dianimasikan, tetapi saat kursor keluar gaya yang berlaku sudah bukan lagi gaya hover, sehingga transisinya tidak terbaca dan tombol kembali ke warna awal secara mendadak. Perbaikannya, deklarasikan transisi pada keadaan dasar elemen, sehingga interpolasi berlaku untuk kedua arah.
Kesalahan kedua adalah membiasakan transition: all. Deklarasi ini menganimasikan setiap properti yang berubah, termasuk yang tidak disengaja, dan menyamakan durasi untuk properti yang karakternya berbeda. Perbaikannya, sebutkan properti secara eksplisit dan beri durasi masing-masing bila perlu. Efek samping lainnya, perubahan yang semestinya seketika seperti pergantian teks, ikut teranimasi dan terasa lambat.
Kesalahan ketiga adalah memberi durasi yang sama panjang untuk semua interaksi. Umpan balik hover yang melebihi setengah detik terasa tertinggal, sedangkan panel besar yang membuka dalam seratus milidetik terasa menyentak. Perbaikannya, sesuaikan durasi dengan besaran perubahan, yaitu pendek untuk interaksi kecil dan lebih panjang untuk perpindahan yang luas.
Ringkasan#
- Transisi menginterpolasi perubahan nilai properti dari keadaan awal ke keadaan akhir, dan pemicunya adalah perubahan gaya apa pun setelah elemen dirender.
- Empat properti panjangnya adalah
transition-property,transition-duration,transition-timing-function, dantransition-delay, sedangkan shorthandtransitionmerangkum keempatnya dengan durasi ditulis sebelum delay. - Nilai easing menentukan kurva kecepatan, dengan
ease-outsebagai pilihan umum untuk umpan balik hover dancubic-bezier()untuk kurva kustom. - Hanya properti dengan nilai yang dapat diinterpolasi yang beranimasi, sedangkan kata kunci seperti
display: nonedan nilaiautoberpindah seketika.
Referensi#
- CSS transitions — MDN — Ikhtisar modul transisi CSS beserta daftar propertinya.
- transition — MDN — Rujukan resmi shorthand transition dan aturan urutan nilai waktunya.
- transition-timing-function — MDN — Rujukan resmi nilai easing, termasuk cubic-bezier() dan steps().
- Learn CSS — web.dev — Kursus resmi yang membahas transisi dalam konteks CSS menyeluruh.