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

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

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

การสาธิต

หากต้องการดูการสาธิตการสร้างคอมโพเนนต์เรื่องราวนี้ด้วยตนเอง โปรดดู Codelab สำหรับคอมโพเนนต์เรื่องราว

หากต้องการดูวิดีโอ โปรดดูโพสต์นี้ใน YouTube

ภาพรวม

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

อาร์เรย์หลายมิติที่แสดงภาพโดยใช้การ์ด จากซ้ายไปขวาคือการ์ดที่มีเส้นขอบสีม่วงซ้อนกัน และในการ์ดแต่ละใบจะมี 1-หลายการ์ดที่มีเส้นขอบสีฟ้า รายการในรายการ
ภาพสไลด์แรกของเพื่อน
ภาพสไลด์ที่ 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;
}
การใช้โหมดอุปกรณ์ ของเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome เพื่อไฮไลต์คอลัมน์ที่สร้างโดย Grid

มาดูรายละเอียดของ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;
}
บุตรหลานเลือกที่จะเป็นเป้าหมายของ Snap

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

รีมิกซ์ของชุมชน