Tutorial CSS / Transformasi dan Transisi CSS: Urutan, Titik Acuan, dan Fokus

Transformasi memindahkan, memutar, atau mengubah skala tampilan kotak yang dirender tanpa mengubah aliran konten di sekitarnya. Transisi menganimasikan perubahan antara nilai properti, jadi pilih properti dan waktunya dengan sengaja serta sediakan alternatif gerakan yang dikurangi.

Pahami transformasi dan aliran normal

Alur dokumen mengacu pada hubungan antara di mana suatu elemen awalnya ditempatkan dan elemen-elemen di sekitarnya. Bahkan jika Anda memindahkan tombol ke atas ke translateY(-.5rem), paragraf di bawahnya tidak bergerak naik sesuai dengan ruang tempat tombol dipindahkan. Elemen yang diubah dapat tumpang tindih dengan konten di sekitarnya atau keluar dari layar, jadi meninggalkan ruang yang cukup di tempat asalnya adalah prioritas daripada meningkatkan jarak pergerakan.

fungsi Contoh Hasil untuk Diamati
translate() translate(1rem, -.5rem) Geser 1rem ke kanan dan .5rem ke atas
rotate() rotate(15deg) Putar mengelilingi titik referensi
scale() scale(1.05) Ditampilkan pada ukuran 1,05 kali ukuran asli

Hanya karena ukurannya terlihat lebih besar tidak berarti ruang yang ditempati oleh kotak sebelum transformasi akan lebih besar. Tinjau aturan Grid atau width untuk mengubah lebar kolom aktual dari kartu, atau gunakan transform untuk membuat efek visual sedikit lebih besar saat ditekan. Kotak inline yang tidak diganti, seperti teks biasa span, tidak dapat ditransformasi, jadi tentukan display: inline-block jika perlu. Definisi target transformasi dan pemrosesan koordinat dapat ditemukan di dokumen MDN transform.

Bandingkan urutan dan asal transformasi

Saat Anda mendaftarkan fungsi transformasi, setiap fungsi membentuk sistem koordinat untuk fungsi berikutnya, dibaca dari kiri ke kanan. Jika koordinat induk dianggap tetap dan suatu titik dihitung, komposisi yang sama dapat dihitung dengan menerapkan fungsi dari kanan ke kiri. Oleh karena itu, translasi/rotasi dan rotasi/translasi umumnya tidak menghasilkan hasil yang sama. Dalam contoh di bawah ini, kotak yang diputar milik A terlihat di tempat di mana telah digeser ke kanan, dan kotak milik B telah bergerak ke arah yang dipengaruhi oleh rotasi dan terlihat lebih jauh ke bawah. Jangan hanya melihat nama fungsi dan menganggap kedua hasilnya sama; bandingkan lokasi sebenarnya.

Pusat rotasi dan ekspansi diatur ke transform-origin. Jika Anda menggunakan left top sebagai pengganti pusat default, itu akan berputar di sekitar sudut kiri atas. Ini berguna ketika Anda ingin mempertahankan titik tertentu, misalnya saat sebuah menu terbuka, tetapi tumpang tindih dengan konten sekitarnya dapat berubah hanya dengan mengubah titik acuan.

Simpan kode berikut sebagai transform-compare.html dalam UTF-8 dan buka di browser Anda. Tidak diperlukan file atau pustaka eksternal.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Transform order and origin</title>
  <style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; padding: 1rem; color: #183044; font-family: sans-serif; line-height: 1.6; }
main { max-width: 46rem; margin-inline: auto; }
h1 { font-size: 1.5rem; } h2 { font-size: 1.2rem; }
button, input { font: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 3px solid #164f73; outline-offset: 3px; }
.comparisons { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr)); gap: 1rem; }
.slot { padding: 1rem; border: 1px solid #8a9ba7; }
.frame { height: 9rem; display: grid; place-items: center; background: #f0f2f4; }
.box { width: 4rem; height: 2rem; display: grid; place-items: center; background: #166b92; color: white; }
.first { transform: translateX(2rem) rotate(45deg); }
.second { transform: rotate(45deg) translateX(2rem); }
.center { transform: rotate(30deg); transform-origin: center; }
.corner { transform: rotate(30deg); transform-origin: left top; }
  </style>
</head>
<body>
<main>
<h1>The same value also varies depending on the order and reference point</h1>
<div class="comparisons">
  <section class="slot"><h2>Translate, then rotate</h2><div class="frame"><div class="box first">A</div></div></section>
  <section class="slot"><h2>Rotate, then translate</h2><div class="frame"><div class="box second">B</div></div></section>
  <section class="slot"><h2>Center origin</h2><div class="frame"><div class="box center">C</div></div></section>
  <section class="slot"><h2>Top-left origin</h2><div class="frame"><div class="box corner">D</div></div></section>
</div>
</main>
</body>
</html>
  1. Bandingkan posisi A dan B. Jika Anda mengubah urutan fungsi .second agar sama dengan A, kedua kotak akan memiliki perpindahan yang sama relatif terhadap bingkainya. Setelah konfirmasi, kembalikan ke urutan semula.
  2. C dan D memiliki sudut rotasi yang sama. Ubah hanya transform-origin dari .corner ke center, periksa perbedaan pada titik referensi, dan kembalikan ke left top.
  3. Bandingkan perbesaran dengan hanya mengubah rotasi C ke scale(1.2). Area di luar kotak akan membesar, tetapi area sekitarnya tidak akan dipindahkan. Setelah dikonfirmasi, kembalikan ke rotate(30deg).

Pilih properti dan waktu transisi

transition tidak mengubah keadaan dengan sendirinya. Perubahan hanya dimulai saat nilai CSS berubah saat hover, fokus, atau perubahan kelas. Tentukan nama properti yang akan dipengaruhi, durasi, kurva progresi, dan penundaan awal; jika penundaan diabaikan, defaultnya adalah 0 detik.

transition: transform 180ms ease 0ms, background-color 180ms ease 0ms;

Di sini, 180ms adalah 0,18 detik, dan ease adalah kurva yang menghubungkan awal dan akhir secara halus daripada hanya bergerak pada kecepatan yang sama. linear berubah dengan laju konstan. Gunakan waktu yang singkat dan tanpa penundaan terlebih dahulu, kemudian sesuaikan sesuai kebutuhan. Menambahkan penundaan panjang pada tombol yang tampaknya tidak responsif dapat membuat sulit untuk memperhatikan hasil tindakan Anda.

Menempatkan transition pada aturan dasar memungkinkan ia beroperasi saat memasuki dan meninggalkan keadaan tersebut. Transisi yang dideklarasikan hanya pada :hover menghilang saat hover berakhir dan dapat menghasilkan pengembalian yang berbeda. Beri nama properti secara sengaja alih-alih menggunakan all. Contoh ini menransisikan transform dan background-color; tidak setiap properti berinterpolasi dengan cara yang sama. Untuk detail lebih lanjut, lihat dokumen transisi MDN.

Uji hover dan fokus keyboard

Simpan kode di bawah ini sebagai transition-state.html. Saat Anda mengarahkan kursor ke tombol atau menggunakan tombol Tab, tombol akan naik dan warna latar belakangnya berubah. Fokus keyboard ditandai dengan garis tepi biru gelap tersendiri. Tombol ini hanya untuk tujuan latihan untuk mengamati perubahan status, dan tidak ada aksi tambahan yang dilakukan setelah menekan tombol.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Transforms and state transitions exercise</title>
  <style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; padding: 1rem; color: #183044; font-family: sans-serif; line-height: 1.6; }
main { max-width: 46rem; margin-inline: auto; }
h1 { font-size: 1.5rem; } h2 { font-size: 1.2rem; }
button, input { font: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 3px solid #164f73; outline-offset: 3px; }
.stage { padding: 2rem 1rem; border: 2px dashed #8a9ba7; }
.action { padding: .75rem 1.25rem; border: 1px solid #166b92; border-radius: .4rem;
  color: #183044; background: #eaf4fa; transform: translateY(0);
  transition: transform 180ms ease, background-color 180ms ease; }
.action:hover, .action:focus-visible { transform: translateY(-.5rem); background: #cfe8f4; }
.neighbor { margin-block: 1rem 0; padding: .75rem; background: #f0f2f4; }
@media (prefers-reduced-motion: reduce) {
  .action { transition: none; }
  .action:hover, .action:focus-visible { transform: none; }
}
  </style>
</head>
<body>
<main>
<h1>The paragraph stays in place as the button moves</h1>
<p>Hover over the button or press Tab to focus it.</p>
<div class="stage">
  <button class="action" type="button">Check state</button>
  <p class="neighbor">This paragraph stays in place when the button is transformed.</p>
</div>
</main>
</body>
</html>
  1. Ingat posisi atas paragraf di bawah ini dan arahkan kursor ke tombol. Hanya tombol yang bergerak dan paragraf harus tetap pada tempatnya.
  2. Ubah durasi di dua tempat dari 180ms menjadi 800ms untuk mengamati masuk dan kembali, lalu kembalikan ke nilai semula.
  3. Biarkan waktu apa adanya dan ubah hanya kurva progres menjadi linear untuk perbandingan. Kemudian kembalikan ke ease.
  4. Kita hanya menambahkan penundaan 400ms di akhir bagian transform pada deklarasi transition: transform 180ms ease 400ms, background-color 180ms ease. Warna latar mulai berubah tanpa penundaan, sedangkan gerakan menunggu 400ms. Setelah membandingkan, hapus penundaan itu.
  5. Fokus pada tombol dengan tombol Tab dan keluar dengan Shift+Tab. Pastikan garis tepi fokus dan warna latar menggambarkan status operasi.

Kurangi gerakan dan periksa efek samping

Jika pengguna telah mengaturnya untuk mengurangi gerakan, aturan dalam blok prefers-reduced-motion: reduce pada contoh ini menghilangkan gerakan, menyisakan warna latar dan tanda fokus. Jika Anda hanya menghapus transisi, perubahan akan terjadi segera, tetapi posisi akhir yang Anda tuju akan tetap. Dalam contoh di atas, kami memutuskan bahwa gerakan dekoratif itu sendiri tidak diperlukan, jadi bahkan transformasi hover dan fokus diubah menjadi none. Silakan merujuk ke panduan pengaturan pengurangan gerakan MDN.

Bandingkan kedua keadaan dengan mengubah pengaturan sistem operasi Anda atau mereproduksi karakteristik media di panel Rendering pada alat pengembang browser Anda. Dalam pengaturan yang dikurangi, tombol seharusnya tidak bergerak, hanya warna dan indikator fokus yang harus berubah. Saat Anda selesai dengan latihan, kembalikan emulasi ke keadaan default.

Sebuah transform yang bukan none menciptakan konteks penumpukan dan dapat menetapkan blok kontainer untuk elemen turunan dengan position: absolute atau fixed. Jika sebuah popup atau elemen tetap berperilaku tidak terduga, periksa elemen leluhur yang ditransformasi. Juga periksa tumpang tindih, fokus keyboard, dan gerakan yang dikurangi; transisi yang mulus saja belum menjamin tata letak dapat digunakan dengan baik. Lihat CSS position: relative, absolute, fixed, dan sticky, CSS z-index dan Stacking Contexts.