Thông tin tổng quan cơ bản về cách xây dựng trải nghiệm tương tự như Instagram Stories trên web.
Trong bài đăng này, tôi muốn chia sẻ suy nghĩ về việc xây dựng một thành phần Tin cho web có khả năng thích ứng, hỗ trợ thao tác bằng bàn phím và hoạt động trên nhiều trình duyệt.
Nếu bạn muốn xem minh hoạ thực tế về cách tự xây dựng thành phần Tin này, hãy xem lớp học lập trình về thành phần Tin.
Nếu bạn thích xem video, thì đây là phiên bản YouTube của bài đăng này:
Tổng quan
Hai ví dụ phổ biến về trải nghiệm người dùng của Tin là Tin trên Snapchat và Tin trên Instagram (chưa kể đến Fleets). Nói chung, Stories thường là một mẫu chỉ dành cho thiết bị di động, tập trung vào thao tác nhấn để điều hướng nhiều gói thuê bao. Ví dụ: trên Instagram, người dùng mở tin của một người bạn và xem các bức ảnh trong đó. Họ thường làm việc này với nhiều bạn bè cùng một lúc. Bằng cách nhấn vào bên phải của thiết bị, người dùng sẽ chuyển sang câu chuyện tiếp theo của người bạn đó. Bằng cách vuốt sang phải, người dùng sẽ chuyển sang một người bạn khác. Thành phần Tin khá giống với băng chuyền, nhưng cho phép điều hướng một mảng đa chiều thay vì mảng một chiều. Cứ như thể có một băng chuyền bên trong mỗi băng chuyền. 🤯
Băng chuyền "xếp chồng" thứ hai về tin bài
👍 Danh sách trong danh sách, hay còn gọi là: mảng đa chiều
Chọn công cụ phù hợp cho công việc
Nhìn chung, tôi thấy thành phần này khá dễ xây dựng nhờ một số tính năng quan trọng của nền tảng web. Hãy cùng tìm hiểu!
Lưới CSS
Bố cục của chúng tôi không phải là một thứ tự cao cho CSS Grid vì bố cục này được trang bị một số cách hiệu quả để sắp xếp nội dung.
Bố cục phim Friends
Trình bao bọc thành phần .stories chính của chúng tôi là một chế độ xem cuộn ngang ưu tiên thiết bị di động:
.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;
}
Hãy cùng phân tích bố cục grid đó:
- Chúng tôi lấp đầy khung nhìn trên thiết bị di động một cách rõ ràng bằng
100vhvà100vw, đồng thời ràng buộc kích thước trên máy tính /phân tách các mẫu hàng và cột của chúng taauto-flowtương đương vớigrid-auto-flow: column- Mẫu tự động điều chỉnh là
100%, trong trường hợp này là bất kỳ chiều rộng nào của cửa sổ cuộn
Trên điện thoại di động, hãy coi kích thước hàng là chiều cao khung nhìn và mỗi cột là chiều rộng khung nhìn. Tiếp tục với ví dụ về Snapchat Stories và Instagram Stories, mỗi cột sẽ là một câu chuyện của bạn bè. Chúng ta muốn tin của bạn bè tiếp tục xuất hiện bên ngoài khung nhìn để có thể cuộn đến. Grid sẽ tạo ra số lượng cột cần thiết để bố cục HTML cho mỗi câu chuyện của bạn bè, tạo ra một vùng chứa cuộn linh động và thích ứng cho chúng ta. Lưới giúp chúng tôi tập trung toàn bộ hiệu ứng.
Kết hợp các chương trình khuyến mãi
Đối với mỗi người bạn, chúng ta cần câu chuyện của họ ở trạng thái sẵn sàng phân trang. Để chuẩn bị cho ảnh động và các mẫu thú vị khác, tôi đã chọn một ngăn xếp. Khi tôi nói xếp chồng, ý tôi là như bạn đang nhìn xuống một chiếc bánh sandwich, chứ không phải như bạn đang nhìn từ bên cạnh.
Với lưới CSS, chúng ta có thể xác định lưới một ô (tức là hình vuông), trong đó các hàng và cột có chung một bí danh ([story]), sau đó mỗi phần tử con được gán cho không gian một ô có bí danh đó:
.user {
display: grid;
grid: [story] 1fr / [story] 1fr;
scroll-snap-align: start;
scroll-snap-stop: always;
}
.story {
grid-area: story;
background-size: cover;
…
}
Điều này giúp HTML của chúng ta kiểm soát thứ tự xếp chồng và cũng giữ cho tất cả các phần tử
trong luồng. Lưu ý rằng chúng ta không cần làm gì với vị trí absolute hoặc z-index và không cần chỉnh sửa hộp bằng height: 100% hoặc width: 100%. Lưới gốc đã xác định kích thước của khung nhìn ảnh tin bài, vì vậy, không cần phải yêu cầu thành phần nào trong số các thành phần tin bài này lấp đầy khung nhìn!
Điểm cố định vị trí cuộn CSS
Thông số kỹ thuật của Điểm cố định vị trí cuộn CSS giúp bạn dễ dàng khoá các phần tử vào khung nhìn khi cuộn. Trước khi có các thuộc tính CSS này, bạn phải sử dụng JavaScript và việc này… ít nhất là rất phức tạp. Hãy xem bài viết Giới thiệu về điểm cố định vị trí cuộn CSS của Sarah Drasner để biết thông tin chi tiết về cách sử dụng các điểm này.
scroll-snap-points.
Nếu không có thuộc tính này, người dùng có thể cuộn tự do như bình thường. Nhờ đó, trình duyệt sẽ dừng lại nhẹ nhàng trên từng mục.
.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; }
Tôi chọn Điểm cố định vị trí cuộn vì một số lý do:
- Hỗ trợ tiếp cận miễn phí. Thông số kỹ thuật của Điểm cố định vị trí cuộn nêu rõ rằng việc nhấn các phím Mũi tên trái và Mũi tên phải sẽ di chuyển qua các điểm cố định vị trí theo mặc định.
- Thông số kỹ thuật ngày càng phát triển. Thông số kỹ thuật của Điểm cố định vị trí cuộn luôn có các tính năng và điểm cải tiến mới, tức là thành phần Stories của tôi có thể sẽ chỉ ngày càng tốt hơn từ đây trở đi.
- Dễ triển khai. Điểm cố định vị trí cuộn được xây dựng cho trường hợp sử dụng phân trang ngang tập trung vào thao tác chạm.
- Quán tính kiểu nền tảng miễn phí. Mỗi nền tảng sẽ cuộn và dừng theo kiểu riêng, trái ngược với quán tính chuẩn hoá có thể có kiểu cuộn và dừng khác thường.
Khả năng tương thích trên nhiều trình duyệt
Chúng tôi đã thử nghiệm trên Opera, Firefox, Safari và Chrome, cũng như Android và iOS. Sau đây là thông tin tóm tắt về các tính năng web mà chúng tôi nhận thấy có sự khác biệt về khả năng và mức độ hỗ trợ.
Tuy nhiên, chúng tôi có một số CSS không áp dụng, vì vậy một số nền tảng hiện đang thiếu tính năng tối ưu hoá trải nghiệm người dùng. Tôi rất thích việc không cần quản lý các tính năng này và tin rằng cuối cùng chúng sẽ đến được với các trình duyệt và nền tảng khác.
scroll-snap-stop
Băng chuyền là một trong những trường hợp sử dụng UX chính thúc đẩy việc tạo thông số kỹ thuật Điểm cố định vị trí cuộn CSS. Không giống như Câu chuyện, băng chuyền không phải lúc nào cũng cần dừng lại trên mỗi hình ảnh sau khi người dùng tương tác với hình ảnh đó. Việc nhanh chóng chuyển qua các mục trong băng chuyền có thể là bình thường hoặc được khuyến khích. Mặt khác, cách tốt nhất để xem tin bài là xem từng tin bài một, và đó chính là điều mà scroll-snap-stop mang lại.
.user {
scroll-snap-align: start;
scroll-snap-stop: always;
}
Tại thời điểm viết bài đăng này, scroll-snap-stop chỉ được hỗ trợ trên các trình duyệt dựa trên Chromium. Hãy xem phần Khả năng tương thích của trình duyệt để biết thông tin cập nhật. Tuy nhiên, đây không phải là vấn đề nghiêm trọng. Điều này chỉ có nghĩa là trên các trình duyệt không được hỗ trợ,
người dùng có thể vô tình bỏ qua một người bạn. Vì vậy, người dùng sẽ phải cẩn thận hơn, hoặc
chúng ta cần viết JavaScript để đảm bảo rằng một người bạn bị bỏ qua sẽ không được đánh dấu là đã xem.
Đọc thêm trong thông số kỹ thuật nếu bạn quan tâm.
overscroll-behavior
Bạn đã bao giờ cuộn qua một phương thức khi đột nhiên bạn
bắt đầu cuộn nội dung phía sau phương thức?
overscroll-behavior cho phép nhà phát triển chặn thao tác cuộn đó và không bao giờ cho phép thao tác đó rời đi. Phù hợp với mọi dịp. Thành phần Stories của tôi sử dụng thành phần này để ngăn các cử chỉ vuốt và cuộn khác rời khỏi thành phần.
.stories {
overflow-x: auto;
overscroll-behavior: contain;
}
Safari và Opera là 2 trình duyệt không hỗ trợ tính năng này và điều đó hoàn toàn bình thường. Những người dùng đó sẽ có trải nghiệm cuộn quá mức như họ vẫn quen dùng và có thể không bao giờ nhận thấy điểm cải tiến này. Cá nhân tôi rất thích và muốn đưa hiệu ứng này vào gần như mọi tính năng cuộn quá mức mà tôi triển khai. Đây là một sự bổ sung vô hại, chỉ có thể giúp cải thiện trải nghiệm người dùng.
scrollIntoView({behavior: 'smooth'})
Khi người dùng nhấn hoặc nhấp và đã xem hết tập hợp tin của một người bạn, thì đã đến lúc chuyển sang người bạn tiếp theo trong tập hợp điểm cố định vị trí cuộn. Với JavaScript, chúng tôi có thể tham chiếu đến người bạn tiếp theo và yêu cầu cuộn người bạn đó vào khung hiển thị. Tính năng này được hỗ trợ rất tốt; mọi trình duyệt đều cuộn phần tử này vào khung hiển thị. Tuy nhiên, không phải trình duyệt nào cũng làm được điều này 'smooth'. Điều này chỉ có nghĩa là
nó được cuộn vào khung hiển thị thay vì được chụp nhanh.
element.scrollIntoView({
behavior: 'smooth'
})
Safari là trình duyệt duy nhất không hỗ trợ behavior: 'smooth' tại đây. Hãy xem phần Khả năng tương thích của trình duyệt để biết thông tin cập nhật.
Tận tay
Giờ thì bạn đã biết cách tôi làm, vậy bạn sẽ làm thế nào?! Hãy đa dạng hoá các phương pháp tiếp cận và tìm hiểu mọi cách để xây dựng trên web. Hãy tạo một bản minh hoạ, tweet cho tôi phiên bản của bạn và tôi sẽ thêm phiên bản đó vào phần Bản phối lại của cộng đồng bên dưới.
Bản phối lại của cộng đồng
- @geoffrich_ với Svelte: mã
- @GauteMeekOlsen với Vue: bản minh hoạ + mã
- @AnaestheticsApp với Lit: mã