ساخت جزء داستان

یک نمای کلی از نحوه ایجاد تجربه ای مشابه استوری اینستاگرام در وب.

در این پست می‌خواهم فکری در مورد ساخت یک جزء Stories برای وب به اشتراک بگذارم که واکنش‌گرا باشد، از ناوبری صفحه‌کلید پشتیبانی کند و در مرورگرها کار کند.

نسخه ی نمایشی

اگر ترجیح می‌دهید یک نمایش عملی از ساخت این مؤلفه داستان‌ها را خودتان انجام دهید، آزمایشگاه کد مؤلفه Stories را بررسی کنید.

اگر ویدیو را ترجیح می دهید، در اینجا یک نسخه YouTube از این پست وجود دارد:

بررسی اجمالی

دو نمونه محبوب از Stories UX استوری Snapchat و Instagram Stories هستند (به ناوگان اشاره نکنیم). به‌طور کلی، استوری‌ها معمولاً یک الگوی ضربه‌محور فقط برای موبایل برای پیمایش چندین اشتراک هستند. به عنوان مثال، در اینستاگرام، کاربران استوری یکی از دوستان را باز می کنند و تصاویر موجود در آن را مرور می کنند. آنها معمولاً این کار را در یک زمان بسیاری از دوستان انجام می دهند. با ضربه زدن روی سمت راست دستگاه، کاربر به داستان بعدی آن دوست می‌رود. با کشیدن انگشت به سمت راست، کاربر به سمت یک دوست دیگر می‌رود. کامپوننت Story تقریباً شبیه به چرخ فلک است، اما امکان پیمایش در یک آرایه چند بعدی را به جای یک آرایه تک بعدی فراهم می کند. انگار داخل هر چرخ و فلکی یک چرخ و فلک هست. 🤯

آرایه چند بعدی با استفاده از کارت ها تجسم شده است. از چپ به راست پشته‌ای از کارت‌های حاشیه بنفش است و در داخل هر کارت 1-چند کارت با حاشیه فیروزه‌ای وجود دارد. فهرست در یک لیست
اولین چرخ فلک دوستان
دومین چرخ فلک داستان‌های «انباشته».
👍 لیست در یک لیست، با نام مستعار: یک آرایه چند بعدی

انتخاب ابزار مناسب برای کار

در مجموع به لطف چند ویژگی مهم پلتفرم وب، ساخت این مؤلفه را بسیار ساده دیدم. بیایید آنها را بپوشانیم!

شبکه CSS

مشخص شد که چیدمان ما برای CSS Grid چندان مناسب نیست، زیرا به روش‌های قدرتمندی برای بحث کردن محتوا مجهز شده است.

چیدمان دوستان

بسته بندی مولفه .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;
}
استفاده از Chrome DevTools' Device Mode برای برجسته کردن ستون های ایجاد شده توسط Grid

بیایید طرح بندی grid را تجزیه کنیم:

  • ما به صراحت ویوپورت روی موبایل را با 100vh و 100vw پر می کنیم و اندازه را روی دسکتاپ محدود می کنیم
  • / قالب های سطر و ستون ما را از هم جدا می کند
  • auto-flow به grid-auto-flow: column
  • الگوی جریان خودکار 100% است، که در این مورد، عرض پنجره اسکرول هر چه باشد است

در تلفن همراه، به این فکر کنید که اندازه ردیف ارتفاع درگاه و هر ستون عرض درگاه دید باشد. در ادامه با مثال استوری های اسنپ چت و استوری های اینستاگرام، هر ستون استوری یک دوست خواهد بود. ما می‌خواهیم داستان‌های دوستان در خارج از ویوپورت ادامه پیدا کند، بنابراین جایی برای حرکت داریم. 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 Scroll Snap Points

مشخصات CSS Scroll Snap Points، قفل کردن عناصر در نما در هنگام اسکرول را آسان می کند. قبل از اینکه این ویژگی‌های CSS وجود داشته باشد، باید از جاوا اسکریپت استفاده می‌کردید، و حداقل می‌توان گفت دشوار بود. برای آشنایی با نحوه استفاده از آنها ، معرفی CSS Scroll Snap Points توسط سارا دراسنر را بررسی کنید.

پیمایش افقی بدون و با سبک‌های 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;
}
والد با overscroll رفتار snap را تعریف می کند.
کودک
.user {
  display: grid;
  grid: [story] 1fr / [story] 1fr;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
کودکان تصمیم می گیرند که یک هدف فوری باشند.

من Scroll Snap Points را به چند دلیل انتخاب کردم:

  • دسترسی رایگان . مشخصات Scroll Snap Points بیان می‌کند که با فشار دادن کلیدهای جهت‌نمای چپ و راست باید به‌طور پیش‌فرض از میان نقاط ضربه‌ای حرکت کند.
  • مشخصات رو به رشد مشخصات Scroll Snap Points همیشه در حال دریافت ویژگی‌ها و پیشرفت‌های جدید است، به این معنی که جزء Stories من احتمالاً از اینجا به بعد بهتر می‌شود.
  • سهولت اجرا . Scroll Snap Points عملاً برای صفحه‌بندی افقی لمسی ساخته شده‌اند.
  • اینرسی به سبک پلت فرم رایگان . هر پلتفرمی به سبک خود اسکرول می‌کند و استراحت می‌کند، برخلاف اینرسی عادی که می‌تواند سبک اسکرول و استراحت غیرعادی داشته باشد.

سازگاری بین مرورگرها

ما روی اپرا، فایرفاکس، سافاری، کروم و اندروید و iOS آزمایش کردیم. در اینجا خلاصه مختصری از ویژگی های وب است که در آن تفاوت هایی در قابلیت ها و پشتیبانی پیدا کردیم.

اگرچه برخی از CSS ها اعمال نمی شوند، بنابراین برخی از پلتفرم ها در حال حاضر بهینه سازی UX را از دست داده اند. من از عدم نیاز به مدیریت این ویژگی‌ها لذت بردم و مطمئن بودم که در نهایت به مرورگرها و پلتفرم‌های دیگر خواهند رسید.

scroll-snap-stop

چرخ فلک ها یکی از موارد اصلی استفاده از UX بودند که باعث ایجاد مشخصات CSS Scroll Snap Points شد. برخلاف Stories، یک چرخ فلک همیشه نیازی به توقف روی هر تصویر پس از تعامل کاربر با آن ندارد. شاید خوب باشد یا تشویق شود که به سرعت در چرخ و فلک بچرخید. از سوی دیگر، استوری‌ها به بهترین شکل یک به یک پیمایش می‌شوند، و این دقیقاً همان چیزی است که scroll-snap-stop ارائه می‌دهد.

.user {
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

در زمان نوشتن این پست، scroll-snap-stop فقط در مرورگرهای مبتنی بر Chromium پشتیبانی می‌شود. برای به روز رسانی، سازگاری مرورگر را بررسی کنید. اگرچه این یک مسدود کننده نیست. این فقط به این معنی است که در مرورگرهای پشتیبانی نشده کاربران می توانند به طور تصادفی دوست خود را رد کنند. بنابراین کاربران فقط باید مراقب باشند، در غیر این صورت باید جاوا اسکریپت بنویسیم تا اطمینان حاصل کنیم که دوستی که نادیده گرفته شده به عنوان مشاهده شده علامت‌گذاری نشده است.

در صورت علاقه بیشتر در مشخصات بخوانید.

overscroll-behavior

آیا تا به حال در حال پیمایش در یک مودال بوده اید که ناگهان شروع به پیمایش محتوای پشت مودال کنید؟ overscroll-behavior به توسعه‌دهنده اجازه می‌دهد آن اسکرول را به دام بیاندازد و هرگز اجازه خروج از آن را ندهد. برای انواع مناسبت ها خوب است. مؤلفه My Stories از آن برای جلوگیری از خروج تند کشیدن‌های اضافی و حرکات حرکتی از مؤلفه استفاده می‌کند.

.stories {
  overflow-x: auto;
  overscroll-behavior: contain;
}

سافاری و اپرا 2 مرورگرهایی بودند که از این پشتیبانی نمی‌کردند و این کاملاً اشکالی ندارد. آن دسته از کاربران یک تجربه Overscroll را خواهند داشت که به آن عادت کرده اند و ممکن است هرگز متوجه این پیشرفت نشوند. من شخصاً طرفدار بزرگی هستم و دوست دارم آن را به عنوان بخشی از تقریباً هر ویژگی Overscroll که پیاده‌سازی می‌کنم قرار دهم. این یک افزودنی بی ضرر است که تنها می تواند به بهبود UX منجر شود.

scrollIntoView({behavior: 'smooth'})

وقتی کاربر ضربه می‌زند یا کلیک می‌کند و به پایان مجموعه داستان‌های دوستش می‌رسد، وقت آن است که به دوست بعدی در مجموعه نقطه اسکرول بروید. با جاوا اسکریپت، ما توانستیم به دوست بعدی ارجاع دهیم و درخواست کنیم که آن را برای مشاهده پیمایش کنیم. پشتیبانی از اصول اولیه این عالی است. هر مرورگر آن را به نمایش اسکرول کرد. اما، همه مرورگرها این کار را 'smooth' انجام ندادند. این فقط به این معنی است که به جای عکس برداری به نمای پیمایش می شود.

element.scrollIntoView({
  behavior: 'smooth'
})

Safari تنها مرورگری بود که behavior: 'smooth' . برای به روز رسانی، سازگاری مرورگر را بررسی کنید.

دست در

حالا که می دانی من چگونه این کار را انجام دادم، شما چطور؟! بیایید رویکردهایمان را متنوع کنیم و همه راه‌های ساخت در وب را بیاموزیم. یک اشکال ایجاد کنید، نسخه خود را برای من توییت کنید ، و من آن را به بخش ریمیکس های انجمن در زیر اضافه می کنم.

ریمیکس های انجمن