Membuat komponen Stories

Ringkasan dasar tentang cara membuat pengalaman yang mirip dengan Instagram Stories di web.

Dalam postingan ini, saya ingin membagikan pemikiran tentang cara membuat komponen Stories untuk web yang responsif, mendukung navigasi keyboard, dan berfungsi di seluruh browser.

Demo

Jika Anda lebih memilih demonstrasi langsung untuk mem-build komponen Stories ini sendiri, lihat codelab komponen Stories.

Jika Anda lebih suka video, berikut versi YouTube dari postingan ini:

Ringkasan

Dua contoh populer UX Stories adalah Snapchat Stories dan Instagram Stories (belum lagi fleet). Dalam istilah UX umum, Stories biasanya merupakan pola khusus seluler yang berfokus pada ketukan untuk menavigasi beberapa langganan. Misalnya, di Instagram, pengguna membuka story teman dan melihat foto-foto di dalamnya. Mereka biasanya melakukan hal ini dengan banyak teman sekaligus. Dengan mengetuk sisi kanan perangkat, pengguna akan langsung ke cerita berikutnya milik teman tersebut. Dengan menggeser ke kanan, pengguna akan melewati ke teman lain. Komponen Cerita cukup mirip dengan carousel, tetapi memungkinkan navigasi array multidimensi, bukan array satu dimensi. Seperti ada carousel di dalam setiap carousel. 🤯

Array multidimensi yang divisualisasi menggunakan kartu. Dari kiri ke kanan adalah tumpukan kartu dengan batas ungu, dan di dalam setiap kartu terdapat 1-banyak kartu dengan batas cyan. Daftar dalam daftar.
Carousel pertama teman
Carousel kedua "bertumpuk" dari story
👍 Daftar dalam daftar, alias: array multi-dimensi

Memilih alat yang tepat untuk pekerjaan

Secara keseluruhan, saya mendapati bahwa komponen ini cukup mudah dibuat, berkat beberapa fitur platform web yang penting. Mari kita bahas.

Petak CSS

Tata letak kami ternyata tidak terlalu sulit untuk CSS Grid karena dilengkapi dengan beberapa cara efektif untuk mengelola konten.

Tata letak teman

Wrapper komponen .stories utama kami adalah scrollview horizontal yang mengutamakan perangkat seluler:

.stories {
  inline-size: 100vw;
  block-size: 100vh;

  display: grid;
  grid: 1fr / auto-flow 100%;
  gap: 1ch;

  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior: contain;
  touch-action: pan-x;
}

/* desktop constraint */
@media (hover: hover) and (min-width: 480px) {
  max-inline-size: 480px;
  max-block-size: 848px;
}
Menggunakan Mode Perangkat Chrome DevTools untuk menandai kolom yang dibuat oleh Petak

Mari kita uraikan tata letak grid tersebut:

  • Kami mengisi viewport di perangkat seluler secara eksplisit dengan 100vh dan 100vw serta membatasi ukuran di desktop
  • / memisahkan template baris dan kolom
  • auto-flow diterjemahkan ke grid-auto-flow: column
  • Template alur otomatis adalah 100%, yang dalam hal ini adalah lebar jendela scroll

Di ponsel, anggaplah ini seperti ukuran baris adalah tinggi area pandang dan setiap kolom adalah lebar area pandang. Melanjutkan contoh Cerita Snapchat dan Cerita Instagram, setiap kolom akan berisi cerita teman. Kita ingin cerita teman berlanjut di luar area pandang sehingga kita memiliki tempat untuk men-scroll. Petak akan membuat kolom sebanyak yang diperlukan untuk menata letak HTML Anda untuk setiap kisah teman, sehingga membuat penampung scroll yang dinamis dan responsif untuk kita. Petak memungkinkan kita memusatkan seluruh efek.

Promosi gabungan

Untuk setiap teman, kita memerlukan cerita mereka dalam status siap penomoran halaman. Sebagai persiapan untuk animasi dan pola menyenangkan lainnya, saya memilih stack. Saat saya mengatakan stack, maksud saya seperti Anda melihat sandwich dari atas, bukan seperti Anda melihat dari samping.

Dengan petak CSS, kita dapat menentukan petak sel tunggal (yaitu persegi), dengan baris dan kolom berbagi alias ([story]), lalu setiap turunan ditetapkan ke ruang sel tunggal dengan alias tersebut:

.user {
  display: grid;
  grid: [story] 1fr / [story] 1fr;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
.story {
  grid-area: story;
  background-size: cover;
  
}

Hal ini membuat HTML kita mengontrol urutan penumpukan dan juga menjaga semua elemen tetap mengalir. Perhatikan bahwa kita tidak perlu melakukan apa pun dengan pemosisian absolute atau z-index dan kita tidak perlu mengoreksi kotak dengan height: 100% atau width: 100%. Petak induk telah menentukan ukuran area pandang gambar cerita, sehingga tidak ada komponen cerita yang perlu diberi tahu untuk mengisinya.

Titik Snap Scroll CSS

Spesifikasi Titik Snap Scroll CSS memudahkan Anda mengunci elemen ke dalam area pandang saat men-scroll. Sebelum properti CSS ini ada, Anda harus menggunakan JavaScript, dan itu… sulit, untuk sedikitnya. Lihat Memperkenalkan Titik Snap Scroll CSS oleh Sarah Drasner untuk mengetahui perincian yang bagus tentang cara menggunakannya.

Scroll horizontal tanpa dan dengan gaya scroll-snap-points. Tanpanya, pengguna dapat men-scroll bebas seperti biasa. Dengan demikian, browser akan beristirahat dengan lembut di setiap item.
induk
.stories {
  display: grid;
  grid: 1fr / auto-flow 100%;
  gap: 1ch;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior: contain;
  touch-action: pan-x;
}
Induk dengan overscroll menentukan perilaku snap.
anak
.user {
  display: grid;
  grid: [story] 1fr / [story] 1fr;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
Anak-anak memilih untuk menjadi target snap.

Saya memilih Titik Snap Scroll karena beberapa alasan:

  • Aksesibilitas gratis. Spesifikasi Titik Snap Scroll menyatakan bahwa menekan tombol Panah Kiri dan Panah Kanan akan berpindah melalui titik snap secara default.
  • Spesifikasi yang terus berkembang. Spesifikasi Titik Snap Scroll terus mendapatkan fitur dan peningkatan baru, yang berarti komponen Stories saya mungkin akan semakin baik dari sekarang dan seterusnya.
  • Kemudahan penerapan. Titik Snap Scroll praktis dibuat untuk kasus penggunaan penomoran halaman horizontal yang berfokus pada sentuh.
  • Inersia gaya platform bebas. Setiap platform akan men-scroll dan beristirahat dalam gayanya, tidak seperti inersia yang dinormalisasi yang dapat memiliki gaya scroll dan istirahat yang aneh.

Kompatibilitas lintas browser

Kami telah mengujinya di Opera, Firefox, Safari, dan Chrome, serta Android dan iOS. Berikut ringkasan singkat tentang fitur web tempat kami menemukan perbedaan kemampuan dan dukungan.

Namun, kami memiliki beberapa CSS yang tidak berlaku, sehingga beberapa platform saat ini tidak memiliki pengoptimalan UX. Saya senang tidak perlu mengelola fitur ini dan merasa yakin bahwa fitur tersebut pada akhirnya akan menjangkau browser dan platform lain.

scroll-snap-stop

Carousel adalah salah satu kasus penggunaan UX utama yang mendorong pembuatan spec CSS Scroll Snap Points. Tidak seperti Stories, carousel tidak selalu perlu berhenti di setiap gambar setelah pengguna berinteraksi dengannya. Anda mungkin tidak perlu khawatir atau dianjurkan untuk berpindah carousel dengan cepat. Di sisi lain, cerita sebaiknya dibuka satu per satu, dan itulah yang disediakan scroll-snap-stop.

.user {
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

Pada saat penulisan postingan ini, scroll-snap-stop hanya didukung di browser berbasis Chromium. Lihat Kompatibilitas browser untuk mengetahui info terbaru. Namun, ini bukan pemblokir. Artinya, pada browser yang tidak didukung, pengguna dapat tidak sengaja melewati teman. Jadi, pengguna hanya perlu lebih berhati-hati, atau kita harus menulis JavaScript untuk memastikan bahwa teman yang dilewati tidak ditandai sebagai dilihat.

Baca selengkapnya di spesifikasi jika Anda tertarik.

overscroll-behavior

Pernahkah Anda men-scroll modal, lalu tiba-tiba mulai men-scroll konten di balik modal? overscroll-behavior memungkinkan developer menjebak scroll tersebut dan tidak pernah membiarkannya pergi. Cocok untuk berbagai acara. Komponen My Stories menggunakannya untuk mencegah gestur geser dan scroll tambahan keluar dari komponen.

.stories {
  overflow-x: auto;
  overscroll-behavior: contain;
}

Safari dan Opera adalah 2 browser yang tidak mendukung hal ini, dan itu sama sekali tidak masalah. Pengguna tersebut akan mendapatkan pengalaman overscroll seperti yang biasa mereka lakukan dan mungkin tidak pernah melihat peningkatan ini. Saya pribadi adalah penggemar berat dan suka menyertakannya sebagai bagian dari hampir setiap fitur overscroll yang saya terapkan. Ini adalah tambahan yang tidak berbahaya dan hanya dapat meningkatkan UX.

scrollIntoView({behavior: 'smooth'})

Saat pengguna mengetuk atau mengklik dan telah mencapai akhir kumpulan cerita teman, saatnya untuk beralih ke teman berikutnya dalam kumpulan titik snap scroll. Dengan JavaScript, kita dapat mereferensikan teman berikutnya dan memintanya di-scroll agar terlihat. Dukungan untuk dasar-dasarnya sangat bagus; setiap browser men-scrollnya ke tampilan. Namun, tidak semua browser melakukannya 'smooth'. Ini hanya berarti tampilan di-scroll ke dalam, bukan di-snap.

element.scrollIntoView({
  behavior: 'smooth'
})

Safari adalah satu-satunya browser yang tidak mendukung behavior: 'smooth' di sini. Lihat Kompatibilitas browser untuk mengetahui info terbaru.

Langsung

Setelah Anda tahu cara saya melakukannya, bagaimana Anda melakukannya? Mari kita diversifikasi pendekatan dan pelajari semua cara untuk mem-build di web. Buat Glitch, tweet versi Anda kepada saya, dan saya akan menambahkannya ke bagian Gabungan komunitas di bawah.

Remix komunitas