برای نمایش بکشید

«کشیدن برای آشکار کردن» یک الگوی واسط کاربر است که در آن محتوا (مانند نوار جستجو یا کنترل بازآوری) در بالای یک ناحیه پیمایش‌شدنی در بارگیری اولیه پنهان می‌شود و کاربر می‌تواند برای آشکار کردن آن، صفحه را پایین بکشد (به‌بالا پیمایش کند). این الگو معمولاً در برنامه‌های تلفن همراه و برنامه‌های وب برای نوارهای جستجو، فیلترها، و سایر کنترل‌های ثانویه استفاده می‌شود که باید دردسترس باشند اما بلافاصله قابل‌مشاهده نباشند.

ویژگی CSS scroll-initial-target روشی اعلانی و فقط CSS برای پیاده‌سازی این الگو ارائه می‌دهد. با تنظیم scroll-initial-target: nearest روی عنصر محتوای اصلی، محفظه پیمایش با محتوای پنهان پیمایش‌شده از دید رندر خواهد شد. قبلاً توسعه‌دهندگان برای انجام این کار به جاوا اسکریپت (Element.scrollIntoView()) یا شناسه‌های قطعه نشانی وب (#content-id) متکی بودند که هر دو محدودیت‌هایی دارند و پیاده‌سازی آن‌ها دشوار است.

نحوه پیاده‌سازی

برای پیاده‌سازی الگوی «کشیدن برای آشکار کردن»:

  1. مطمئن شوید که محفظه پیمایش وجود دارد: عنصر هدف باید داخل محفظه پیمایش باشد (عنصری با سرریز که پیمایش را مجاز می‌کند، مثل overflow: auto). این می‌تواند هر عنصر اجدادی باشد، ازجمله عنصر ریشه <html>.
  2. عنصر پنهان را تعریف کنید: محتوایی را که می‌خواهید پنهان کنید (مثلاً نوار جستجو) به‌عنوان اولین فرزند در داخل محفظه پیمایش قرار دهید. این عنصر در بارگیری اولیه از نما پیمایش خواهد شد.
  3. تعریف محتوای اصلی: عنصر محتوای اصلی را بلافاصله بعداز عنصر پنهان قرار دهید. این عنصری است که کاربر باید اول ببیند.
  4. محتوای اصلی را هدف قرار دهید: scroll-initial-target: nearest را روی عنصر محتوای اصلی اعمال کنید تا محفظه پیمایش با پیمایش آن به داخل نما رندر شود و عنصر بالای آن پنهان شود.
  5. افزودن میزان کردن پیمایش: برای اطمینان از اینکه عنصر پنهان همیشه یا کاملاً نمایان است یا کاملاً پنهان (و در حالت نیمه‌پیمایش‌شده باقی نمی‌ماند)، scroll-snap-type: y mandatory را به محفظه پیمایش و scroll-snap-align: start را به عنصر پنهان و عنصر محتوای اصلی اضافه کنید.
/**
 * ANCESTOR: Define the scroll container.
 * Scroll snapping ensures the search bar is always
 * either fully visible or fully hidden.
 */
.scroll-container {
  height: 100vh;
  overflow-y: auto;
  scroll-snap-type: y mandatory;
}

/**
 * HIDDEN ELEMENT: The search bar hidden above the fold on load.
 * It has scroll-snap-align so it snaps into place when pulled down.
 */
.search-bar {
  height: 60px;
  scroll-snap-align: start;
}

/**
 * MAIN CONTENT + TARGET: The element the user sees first.
 * scroll-snap-align makes it a valid snap point.
 * scroll-initial-target tells the browser to scroll here on
 * initial render, hiding the search bar above it.
 */
.main-content {
  scroll-snap-align: start;
  scroll-initial-target: nearest;
}

پیاده‌سازی استراتژیک و روال‌های مطلوب

  • باید از scroll-initial-target: nearest استفاده کنید وقتی می‌خواهید توجه کاربر را به بخش خاصی از ناحیه پیمایش‌شدنی هنگام بار کردن جلب کنید و به‌طور عمدی واحدهای واسط کاربر جانبی مثل نوار جستجو را در بالاترین قسمت پنهان کنید.
  • این را با تمرکز دسترس‌پذیری اشتباه نگیرید. این ویژگی فقط نمای دیداری را جابه‌جا می‌کند؛ تمرکز صفحه‌کلید را جابه‌جا نمی‌کند. اگر هدف قرار است نقطه شروع برای کاربران صفحه‌کلید باشد، باید element.focus() را به‌صورت دستی مدیریت کنید.
  • اگر به پویانمایی «پیمایش» روان هنگام بار کردن نیاز دارید، از این ویژگی استفاده نکنید؛ این ویژگی گسسته است و موقعیت را فوراً درطول فاز چیدمان تنظیم می‌کند.
  • scroll-initial-target را روی چند عنصر در یک محفظه پیمایش‌پذیر تنظیم نکنید. اگر چند عنصر scroll-initial-target: nearest را مشخص کنند، مرورگر عنصری را انتخاب می‌کند که ابتدا در ترتیب درخت DOM ظاهر می‌شود.
  • باید سلسله‌مراتب تقدم را درنظر بگیرید: هم قطعه نشانی وب (مثلاً example.com/#top) و هم ویژگی scroll-start در سطح محفظه بر scroll-initial-target تقدم دارند.

راهبرد جایگزین

برای مرورگرهایی که هنوز از میانای برنامه‌سازی کاربردی پشتیبانی نمی‌کنند، از جاوا اسکریپت جایگزین استفاده کنید. توجه داشته باشید که برای کشیدن محتوا برای آشکار کردن، می‌خواهید محتوای اصلی به start (بالای) ظرف محدود شود.

/**
 * Progressive Enhancement Fallback
 */
document.addEventListener("DOMContentLoaded", () => {
  // Check for native CSS support
  if (!CSS.supports("scroll-initial-target", "nearest")) {
    const targetContent = document.querySelector('.main-content.target');
    if (targetContent) {
      // Use behavior: "instant" to mimic the native CSS behavior
      // 'block: start' should match your CSS 'scroll-snap-align' (or expected top position)
      targetContent.scrollIntoView({ behavior: 'instant', block: 'start' });
    }
  }
});