Ringkasan dasar tentang cara membangun pengalaman yang mirip dengan Instagram Stories di web.
Dalam postingan ini, saya ingin berbagi pemikiran tentang cara membuat komponen Stories untuk web yang responsif, mendukung navigasi keyboard, dan berfungsi di berbagai browser.
Jika Anda lebih suka demonstrasi langsung dalam membuat 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 fleets). Dalam istilah UX umum, Cerita biasanya merupakan pola khusus seluler yang berfokus pada ketukan untuk menavigasi beberapa langganan. Misalnya, di Instagram, pengguna membuka story teman dan melihat-lihat gambar di dalamnya. Mereka biasanya melakukan ini dengan banyak teman sekaligus. Dengan mengetuk sisi kanan perangkat, pengguna akan langsung beralih ke story berikutnya dari teman tersebut. Dengan menggeser ke kanan, pengguna akan beralih ke teman lain. Komponen Cerita cukup mirip dengan carousel, tetapi memungkinkan navigasi array multi-dimensi, bukan array satu dimensi. Seolah-olah ada carousel di dalam setiap carousel. 🤯
Carousel story "bertumpuk" ke-2
👍 Daftar dalam daftar, alias: array multi-dimensi
Memilih alat yang tepat untuk pekerjaan
Secara keseluruhan, menurut saya 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 yang efektif untuk mengelola konten.
Tata letak Friends
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;
}
Mari kita uraikan tata letak grid tersebut:
- Kami secara eksplisit mengisi area pandang di perangkat seluler dengan
100vhdan100vwserta membatasi ukuran di desktop /memisahkan template baris dan kolom kamiauto-flowditerjemahkan kegrid-auto-flow: column- Template autoflow adalah
100%, yang dalam hal ini adalah berapa pun lebar jendela scroll
Di ponsel, anggap ini seperti ukuran baris sebagai tinggi area pandang dan setiap kolom sebagai lebar area pandang. Melanjutkan contoh Snapchat Stories dan Instagram Stories, setiap kolom akan menjadi cerita teman. Kita ingin cerita teman berlanjut di luar area pandang sehingga kita memiliki tempat untuk men-scroll. Grid akan membuat berapa pun kolom yang diperlukan untuk menata letak HTML untuk setiap story teman, sehingga membuat penampung scroll yang dinamis dan responsif untuk kita. Grid memungkinkan kita memusatkan seluruh efek.
Promosi gabungan
Untuk setiap teman, kita memerlukan story mereka dalam status siap penomoran halaman. Sebagai persiapan untuk animasi dan pola menarik lainnya, saya memilih stack. Saat saya mengatakan tumpukan, maksudnya seperti Anda melihat sandwich dari atas, bukan dari samping.
Dengan petak CSS, kita dapat menentukan petak satu sel (yaitu persegi), tempat baris
dan kolom berbagi alias ([story]), lalu setiap turunan ditetapkan ke ruang
satu sel 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 tumpukan dan juga menjaga semua elemen
tetap dalam alur. 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
sudah menentukan ukuran area pandang gambar cerita, sehingga tidak ada komponen cerita ini
yang perlu diberi tahu untuk mengisinya.
Titik Snap Scroll CSS
Spesifikasi Titik Snap Scroll CSS memudahkan penguncian elemen ke area pandang saat di-scroll. Sebelum properti CSS ini ada, Anda harus menggunakan JavaScript, dan itu… rumit, setidaknya. Lihat Memperkenalkan Titik Snap Scroll CSS oleh Sarah Drasner untuk mengetahui penjelasan yang bagus tentang cara menggunakannya.
scroll-snap-points.
Tanpa itu, pengguna dapat men-scroll bebas seperti biasa. Dengan begitu, browser akan berhenti dengan mulus di setiap item.
.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; }
.user { display: grid; grid: [story] 1fr / [story] 1fr; scroll-snap-align: start; scroll-snap-stop: always; }
Saya memilih Scroll Snap Points karena beberapa alasan:
- Aksesibilitas gratis. Spesifikasi Titik Pengepasan Posisi Scroll menyatakan bahwa menekan tombol Panah Kiri dan Panah Kanan akan berpindah-pindah titik pengepasan posisi scroll secara default.
- Spesifikasi yang terus berkembang. Spesifikasi Scroll Snap Points terus mendapatkan fitur dan peningkatan baru, yang berarti komponen Stories saya mungkin akan terus menjadi lebih baik mulai sekarang.
- Kemudahan penerapan. Scroll Snap Points praktis dibuat untuk kasus penggunaan paginasi horizontal yang berfokus pada sentuhan.
- Inersia gaya platform gratis. Setiap platform akan men-scroll dan berhenti sesuai gayanya, bukan inersia yang dinormalisasi yang dapat memiliki gaya scroll dan berhenti yang aneh.
Kompatibilitas lintas browser
Kami menguji di Opera, Firefox, Safari, dan Chrome, serta Android dan iOS. Berikut ringkasan singkat fitur web yang memiliki perbedaan kemampuan dan dukungan.
Namun, ada beberapa CSS yang tidak diterapkan, sehingga beberapa platform saat ini tidak mendapatkan pengoptimalan UX. Saya senang karena tidak perlu mengelola fitur ini dan yakin bahwa fitur ini pada akhirnya akan menjangkau browser dan platform lain.
scroll-snap-stop
Carousel adalah salah satu kasus penggunaan UX utama yang mendorong pembuatan
spesifikasi Titik Pengepasan Posisi Scroll CSS. Tidak seperti Stories, carousel tidak selalu harus berhenti
pada setiap gambar setelah pengguna berinteraksi dengannya. Mungkin tidak masalah atau dianjurkan untuk
berpindah-pindah carousel dengan cepat. Di sisi lain, Stories paling baik dijelajahi satu per satu,
dan itulah yang disediakan scroll-snap-stop.
.user {
scroll-snap-align: start;
scroll-snap-stop: always;
}
Saat postingan ini ditulis, scroll-snap-stop hanya didukung di browser berbasis Chromium. Lihat
Kompatibilitas browser
untuk mengetahui info terbaru. Namun, ini bukan pemblokir. Artinya, di browser yang tidak didukung,
pengguna dapat secara tidak sengaja melewati teman. Jadi, pengguna harus lebih berhati-hati, atau
kita perlu 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 membiarkannya
keluar. 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 tidak masalah. Pengguna tersebut akan mendapatkan pengalaman overscroll seperti yang biasa mereka lakukan dan mungkin tidak akan pernah menyadari peningkatan ini. Saya pribadi sangat menyukainya dan suka menyertakannya sebagai bagian dari hampir setiap fitur overscroll yang saya terapkan. Penambahan ini tidak berbahaya dan hanya dapat meningkatkan UX.
scrollIntoView({behavior: 'smooth'})
Saat pengguna mengetuk atau mengklik dan telah mencapai akhir kumpulan story teman,
saatnya beralih ke teman berikutnya dalam kumpulan titik pengepasan posisi scroll. Dengan
JavaScript, kita dapat mereferensikan teman berikutnya dan memintanya untuk
di-scroll ke tampilan. Dukungan untuk dasar-dasar ini sangat bagus; setiap browser
men-scroll-nya ke tampilan. Namun, tidak semua browser melakukannya 'smooth'. Artinya,
elemen di-scroll ke tampilan, bukan diposisikan.
element.scrollIntoView({
behavior: 'smooth'
})
Safari adalah satu-satunya browser yang tidak mendukung behavior: 'smooth' di sini. Lihat
Kompatibilitas browser
untuk mengetahui info terbaru.
Praktik Langsung
Setelah tahu cara saya melakukannya, bagaimana cara Anda melakukannya? Mari kita diversifikasi pendekatan kita dan pelajari semua cara untuk membangun di web. Buat demo, tweet saya versi Anda, dan saya akan menambahkannya ke bagian Remix komunitas di bawah.
Remix komunitas
- @geoffrich_ dengan Svelte: kode
- @GauteMeekOlsen dengan Vue: demo + kode
- @AnaestheticsApp dengan Lit: kode