การสร้างคอมโพเนนต์เรื่องราว

ภาพรวมพื้นฐานเกี่ยวกับวิธีสร้างประสบการณ์การใช้งานที่คล้ายกับ Instagram Stories บนเว็บ

ในโพสต์นี้ เราต้องการแชร์แนวคิดในการสร้างคอมโพเนนต์เรื่องราวสําหรับเว็บที่ปรับเปลี่ยนตามพื้นที่โฆษณา รองรับการไปยังส่วนต่างๆ ด้วยแป้นพิมพ์ และทํางานได้กับเบราว์เซอร์ต่างๆ

การสาธิต

ถ้าอยากดูการสาธิตการสร้างคอมโพเนนต์เรื่องราวนี้ด้วยตัวเอง ลองดูที่ Codelab คอมโพเนนต์เรื่องราว

หากต้องการดูวิดีโอ โปรดดูโพสต์เวอร์ชัน YouTube ที่นี่

ภาพรวม

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

อาร์เรย์หลายมิติที่แสดงเป็นภาพโดยใช้การ์ด จากซ้ายไปขวาคือกองการ์ดที่มีขอบสีม่วง และภายในการ์ดแต่ละใบมีการ์ดที่มีขอบสีฟ้าซีน 1-หลายใบ รายการในรายการ
ภาพสไลด์ของเพื่อนชุดที่ 1
ภาพสไลด์ "ซ้อนกัน" ชุดที่ 2 ของเรื่องราว
👍 รายการในรายการ หรือที่เรียกว่าอาร์เรย์หลายมิติ

การเลือกเครื่องมือที่เหมาะสมกับงาน

สรุปทั้งหมด ผมพบว่าคอมโพเนนต์นี้สร้างได้ง่ายมาก ด้วย ฟีเจอร์ที่สำคัญของแพลตฟอร์มเว็บบางอย่าง มาเริ่มกันเลย

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;
}
การใช้โหมดอุปกรณ์ของ Chrome DevTools เพื่อไฮไลต์คอลัมน์ที่สร้างโดยตารางกริด

มาวิเคราะห์เลย์เอาต์ 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 เพื่อดูรายละเอียดที่ยอดเยี่ยมเกี่ยวกับวิธีใช้

การเลื่อนในแนวนอนแบบไม่มีและแบบมีสไตล์ 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;
}
เด็กเลือกที่จะเป็นเป้าหมายในการสแนป

เราเลือกจุดยึดการเลื่อนเนื่องจากเหตุผลต่อไปนี้

  • การช่วยเหลือพิเศษฟรี ข้อมูลจำเพาะของการเลื่อนจุดสแนประบุว่าการกดแป้นลูกศรซ้ายและลูกศรขวาควรผ่านจุดสแนปโดยค่าเริ่มต้น
  • ข้อกำหนดที่พัฒนาอย่างต่อเนื่อง ข้อกำหนดของจุดยึดการเลื่อนได้รับการปรับปรุงและเพิ่มฟีเจอร์ใหม่ๆ อยู่เสมอ ซึ่งหมายความว่าคอมโพเนนต์เรื่องราวน่าจะดีขึ้นเรื่อยๆ นับจากนี้ไป
  • ความสะดวกในการใช้งาน จุดยึดการเลื่อนสร้างขึ้นเพื่อการใช้งานแบบหน้าแนวนอนที่เน้นการสัมผัส
  • ความเฉื่อยแบบแพลตฟอร์มฟรี แพลตฟอร์มทุกแพลตฟอร์มจะเลื่อนและหยุดในสไตล์ของตัวเอง ซึ่งต่างจากแรงเฉื่อยที่ปรับให้เป็นมาตรฐานซึ่งอาจมีลักษณะการเลื่อนและหยุดที่แปลกประหลาด

ความเข้ากันได้ในเบราว์เซอร์ต่างๆ

เราได้ทดสอบใน 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 แล้วทวีตเวอร์ชันของคุณมาให้เรา เราจะเพิ่มเวอร์ชันของคุณลงในส่วนรีมิกซ์ของชุมชนด้านล่าง

รีมิกซ์ในชุมชน