ภาพรวมพื้นฐานเกี่ยวกับวิธีสร้างประสบการณ์การใช้งานที่คล้ายกับ Instagram Stories บนเว็บ
ในโพสต์นี้ เราต้องการแชร์แนวคิดในการสร้างคอมโพเนนต์เรื่องราวสําหรับเว็บที่ปรับเปลี่ยนตามพื้นที่โฆษณา รองรับการไปยังส่วนต่างๆ ด้วยแป้นพิมพ์ และทํางานได้กับเบราว์เซอร์ต่างๆ
ถ้าอยากดูการสาธิตการสร้างคอมโพเนนต์เรื่องราวนี้ด้วยตัวเอง ลองดูที่ Codelab คอมโพเนนต์เรื่องราว
หากต้องการดูวิดีโอ โปรดดูโพสต์เวอร์ชัน YouTube ที่นี่
ภาพรวม
ตัวอย่าง UX ของเรื่องราวที่ได้รับความนิยม 2 ตัวอย่าง ได้แก่ สตอรี่ Snapchat และสตอรี่ Instagram (ยังไม่พูดถึงฟีเจอร์ Fleets) ในคำศัพท์ UX ทั่วไป เรื่องราวมักจะเป็นรูปแบบที่เน้นการแตะบนอุปกรณ์เคลื่อนที่เท่านั้นสำหรับไปยังส่วนต่างๆ ของการติดตามหลายรายการ ตัวอย่างเช่น ใน Instagram ผู้ใช้เปิดเรื่องราวของเพื่อน และดูรูปภาพที่อยู่ในนั้น โดยปกติแล้ว ผู้ใช้จะเพิ่มเพื่อนหลายคนพร้อมกัน การแตะด้านขวาของอุปกรณ์จะเป็นการข้ามไปดูเรื่องราวถัดไปของเพื่อน การปัดไปทางขวาจะเป็นการข้ามไปยังเพื่อนคนถัดไป คอมโพเนนต์เรื่องราวคล้ายกับภาพสไลด์ แต่อนุญาตให้ไปยังส่วนต่างๆ ของอาร์เรย์หลายมิติแทนอาร์เรย์มิติเดียว เหมือนกับมีภาพสไลด์ภายในภาพสไลด์แต่ละภาพ 🤯
การเลือกเครื่องมือที่เหมาะสมกับงาน
สรุปทั้งหมด ผมพบว่าคอมโพเนนต์นี้สร้างได้ง่ายมาก ด้วย ฟีเจอร์ที่สำคัญของแพลตฟอร์มเว็บบางอย่าง มาเริ่มกันเลย
CSS Grid
เลยพบว่าเลย์เอาต์ของเรานั้นไม่ยากสำหรับ CSS Grid เนื่องจากมีวิธีจัดการเนื้อหาที่มีประสิทธิภาพ
เลย์เอาต์เพื่อน
Wrapper คอมโพเนนต์ .stories
หลักของเราคือ ScrollView แนวนอนเพื่ออุปกรณ์เคลื่อนที่เป็นอันดับแรก
.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 Stories แต่ละคอลัมน์จะเป็นเรื่องราวของเพื่อน เราอยากให้เรื่องราวต่างๆ ของเพื่อนดำเนินต่อนอกวิวพอร์ตเพื่อให้มีปลายทางได้ ตารางกริดจะสร้างคอลัมน์ตามจำนวนที่ต้องการเพื่อจัดวาง HTML ของเรื่องราวเพื่อนแต่ละคน ซึ่งจะสร้างคอนเทนเนอร์การเลื่อนแบบไดนามิกและตอบสนองต่อผู้ใช้ ตารางกริดช่วยให้เราควบคุมเอฟเฟกต์ทั้งหมดจากส่วนกลางได้
การซ้อน
สำหรับเพื่อนแต่ละคน เราต้องการเรื่องราวที่อยู่ในสถานะพร้อมแบ่งหน้า เราเลือกกองเพื่อเตรียมไว้สำหรับภาพเคลื่อนไหวและลวดลายสนุกๆ อื่นๆ ที่ผมพูดถึงการกองซ้อน ผมหมายถึงเหมือนคุณกำลังมองลงไปที่ แซนด์วิช ไม่ใช่เหมือนคุณมองจากด้านข้าง
ตารางกริด 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 ของ Sarah Drasner เพื่อดูรายละเอียดที่ยอดเยี่ยมเกี่ยวกับวิธีใช้
.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; }
เราเลือกจุดยึดการเลื่อนเนื่องจากเหตุผลต่อไปนี้
- การช่วยเหลือพิเศษฟรี ข้อมูลจำเพาะของการเลื่อนจุดสแนประบุว่าการกดแป้นลูกศรซ้ายและลูกศรขวาควรผ่านจุดสแนปโดยค่าเริ่มต้น
- ข้อกำหนดที่พัฒนาอย่างต่อเนื่อง ข้อกำหนดของจุดยึดการเลื่อนได้รับการปรับปรุงและเพิ่มฟีเจอร์ใหม่ๆ อยู่เสมอ ซึ่งหมายความว่าคอมโพเนนต์เรื่องราวน่าจะดีขึ้นเรื่อยๆ นับจากนี้ไป
- ความสะดวกในการใช้งาน จุดยึดการเลื่อนสร้างขึ้นเพื่อการใช้งานแบบหน้าแนวนอนที่เน้นการสัมผัส
- ความเฉื่อยแบบแพลตฟอร์มฟรี แพลตฟอร์มทุกแพลตฟอร์มจะเลื่อนและหยุดในสไตล์ของตัวเอง ซึ่งต่างจากแรงเฉื่อยที่ปรับให้เป็นมาตรฐานซึ่งอาจมีลักษณะการเลื่อนและหยุดที่แปลกประหลาด
ความเข้ากันได้ในเบราว์เซอร์ต่างๆ
เราได้ทดสอบใน Opera, Firefox, Safari และ Chrome รวมถึง Android และ iOS ต่อไปนี้เป็นข้อมูลสรุปสั้นๆ เกี่ยวกับฟีเจอร์บนเว็บที่เราพบว่ามีความแตกต่างกันในด้านความสามารถและการสนับสนุน
อย่างไรก็ตาม เราพบว่า CSS บางรายการใช้ไม่ได้ ดังนั้นแพลตฟอร์มบางแห่งจึงไม่ได้รับการเพิ่มประสิทธิภาพ UX ในขณะนี้ เราชอบที่ไม่ต้องจัดการฟีเจอร์เหล่านี้และมั่นใจว่าฟีเจอร์เหล่านี้จะพร้อมให้บริการในเบราว์เซอร์และแพลตฟอร์มอื่นๆ ในที่สุด
scroll-snap-stop
ภาพสไลด์เป็นหนึ่งใน Use Case หลักของ UX ที่กระตุ้นให้สร้างข้อกำหนดเกี่ยวกับจุดหยุดของ CSS Scroll ซึ่งแตกต่างจากเรื่องราวตรงที่ภาพสไลด์ไม่จำเป็นต้องหยุดที่รูปภาพแต่ละรูปเสมอไปหลังจากที่ผู้ใช้โต้ตอบกับรูปภาพ คุณอาจเลื่อนดูภาพสไลด์อย่างรวดเร็วได้ ในทางกลับกัน เรื่องราวควรดูทีละเรื่อง และ 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'
ที่นี่ ดูข้อมูลอัปเดตได้ที่ความเข้ากันได้ของเบราว์เซอร์
ลงมือปฏิบัติ
ตอนนี้คุณก็รู้วิธีที่เราทําแล้ว คุณจะทําอย่างไร มาลองใช้แนวทางที่หลากหลายและดูวิธีทั้งหมดในการสร้างบนเว็บกัน สร้างGlitch แล้วทวีตเวอร์ชันของคุณมาให้เรา เราจะเพิ่มเวอร์ชันของคุณลงในส่วนรีมิกซ์ของชุมชนด้านล่าง
รีมิกซ์ในชุมชน
- @geoffrich_ กับ Svelte: demo และ code
- @GauteMeekOlsen ใช้ Vue: demo + code
- @AnaestheticsApp พร้อม Lit: demo และ code