ภาพรวมพื้นฐานเกี่ยวกับวิธีสร้างประสบการณ์การใช้งานที่คล้ายกับ Instagram Stories บนเว็บ
ในโพสต์นี้ ฉันต้องการแชร์แนวคิดในการสร้างคอมโพเนนต์ Stories สำหรับเว็บที่ปรับเปลี่ยนตามพื้นที่โฆษณา รองรับการนำทางด้วยคีย์บอร์ด และทำงานได้ในทุกเบราว์เซอร์
หากต้องการดูการสาธิตการสร้างคอมโพเนนต์เรื่องราวนี้ด้วยตนเอง โปรดดู Codelab สำหรับคอมโพเนนต์เรื่องราว
หากต้องการดูวิดีโอ โปรดดูโพสต์นี้ใน YouTube
ภาพรวม
ตัวอย่าง UX ของสตอรี่ที่ได้รับความนิยม 2 รายการ ได้แก่ สตอรี่ Snapchat และสตอรี่ Instagram (รวมถึงฟลีต) ในแง่ของ UX ทั่วไป เรื่องราวเป็นรูปแบบการแตะที่เน้นอุปกรณ์เคลื่อนที่เท่านั้นสำหรับการไปยังส่วนต่างๆ ของการติดตามหลายรายการ ตัวอย่างเช่น ใน Instagram ผู้ใช้จะเปิดสตอรี่ของเพื่อน และดูรูปภาพในสตอรี่ โดยปกติแล้วแฮ็กเกอร์จะทำเช่นนี้กับเพื่อนหลายคนพร้อมกัน การแตะที่ด้านขวาของอุปกรณ์จะทำให้ผู้ใช้ข้ามไปยัง สตอรี่ถัดไปของเพื่อนคนนั้น การปัดไปทางขวาจะทำให้ผู้ใช้ข้ามไปหาเพื่อนคนอื่น คอมโพเนนต์เรื่องราวค่อนข้างคล้ายกับภาพสไลด์ แต่ช่วยให้ไปยังอาร์เรย์หลายมิติได้แทนที่จะเป็นอาร์เรย์มิติเดียว ราวกับว่ามีภาพสไลด์อยู่ภายใน ภาพสไลด์แต่ละรายการ 🤯

ภาพสไลด์ที่ 2 ของสตอรี่ที่ "ซ้อนกัน"
👍 รายการในรายการ หรือที่เรียกว่าอาร์เรย์หลายมิติ
การเลือกเครื่องมือที่เหมาะสมสำหรับงาน
โดยรวมแล้ว ฉันคิดว่าคอมโพเนนต์นี้สร้างได้ง่ายมาก เนื่องจากมีฟีเจอร์ที่สำคัญบางอย่างของแพลตฟอร์มเว็บ มาดูกันเลย
CSS Grid
เลย์เอาต์ของเราไม่ได้เป็นเรื่องยากสำหรับ CSS Grid เนื่องจากมีวิธีที่มีประสิทธิภาพในการจัดการเนื้อหา
เลย์เอาต์ของ Friends
.stories
Wrapper คอมโพเนนต์หลักของเราคือ 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 และเรื่องราว Instagram แต่ละคอลัมน์จะเป็นเรื่องราวของเพื่อน เราต้องการให้สตอรี่ของเพื่อน แสดงต่อไปนอกวิวพอร์ตเพื่อให้มีที่ให้เลื่อน Grid จะสร้างคอลัมน์ตามจำนวนที่จำเป็นเพื่อจัดวาง HTML สำหรับสตอรี่ของเพื่อนแต่ละคน ซึ่งจะสร้างคอนเทนเนอร์แบบเลื่อนที่ปรับเปลี่ยนตามอุปกรณ์แบบไดนามิกและตอบสนองต่อการใช้งาน Grid ช่วยให้เราสามารถรวมเอฟเฟกต์ทั้งหมดไว้ที่เดียว
การซ้อน
สำหรับเพื่อนแต่ละคน เราต้องการเรื่องราวของเพื่อนในสถานะที่พร้อมสำหรับการแบ่งหน้า ฉันเลือกใช้กองซ้อนเพื่อเตรียมพร้อมสำหรับการเคลื่อนไหวและรูปแบบสนุกๆ อื่นๆ เมื่อพูดถึงการซ้อนกัน ฉันหมายถึงการมองลงไปที่ แซนวิช ไม่ใช่การมองจากด้านข้าง
ด้วยตารางกริด 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 เพื่อดูรายละเอียดวิธีใช้
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; }
ฉันเลือกจุดเลื่อนสแนปด้วยเหตุผล 2 ประการดังนี้
- การช่วยเหลือพิเศษฟรี ข้อกำหนดของจุดเลื่อนสแนประบุว่าการกดปุ่มลูกศรซ้ายและลูกศรขวาควรเลื่อนผ่านจุดสแนป โดยค่าเริ่มต้น
- ข้อกำหนดที่เพิ่มขึ้น ข้อกำหนดของจุดสแนปการเลื่อนจะได้รับการปรับปรุงและฟีเจอร์ใหม่ๆ อยู่เสมอ ซึ่งหมายความว่าคอมโพเนนต์ Stories ของฉันน่าจะดีขึ้นเรื่อยๆ นับจากนี้เป็นต้นไป
- ความสะดวกในการติดตั้งใช้งาน จุดเลื่อนสแนปสร้างขึ้นเพื่อกรณีการใช้งานการแบ่งหน้าแนวนอนที่เน้นการสัมผัสโดยเฉพาะ
- ความเฉื่อยแบบแพลตฟอร์มอิสระ ทุกแพลตฟอร์มจะเลื่อนและหยุดในสไตล์ของตัวเอง ซึ่งแตกต่างจาก แรงเฉื่อยที่ปรับให้เป็นมาตรฐานซึ่งอาจมีสไตล์การเลื่อนและการหยุดที่แปลกประหลาด
ความเข้ากันได้ในเบราว์เซอร์ต่างๆ
เราทดสอบใน Opera, Firefox, Safari และ Chrome รวมถึง Android และ iOS ต่อไปนี้เป็น ข้อมูลสรุปสั้นๆ เกี่ยวกับฟีเจอร์บนเว็บที่เราพบว่ามีความแตกต่างในด้านความสามารถและการรองรับ
แต่เรามี CSS บางรายการที่ไม่ได้ใช้ ดังนั้นแพลตฟอร์มบางแพลตฟอร์มจึงยังไม่ได้รับการเพิ่มประสิทธิภาพ UX ฉันชอบที่ไม่ต้องจัดการฟีเจอร์เหล่านี้และมั่นใจว่า ในที่สุดฟีเจอร์เหล่านี้จะพร้อมใช้งานในเบราว์เซอร์และแพลตฟอร์มอื่นๆ
scroll-snap-stop
ภาพหมุนเป็นหนึ่งในกรณีการใช้งาน UX ที่สำคัญซึ่งกระตุ้นให้เกิดการสร้างข้อกำหนดจุดสแนปการเลื่อน CSS ซึ่งแตกต่างจากสตอรี่ตรงที่ภาพหมุนไม่จำเป็นต้องหยุดที่รูปภาพแต่ละรูปเสมอไปหลังจากที่ผู้ใช้โต้ตอบกับภาพหมุน คุณอาจเลื่อนดูภาพสไลด์อย่างรวดเร็วได้ ในทางกลับกัน คุณควรเลื่อนดูเรื่องราวทีละรายการ
และนั่นคือสิ่งที่ 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: การสาธิต + โค้ด
- @AnaestheticsApp ที่มี Lit: การสาธิตและโค้ด