Slider Tak Terbatas CSS Membalik Gambar Polaroid Kecerdasan Data PlatoBlockchain. Pencarian Vertikal. Ai.

CSS Infinite Slider Membalik Melalui Gambar Polaroid

Di artikel terakhir, kami membuat penggeser kecil yang cukup keren (atau "carousel" jika itu yang Anda suka) yang berputar dalam arah melingkar. Kali ini kita akan membuat satu yang membolak-balik setumpuk gambar Polaroid.

Keren kan? Jangan lihat kodenya dulu karena masih banyak yang harus diurai. Bergabunglah dengan saya, ya?

Seri Slider CSS

Pengaturan dasar

Sebagian besar HTML dan CSS untuk penggeser ini mirip dengan yang melingkar yang kami buat terakhir kali. Faktanya, kami menggunakan markup yang sama persis:

Dan ini adalah CSS dasar yang mengatur induk kita .gallery container sebagai kisi tempat semua gambar ditumpuk satu sama lain:

.gallery  {
  display: grid;
  width: 220px; /* controls the size */
}
.gallery > img {
  grid-area: 1 / 1;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border: 10px solid #f2f2f2;
  box-shadow: 0 0 4px #0007;
}

Tidak ada yang rumit sejauh ini. Bahkan untuk gaya seperti Polaroid untuk gambar, yang saya gunakan hanyalah beberapa border dan box-shadow. Anda mungkin dapat melakukannya dengan lebih baik, jadi jangan ragu untuk bermain-main dengan gaya dekoratif tersebut! Kami akan menempatkan sebagian besar fokus kami pada animasi, yang merupakan bagian tersulit.

Apa triknya?

Logika penggeser ini bergantung pada urutan gambar yang ditumpuk - jadi ya, kita akan bermain dengannya z-index. Semua gambar dimulai dengan hal yang sama z-index nilai (2) yang secara logis akan membuat gambar terakhir di atas tumpukan.

Kami mengambil gambar terakhir itu dan menggesernya ke kanan hingga gambar berikutnya muncul di tumpukan. Kemudian kita menurunkan gambarnya z-index nilai kemudian kita geser kembali ke dek. Dan sejak itu z-index nilai lebih rendah dari gambar lainnya, itu menjadi gambar terakhir dalam tumpukan.

Ini adalah demo stripped back yang menunjukkan triknya. Arahkan gambar untuk mengaktifkan animasi:

Sekarang, bayangkan trik yang sama diterapkan pada semua gambar. Inilah polanya jika kita menggunakan :nth-child() pseudo-selector untuk membedakan gambar:

  • Kami geser gambar terakhir (N). Gambar berikutnya terlihat (N - 1).
  • Kami geser gambar berikutnya (N - 1). Gambar berikutnya terlihat (N - 2)
  • Kami geser gambar berikutnya (N - 2). Gambar berikutnya terlihat (N - 3)
  • (Kami melanjutkan proses yang sama hingga mencapai gambar pertama)
  • Kami menggeser gambar pertama (1). gambar terakhir (N) terlihat lagi.

Itulah penggeser tak terbatas kami!

Membedah animasi

Jika Anda ingat artikel sebelumnya, saya hanya mendefinisikan satu animasi dan bermain dengan penundaan untuk mengontrol setiap gambar. Kami akan melakukan hal yang sama di sini. Pertama mari kita coba memvisualisasikan garis waktu animasi kita. Kami akan mulai dengan tiga gambar, lalu menggeneralisasikannya nanti untuk nomor berapa pun (N) dari gambar.

CSS Infinite Slider Membalik Melalui Gambar Polaroid

Animasi kami dibagi menjadi tiga bagian: "geser ke kanan", "geser ke kiri" dan "jangan bergerak". Kami dapat dengan mudah mengidentifikasi penundaan antara setiap gambar. Jika kita menganggap bahwa gambar pertama dimulai pada 0s, dan durasinya sama dengan 6s, maka yang kedua akan dimulai pada -2s dan yang ketiga di -4s.

.gallery > img:nth-child(2) { animation-delay: -2s; } /* -1 * 6s / 3 */
.gallery > img:nth-child(3) { animation-delay: -4s; } /* -2 * 6s / 3 */

Kita juga dapat melihat bahwa bagian "jangan bergerak" mengambil dua pertiga dari keseluruhan animasi (2*100%/3) sedangkan bagian "geser ke kanan" dan "geser ke kiri" menyatukan sepertiganya โ€” jadi, masing-masing sama dengan 100%/6 dari total animasi.

Kami dapat menulis keyframe animasi kami seperti ini:

@keyframes slide {
  0%     { transform: translateX(0%); }
  16.67% { transform: translateX(120%); }
  33.34% { transform: translateX(0%); }
  100%   { transform: translateX(0%); } 
}

Bahwa 120% adalah nilai arbitrer. Saya membutuhkan sesuatu yang lebih besar dari 100%. Gambar harus digeser ke kanan jauh dari gambar lainnya. Untuk melakukan itu, setidaknya perlu bergerak 100% dari ukurannya. Itu sebabnya saya pergi 120% - untuk mendapatkan ruang ekstra.

Sekarang kita perlu mempertimbangkan z-index. Jangan lupa bahwa kita perlu memperbarui gambar z-index nilai setelah itu meluncur ke kanan tumpukan, dan sebelum kami menggesernya kembali ke bagian bawah tumpukan.

@keyframes slide {
  0%     { transform: translateX(0%);   z-index: 2; }
  16.66% { transform: translateX(120%); z-index: 2; }
  16.67% { transform: translateX(120%); z-index: 1; } /* we update the z-order here */
  33.34% { transform: translateX(0%);   z-index: 1; }
  100%   { transform: translateX(0% );  z-index: 1; }  
}

Alih-alih mendefinisikan satu negara bagian di 16.67% (100%/6) di garis waktu, kami mendefinisikan dua status pada titik yang hampir identik (16.66% dan 16.67%) Dimana z-index nilai berkurang sebelum kita menggeser kembali gambar kembali ke geladak.

Inilah yang terjadi ketika kita menarik semua itu bersama-sama:

Hmmm, bagian geser sepertinya berfungsi dengan baik, tapi urutan susunnya acak-acakan! Animasi dimulai dengan baik karena gambar atas bergerak ke belakangโ€ฆ tetapi gambar selanjutnya tidak mengikuti. Jika Anda perhatikan, gambar kedua dalam urutan kembali ke atas tumpukan sebelum gambar berikutnya berkedip di atasnya.

Kita perlu mengikuti dengan cermat z-index perubahan. Awalnya, semua gambar memiliki z-index: 2. Itu berarti urutan susun harus pergi ...

Our eyes ๐Ÿ‘€ --> 3rd (2) | 2nd (2) | 1st (2)

Kami menggeser gambar ketiga dan memperbaruinya z-index untuk mendapatkan pesanan ini:

Our eyes ๐Ÿ‘€ --> 2nd (2) | 1st (2) | 3rd (1)

Kami melakukan hal yang sama dengan yang kedua:

Our eyes ๐Ÿ‘€ --> 1st (2) | 3rd (1) | 2nd (1)

โ€ฆdan yang pertama:

Our eyes ๐Ÿ‘€ --> 3rd (1) | 2nd (1) | 1st (1)

Kami melakukan itu dan semuanya tampak baik-baik saja. Tapi kenyataannya, tidak! Saat gambar pertama dipindahkan ke belakang, gambar ketiga akan memulai iterasi lain, artinya kembali ke z-index: 2:

Our eyes ๐Ÿ‘€ --> 3rd (2) | 2nd (1) | 1st (1)

Jadi, pada kenyataannya kami tidak pernah memiliki semua gambar z-index: 2 sama sekali! Saat gambar tidak bergerak (yaitu, bagian "jangan bergerak" dari animasi) z-index is 1. Jika kita geser gambar ketiga dan perbarui z-index nilai dari 2 untuk 1, itu akan tetap di atas! Ketika semua gambar memiliki yang sama z-index, yang terakhir dalam urutan sumber โ€” gambar ketiga kita dalam hal ini โ€” ada di atas tumpukan. Menggeser hasil gambar ketiga sebagai berikut:

Our eyes ๐Ÿ‘€ --> 3rd (1) | 2nd (1) | 1st (1)

Gambar ketiga masih di atas dan, tepat setelahnya, kami memindahkan gambar kedua ke atas saat animasi dimulai ulang pada z-index: 2:

Our eyes ๐Ÿ‘€ --> 2nd (2) | 3rd (1) | 1st (1)

Setelah kita geser, kita mendapatkan:

Our eyes ๐Ÿ‘€ --> 3rd (1) | 2nd (1) | 1st (1)

Kemudian gambar pertama akan melompat ke atas:

Our eyes ๐Ÿ‘€ --> 1st(2) | 3rd (1) | 2nd (1)

Oke, saya tersesat. Kalau begitu semua logikanya salah?

Aku tahu, itu membingungkan. Tapi logika kita tidak sepenuhnya salah. Kami hanya perlu sedikit memperbaiki animasinya agar semuanya berjalan seperti yang kami inginkan. Caranya adalah dengan mengatur ulang dengan benar z-index.

Mari kita ambil situasi di mana gambar ketiga berada di atas:

Our eyes ๐Ÿ‘€ -->  3rd (2) | 2nd (1) | 1st (1)

Kami melihat bahwa menggeser gambar ketiga dan mengubahnya z-index menyimpannya di atas. Yang perlu kita lakukan adalah memperbarui z-index dari gambar kedua. Jadi, sebelum kita menggeser gambar ketiga dari dek, kita perbarui z-index dari gambar kedua ke 2.

Dengan kata lain, kami mengatur ulang z-index gambar kedua sebelum animasi berakhir.

Membuat diagram bagian animasi dengan indikator di mana indeks-z dinaikkan atau diturunkan.
CSS Infinite Slider Membalik Melalui Gambar Polaroid

Simbol tambah hijau melambangkan peningkatan z-index untuk 2, dan simbol minus merah berkorelasi dengan z-index: 1. Gambar kedua dimulai dengan z-index: 2, lalu kami perbarui menjadi 1 saat meluncur menjauh dari geladak. Tapi sebelum gambar pertama menjauh dari geladak, kami mengubah z-index dari gambar kedua kembali ke 2. Ini akan memastikan kedua gambar memiliki kesamaan z-index, tapi tetap saja yang ketiga akan tetap di atas karena muncul nanti di DOM. Tapi setelah slide gambar ketiga dan nya z-index diperbarui, itu bergerak ke bawah.

Ini dua pertiga melalui animasi, jadi mari perbarui keyframe kita sesuai:

@keyframes slide {
  0%     { transform: translateX(0%);   z-index: 2; }
  16.66% { transform: translateX(120%); z-index: 2; }
  16.67% { transform: translateX(120%); z-index: 1; } /* we update the z-order here */
  33.34% { transform: translateX(0%);   z-index: 1; }
  66.33% { transform: translateX(0%);   z-index: 1; }
  66.34% { transform: translateX(0%);   z-index: 2; } /* and also here */
  100%   { transform: translateX(0%);   z-index: 2; }  
}

Sedikit lebih baik, tapi tetap saja tidak agak di sana. Ada masalah lainโ€ฆ

Oh tidak, ini tidak akan pernah berakhir!

Jangan khawatir, kami tidak akan mengubah bingkai kunci lagi karena masalah ini hanya terjadi jika gambar terakhir terlibat. Kita dapat membuat animasi keyframe "khusus" khusus untuk gambar terakhir untuk memperbaiki keadaan.

Saat gambar pertama berada di atas, kami memiliki situasi berikut:

Our eyes ๐Ÿ‘€ -->  1st (2) | 3rd (1) | 2nd (1)

Mempertimbangkan penyesuaian sebelumnya yang kami buat, gambar ketiga akan melompat di atas sebelum gambar pertama meluncur. Ini hanya terjadi dalam situasi ini karena gambar berikutnya yang bergerak setelah gambar pertama adalah terakhir gambar yang memiliki urutan lebih tinggi di DOM. Sisa gambar baik-baik saja karena kita punya N, kemudian N - 1, lalu kita pergi dari 3 untuk 2, dan 2 untuk 1โ€ฆ tapi kemudian kita pergi dari 1 untuk N.

Untuk menghindarinya, kami akan menggunakan keyframe berikut untuk gambar terakhir:

@keyframes slide-last {
  0%     { transform: translateX(0%);   z-index: 2;}
  16.66% { transform: translateX(120%); z-index: 2; }
  16.67% { transform: translateX(120%); z-index: 1; } /* we update the z-order here */
  33.34% { transform: translateX(0%);   z-index: 1; }
  83.33% { transform: translateX(0%);   z-index: 1; }
  83.34% { transform: translateX(0%);   z-index: 2; } /* and also here */
  100%   { transform: translateX(0%);   z-index: 2; }
}

Kami mengatur ulang z-index nilai 5/6 melalui animasi (bukan dua pertiga) yaitu saat gambar pertama keluar dari tumpukan. Jadi kami tidak melihat adanya lompatan!

TADA! Penggeser tak terbatas kami sekarang sempurna! Inilah kode terakhir kami dengan segala kemegahannya:

.gallery > img {
  animation: slide 6s infinite;
}
.gallery > img:last-child {
  animation-name: slide-last;
}
.gallery > img:nth-child(2) { animation-delay: -2s; } 
.gallery > img:nth-child(3) { animation-delay: -4s; }

@keyframes slide {
  0% { transform: translateX(0%); z-index: 2; }
  16.66% { transform: translateX(120%); z-index: 2; }
  16.67% { transform: translateX(120%); z-index: 1; } 
  33.34% { transform: translateX(0%); z-index: 1; }
  66.33% { transform: translateX(0%); z-index: 1; }
  66.34% { transform: translateX(0%); z-index: 2; } 
  100% { transform: translateX(0%); z-index: 2; }
}
@keyframes slide-last {
  0% { transform: translateX(0%); z-index: 2; }
  16.66% { transform: translateX(120%); z-index: 2; }
  16.67% { transform: translateX(120%); z-index: 1; }
  33.34% { transform: translateX(0%); z-index: 1; }
  83.33% { transform: translateX(0%); z-index: 1; }
  83.34% { transform: translateX(0%); z-index: 2; } 
  100%  { transform: translateX(0%); z-index: 2; }
}

Mendukung sejumlah gambar

Sekarang animasi kita berfungsi untuk tiga gambar, mari buat itu berfungsi untuk angka berapa pun (N) dari gambar. Tapi pertama-tama, kita bisa sedikit mengoptimalkan pekerjaan kita dengan memisahkan animasi untuk menghindari redundansi:

.gallery > img {
  z-index: 2;
  animation: 
    slide 6s infinite,
    z-order 6s infinite steps(1);
}
.gallery > img:last-child {
  animation-name: slide, z-order-last;
}
.gallery > img:nth-child(2) { animation-delay: -2s; } 
.gallery > img:nth-child(3) { animation-delay: -4s; }

@keyframes slide {
  16.67% { transform: translateX(120%); }
  33.33% { transform: translateX(0%); }
}
@keyframes z-order {
  16.67%,
  33.33% { z-index: 1; }
  66.33% { z-index: 2; }
}
@keyframes z-order-last {
  16.67%,
  33.33% { z-index: 1; }
  83.33% { z-index: 2; }
}

Jauh lebih sedikit kode sekarang! Kami membuat satu animasi untuk bagian geser dan satu lagi untuk z-index update. Perhatikan bahwa kami menggunakan steps(1) pada z-index animasi. Itu karena saya ingin tiba-tiba mengubah z-index nilai, tidak seperti animasi geser di mana kita ingin gerakan halus.

Sekarang kode lebih mudah dibaca dan dikelola, kami memiliki pandangan yang lebih baik untuk mencari tahu bagaimana mendukung sejumlah gambar. Yang perlu kita lakukan adalah memperbarui penundaan animasi dan persentase keyframe. Penundaannya mudah karena kita dapat menggunakan loop yang sama persis dengan yang kita buat di artikel sebelumnya untuk mendukung banyak gambar di penggeser melingkar:

@for $i from 2 to ($n + 1) {
  .gallery > img:nth-child(#{$i}) {
    animation-delay: calc(#{(1 - $i)/$n}*6s);
  }
}

Itu berarti kita berpindah dari vanilla CSS ke Sass. Selanjutnya, kita perlu membayangkan bagaimana skala garis waktunya N gambar-gambar. Jangan lupa bahwa animasi terjadi dalam tiga fase:

Menampilkan tiga bagian animasi dalam rangkaian garis dengan panah.
CSS Infinite Slider Membalik Melalui Gambar Polaroid

Setelah "geser ke kanan" dan "geser ke kiri", gambar harus tetap diam hingga gambar lainnya melewati urutan. Jadi bagian "jangan bergerak" perlu waktu yang sama dengan (N - 1) sebagai "geser ke kanan" dan "geser ke kiri". Dan dalam satu iterasi, N gambar akan meluncur. Jadi, "geser ke kanan" dan "geser ke kiri" sama-sama mengambil 100%/N dari total garis waktu animasi. Gambar meluncur menjauh dari tumpukan di (100%/N)/2 dan meluncur kembali 100%/N .

Kita dapat mengubah ini:

@keyframes slide {
  16.67% { transform: translateX(120%); }
  33.33% { transform: translateX(0%); }
}

โ€ฆuntuk ini:

@keyframes slide {
  #{50/$n}%  { transform: translateX(120%); }
  #{100/$n}% { transform: translateX(0%); }
}

Jika kita mengganti N dengan 3, kita mendapatkan 16.67% dan 33.33% kapan ada 3 gambar dalam tumpukan. Logikanya sama dengan urutan susun di mana kita akan memiliki ini:

@keyframes z-order {
  #{50/$n}%,
  #{100/$n}% { z-index: 1; }
  66.33% { z-index: 2; }
}

Kami masih perlu memperbarui 66.33% titik. Seharusnya di situlah gambar disetel ulang z-index sebelum akhir animasi. Pada saat yang sama, gambar berikutnya mulai meluncur. Sejak bagian geser mengambil 100%/N, reset harus terjadi pada 100% - 100%/N:

@keyframes z-order {
  #{50/$n}%,
  #{100/$n}% { z-index: 1; }
  #{100 - 100/$n}% { z-index: 2; }
}

Tapi untuk kita z-order-last animasi untuk bekerja, itu harus terjadi sedikit kemudian dalam urutan. Ingat perbaikan yang kami lakukan untuk gambar terakhir? Mengatur ulang z-index nilai perlu terjadi saat gambar pertama keluar dari tumpukan dan bukan saat mulai meluncur. Kita dapat menggunakan alasan yang sama di sini di keyframes kita:

@keyframes z-order-last {
  #{50/$n}%,
  #{100/$n}% { z-index: 1; }
  #{100 - 50/$n}% { z-index: 2; }
}

Kita sudah selesai! Inilah yang kami dapatkan saat menggunakan lima gambar:

Kita dapat menambahkan sentuhan rotasi untuk membuatnya lebih menarik:

Yang saya lakukan hanyalah menambahkan rotate(var(--r)) ke transform Properti. Di dalam lingkaran, --r didefinisikan dengan sudut acak:

@for $i from 1 to ($n + 1) {
  .gallery > img:nth-child(#{$i}) {
    --r: #{(-20 + random(40))*1deg}; /* a random angle between -20deg and 20deg */
  }
}

Rotasi menciptakan gangguan kecil karena terkadang kita dapat melihat beberapa gambar melompat ke belakang tumpukan, tetapi itu bukan masalah besar.

Membungkus

Semua itu z-index bekerja adalah tindakan penyeimbang yang besar, bukan? Jika Anda tidak yakin bagaimana susunan susun bekerja sebelum latihan ini, Anda mungkin memiliki ide yang jauh lebih baik sekarang! Jika Anda menemukan beberapa penjelasan sulit untuk diikuti, saya sangat menyarankan Anda untuk membaca artikel lagi dan memetakan sesuatu dengan pensil dan kertas. Cobalah untuk mengilustrasikan setiap langkah animasi menggunakan jumlah gambar yang berbeda untuk lebih memahami triknya.

Terakhir kali, kami menggunakan beberapa trik geometri untuk membuat penggeser melingkar yang berputar kembali ke gambar pertama setelah urutan penuh. Kali ini, kami menyelesaikan trik serupa menggunakan z-index. Dalam kedua kasus tersebut, kami tidak menduplikasi gambar apa pun untuk mensimulasikan animasi berkelanjutan, kami juga tidak menggunakan JavaScript untuk membantu penghitungan.

Lain kali kita akan membuat slider 3D. Pantau terus!

Stempel Waktu:

Lebih dari Trik CSS