ภาพรวมพื้นฐานของวิธีการสร้างประสบการณ์ที่คล้ายกับสตอรี่ของ Instagram บนเว็บ
ในโพสต์นี้ ผมจะมาแชร์แนวคิดในการสร้างองค์ประกอบเรื่องราวสำหรับเว็บที่ตอบสนองตามอุปกรณ์ รองรับการไปยังส่วนต่างๆ ด้วยแป้นพิมพ์ และทำงานในเบราว์เซอร์ต่างๆ
หากต้องการดูการสาธิตการสร้างคอมโพเนนต์เรื่องราวนี้ด้วยตนเอง โปรดไปที่ Codelab สำหรับคอมโพเนนต์เรื่องราว
หากชอบวิดีโอ นี่คือโพสต์นี้เวอร์ชัน YouTube
ภาพรวม
ตัวอย่างยอดนิยม 2 ตัวอย่างของ UX ของ Stories ได้แก่ Snapchat Stories และ Instagram Stories (ไม่รวมกลุ่มอุปกรณ์) ในแง่ของ UX โดยทั่วไป เรื่องราวเป็นรูปแบบสำหรับอุปกรณ์เคลื่อนที่เท่านั้น ที่เน้นการแตะเป็นหลัก เพื่อใช้ในการติดตามหลายรายการ ตัวอย่างเช่น ใน Instagram ผู้ใช้เปิดสตอรี่ของเพื่อนและดูรูปภาพในสตอรี่ และมักจะทำแบบนี้กับเพื่อนๆ ครั้งละหลายคน เมื่อผู้ใช้แตะทางด้านขวาของอุปกรณ์ ผู้ใช้ก็ข้ามไปยังเรื่องราวถัดไปของเพื่อนคนนั้น การปัดไปทางขวาจะเป็นการข้ามไปข้างหน้ากับเพื่อนอีกคน คอมโพเนนต์เรื่องราวค่อนข้างคล้ายกับภาพหมุน แต่ช่วยให้ไปยังส่วนต่างๆ ของอาร์เรย์หลายมิติได้ ไม่ใช่อาร์เรย์มิติข้อมูลเดียว เหมือนมีภาพสไลด์อยู่ในแต่ละภาพสไลด์ 🤯
![แสดงภาพอาร์เรย์หลายมิติโดยใช้การ์ด จากซ้ายไปขวาคือกลุ่มการ์ดที่มีเส้นขอบสีม่วง และภายในการ์ดแต่ละใบจะมีเส้นขอบสีน้ำเงินเขียว 1 ใบ รายการในรายชื่อ](https://web.dev/static/articles/building/a-stories-component/image/visualized-multi-dimensio-bca9c1e40444a.png?authuser=5&hl=th)
ภาพสไลด์เรื่องราวแบบ "ซ้อน" รายการที่ 2
👍 รายการในรายการ หรืออาร์เรย์หลายมิติ
การเลือกเครื่องมือที่เหมาะกับงาน
โดยสรุปแล้ว ผมพบว่าคอมโพเนนต์นี้สร้างขึ้นมาได้ง่ายๆ เพราะมีฟีเจอร์แพลตฟอร์มเว็บที่สำคัญบางประการ มาดูกันเลย
ตารางกริด CSS
เลย์เอาต์ของเราไม่ได้เรียงลำดับแบบสูงสำหรับ CSS Grid เนื่องจากมาพร้อมวิธีมากมายที่ทรงพลังในการจัดรูปแบบเนื้อหา
เลย์เอาต์ Friends
Wrapper ของคอมโพเนนต์ .stories
หลักของเราคือมุมมองแบบเลื่อนแนวนอนที่เน้นอุปกรณ์เคลื่อนที่เป็นหลัก:
.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;
}
มาดูรายละเอียดเกี่ยวกับเลย์เอาต์ของ grid
กัน
- เราแก้ไขวิวพอร์ตบนอุปกรณ์เคลื่อนที่อย่างชัดแจ้งด้วย
100vh
และ100vw
และจำกัดขนาดบนเดสก์ท็อป /
แยกเทมเพลตแถวและคอลัมน์ออกจากกันauto-flow
แปลว่าgrid-auto-flow: column
- เทมเพลตโฟลว์อัตโนมัติคือ
100%
ซึ่งในกรณีนี้คือตามความกว้างของหน้าต่างที่เลื่อน
ในโทรศัพท์มือถือ ให้คิดว่าขนาดแถวคือความสูงของวิวพอร์ต และแต่ละคอลัมน์คือความกว้างของวิวพอร์ต จากตัวอย่าง Snapchat Stories และ เรื่องราว Instagram แต่ละคอลัมน์จะเป็นเรื่องราวของเพื่อน เราอยากให้มีเรื่องราวกับเพื่อนๆ ต่อไปเรื่อยๆ นอกวิวพอร์ต เพื่อให้เรามีที่ที่ต้องเลื่อนดู ตารางกริดจะสร้างคอลัมน์ที่ต้องใช้ในการจัดวาง HTML สำหรับเรื่องราวของเพื่อนแต่ละเรื่องเพื่อสร้างคอนเทนเนอร์แบบเลื่อนที่ปรับเปลี่ยนตามอุปกรณ์ให้เรา ตารางกริดช่วยให้เรารวม เอฟเฟกต์ทั้งหมดไว้ในที่เดียว
กองซ้อน
สำหรับเพื่อนแต่ละคน เราต้องการเรื่องราวของพวกเขาในสถานะที่พร้อมใส่เลขหน้า ในการเตรียมตัวสำหรับแอนิเมชันและแพทเทิร์นที่สนุกอื่นๆ ผมเลือกมา 1 ชุด เมื่อฉันพูดว่าสแต็ก ฉันหมายถึงว่าคุณกำลังมองแซนด์วิช ไม่เหมือนมุมมองจากด้านข้าง
เมื่อใช้ตารางกริด CSS เราจะกำหนดตารางกริดแบบเซลล์เดียว (สี่เหลี่ยมจัตุรัส) ซึ่งแถวและคอลัมน์จะใช้ชื่อแทน ([story]
) ร่วมกันได้ และระบบจะกำหนดตารางย่อยแต่ละเซลล์ให้กับพื้นที่เซลล์เดียวที่มีชื่อแทนดังกล่าว ดังนี้
.user {
display: grid;
grid: [story] 1fr / [story] 1fr;
scroll-snap-align: start;
scroll-snap-stop: always;
}
.story {
grid-area: story;
background-size: cover;
…
}
ซึ่งจะทำให้ HTML ของเราควบคุมลำดับการเรียงซ้อนได้และยังทำให้องค์ประกอบทั้งหมดทำงานอย่างลื่นไหลอีกด้วย โปรดสังเกตวิธีที่เราไม่จำเป็นต้องดำเนินการใดๆ กับการจัดตำแหน่ง absolute
หรือ z-index
และเราไม่จำเป็นต้องแก้ไขให้ถูกต้องด้วย height: 100%
หรือ width: 100%
ตารางกริดระดับบนสุดกำหนดขนาดของวิวพอร์ตรูปภาพเรื่องราวไว้แล้ว จึงไม่จำเป็นต้องบอกองค์ประกอบเรื่องราวเหล่านี้ให้เติมเนื้อหา
จุดสแนปการเลื่อน CSS
ข้อกำหนดคะแนนการเลื่อนของ CSS ช่วยให้ล็อกองค์ประกอบต่างๆ ในวิวพอร์ตขณะเลื่อนได้อย่างง่ายดาย ก่อนที่จะมีพร็อพเพอร์ตี้ CSS เหล่านี้ คุณต้องใช้ JavaScript ซึ่งก็ค่อนข้างยาก ลองอ่าน ขอแนะนำ CSS Scroll Snap Points ของ Sarah Drasner เพื่อดูรายละเอียดเกี่ยวกับวิธีใช้
scroll-snap-points
หากไม่มี ผู้ใช้ก็จะเลื่อนได้ตามปกติ ด้วยการทำเช่นนี้ เบราว์เซอร์จะค่อยๆ วางใจในแต่ละรายการ
.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; }บุตรหลานเลือกที่จะเป็นเป้าหมายของสแนป
ฉันเลือก Scroll Snap Points ด้วยเหตุผล 2-3 ประการคือ
- การช่วยเหลือพิเศษฟรี ข้อมูลจำเพาะของการเลื่อน Snap Point ระบุว่าการกดแป้นลูกศรซ้ายและลูกศรขวาควรเลื่อนผ่านจุดสแนปโดยค่าเริ่มต้น
- ข้อมูลจำเพาะที่เพิ่มขึ้น ข้อมูลจำเพาะของ Scroll Snap Points ได้รับฟีเจอร์และการปรับปรุงใหม่ๆ ตลอดเวลา ซึ่งหมายความว่าคอมโพเนนต์เรื่องราวของฉันน่าจะดีขึ้นกว่าเดิมเท่านั้น
- ใช้งานง่าย จุด Snap ของการเลื่อนสร้างขึ้นเพื่อการใช้งานสำหรับกรณีการใช้งานที่มีการแบ่งหน้าในแนวนอนที่เน้นการแตะ
- ความเฉื่อยแบบแพลตฟอร์มฟรี ทุกแพลตฟอร์มจะเลื่อนและวางตัวตามสไตล์ของตน ซึ่งตรงข้ามกับความเฉื่อยมาตรฐานซึ่งอาจมีรูปแบบการเลื่อนและการเคลื่อนไหวที่แปลกประหลาด
ความสามารถในการใช้งานร่วมกันข้ามเบราว์เซอร์
เราทดสอบใน Opera, Firefox, Safari และ Chrome รวมถึง Android และ iOS ต่อไปนี้เป็นคำอธิบายโดยย่อของฟีเจอร์บนเว็บที่เราพบความแตกต่างด้านความสามารถและการสนับสนุน
แต่ในกรณีที่เราไม่ได้ใช้ CSS บางรายการ บางแพลตฟอร์มจึงยังขาดการเพิ่มประสิทธิภาพ UX ในขณะนี้ ผมสนุกกับการไม่จำเป็นต้องจัดการฟีเจอร์เหล่านี้ และรู้สึกมั่นใจว่าในที่สุดแล้วจะเข้าถึงเบราว์เซอร์และแพลตฟอร์มอื่นๆ ได้
scroll-snap-stop
ภาพสไลด์เป็นหนึ่งใน Use Case หลัก UX ที่ส่งผลให้เกิดการสร้างข้อกำหนดเฉพาะของ CSS Scroll Snap Points ซึ่งต่างจากเรื่องราวตรงที่ภาพสไลด์ไม่จำเป็นต้องหยุดกับแต่ละรูปภาพหลังจากที่ผู้ใช้โต้ตอบกับรูปแล้วเสมอไป ขอแนะนำให้หมุนภาพสไลด์อย่างรวดเร็ว ในทางตรงกันข้าม เรื่องราวจะเลือกไปทีละเรื่องได้ดีที่สุด และ scroll-snap-stop
ก็แนะนำเนื้อหาได้ดี
.user {
scroll-snap-align: start;
scroll-snap-stop: always;
}
ในขณะที่เขียนโพสต์นี้ scroll-snap-stop
ได้รับการสนับสนุนเฉพาะในเบราว์เซอร์แบบ Chromium เท่านั้น โปรดดูความเข้ากันได้ของเบราว์เซอร์สำหรับการอัปเดต แต่สิ่งนี้ไม่ใช่ตัวบล็อก แต่หมายความว่าบนเบราว์เซอร์ที่ไม่รองรับ
ผู้ใช้อาจข้ามเพื่อนโดยไม่ตั้งใจได้ ดังนั้นผู้ใช้จึงต้องใช้ความระมัดระวังมากขึ้น
หรือเราจะต้องเขียน JavaScript เพื่อไม่ให้เพื่อนที่ถูกข้ามว่าดูแล้ว
อ่านเพิ่มเติมในข้อกำหนดหากคุณสนใจ
overscroll-behavior
คุณเคยต้องเลื่อนผ่านโมดัลไหม เมื่อจู่ๆ ก็เริ่มเลื่อนเนื้อหาไปข้างหลังโมดัลนี้
overscroll-behavior
ช่วยให้นักพัฒนาซอฟต์แวร์ที่เลื่อนและปล่อยมือออกมาได้ เหมาะสำหรับทุกโอกาส คอมโพเนนต์เรื่องราวของฉันใช้คอมโพเนนต์
เพื่อป้องกันไม่ให้การเลื่อนและท่าทางสัมผัสการเลื่อนออกจากคอมโพเนนต์
.stories {
overflow-x: auto;
overscroll-behavior: contain;
}
Safari และ Opera เป็น 2 เบราว์เซอร์ที่ไม่ สนับสนุนเรื่องนี้ ซึ่งก็ไม่เป็นไร ผู้ใช้เหล่านี้จะได้รับประสบการณ์การเลื่อนมากเกินไปเหมือนอย่างที่เคย คุ้นเคย และอาจไม่สังเกตเห็นการเพิ่มประสิทธิภาพนี้ โดยส่วนตัวแล้วผมเป็นแฟนตัวยงและชอบ รวมฟีเจอร์นี้ไว้เป็นส่วนหนึ่งของฟีเจอร์การเลื่อนเกินทั้งหมดที่ผมใช้ ซึ่งเป็นการเพิ่มที่ไม่เป็นอันตราย แต่จะทำให้ UX ดีขึ้นเท่านั้น
scrollIntoView({behavior: 'smooth'})
เมื่อผู้ใช้แตะหรือคลิกจบชุดเรื่องราวของเพื่อนแล้ว
ถึงเวลาย้ายไปที่เพื่อนคนถัดไปในชุดจุดเลื่อนของการเลื่อน ด้วย JavaScript ทำให้เราสามารถอ้างอิงเพื่อนคนถัดไปและขอให้เลื่อนเข้ามาในมุมมองได้ การสนับสนุนข้อมูลพื้นฐานเกี่ยวกับเรื่องนี้เป็นอย่างดี เบราว์เซอร์ทุกชนิด
เลื่อนดูจนครบ แต่ไม่ใช่ทุกเบราว์เซอร์ 'smooth'
เพียงแต่หมายความว่า
มีการเลื่อนมุมมองเข้ามาในมุมมองแทนที่จะสแนป
element.scrollIntoView({
behavior: 'smooth'
})
Safari เป็นเบราว์เซอร์เดียวที่ไม่รองรับ behavior: 'smooth'
ที่นี่ โปรดดูความเข้ากันได้ของเบราว์เซอร์สำหรับการอัปเดต
ลงมือจริง
ตอนนี้คุณก็รู้แล้วว่าผมทำยังไงแล้วคุณล่ะ คุณจะต้องทำอย่างไร มาเพิ่มความหลากหลายให้กับวิธีการของเรา และเรียนรู้ทุกวิธีในการสร้างเว็บ สร้างกลิทช์ ทวีตฉันถึงเวอร์ชันของคุณ แล้วฉันจะเพิ่มไปยังส่วนรีมิกซ์ของชุมชนด้านล่าง
รีมิกซ์ของชุมชน
- @geoffrich_ ด้วย Svelte: การสาธิตและโค้ด
- @GauteMeekOlsen โดยใช้ Vue: การสาธิต + โค้ด
- @AnaestheticsApp พร้อม Lit: การสาธิตและโค้ด