أنشِئ تجارب تمرير منظَّم جيدًا من خلال الإعلان عن مواضع انطباق التمرير.
تسمح ميزة CSS Scroll Snap لمطوّري البرامج على الويب بإنشاء تجارب تمرير متحكّم فيها جيدًا من خلال الإعلان عن مواضع انطباق التمرير. تُعد المقالات المقسّمة إلى صفحات ولوحات العرض الدوّارة للصور مثالين شائعين للاستخدام على ذلك. يوفر CSS Scroll Snap واجهة برمجة تطبيقات سهلة الاستخدام ومتسقة لإنشاء أنماط تجربة المستخدم الشائعة هذه.
الخلفية
حالة انطباق التمرير
يُعد التمرير طريقة شائعة وطبيعية للتفاعل مع المحتوى على الويب. إنّه الوسيلة الأصلية للمنصة لتوفير الوصول إلى معلومات أكثر من تلك التي تكون مرئية على الشاشة في الوقت نفسه، وسيصبح هذا المحتوى عاملاً حيويًا بشكل خاص على الأنظمة الأساسية للأجهزة الجوّالة ذات المساحات المحدودة للشاشة. لذلك، ليس من المستغرب أن يفضل مؤلفو الويب بشكل متزايد تنظيم المحتوى في قوائم مسطحة قابلة للتمرير بدلاً من تسلسلات هرمية عميقة.
العيب الرئيسي للتمرير هو افتقار الدقة. نادرًا ما تتم محاذاة التمرير مع فقرة أو جملة. ويزيد لفظها على المحتوى المقسّم على صفحات أو المحتوى المقسّم إلى فئات ذات حدود ذات معنى عند انتهاء التمرير في منتصف الصفحة أو الصورة، ما يجعلها مرئية جزئيًا. تستفيد حالات الاستخدام هذه من تجربة تمرير يتم التحكم فيها جيدًا.
اعتمد مطورو الويب منذ فترة طويلة على الحلول المستندة إلى JavaScript للتحكم في التمرير للمساعدة في معالجة هذا القصور. ومع ذلك، لا تنجح الحلول المستندة إلى JavaScript في توفير حل كامل الدقة بسبب نقص العناصر الأساسية لتخصيص التمرير أو الوصول إلى التمرير المركَّب. يضمن لك CSS Scroll Snap تقديم حل سريع وعالي الدقة وسهل الاستخدام يعمل باتساق على مختلف المتصفّحات.
يسمح CSS Scroll Snap لمؤلفي الويب بوضع علامة على كل حاوية تمرير بحدود لعمليات التمرير التي تنتهي عندها. بعد ذلك، تختار المتصفحات موضع النهاية الأنسب بناءً على تفاصيل عملية التمرير، وتنسيق حاوية التمرير ومستوى رؤيتها، وتفاصيل مواضع الانطباق، ثم تحريكها بسلاسة. بالعودة إلى مثالنا السابق، عندما ينتهي المستخدم من تمرير العرض الدوار، تستقر صورته المرئية في مكانها. لا حاجة إلى تعديلات التمرير التي يحتاجها JavaScript.
محاذاة صفحات CSS
انطباق التمرير هو عملية ضبط إزاحة التمرير لحاوية التمرير لتكون في موضع الانطباق المفضل بعد انتهاء عملية التمرير.
يمكن تفعيل ميزة "محاذاة التمرير" لحاوية التمرير باستخدام السمة
scroll-snap-type
. وهذا يخبر المتصفح أنه يجب أن يفكر في التقاط حاوية التمرير هذه على مواضع الانطباق التي تنتجها العناصر التابعة. وتحدّد السمة scroll-snap-type
المحور الذي يحدث التمرير عليه: x
أو y
أو both
، ومدى دقة الانطباق: mandatory
أو proximity
. سنتحدّث عن المزيد حول هذا لاحقًا.
يمكن إنشاء موضع الانطباق من خلال إعلان المحاذاة المطلوبة على أحد العناصر.
هذا الموضع هو إزاحة التمرير التي تتم عندها محاذاة أقرب حاوية تمرير للأصل والعنصر كما هو محدد للمحور المحدّد. ويمكن إجراء عمليات المحاذاة التالية على كل محور: start
وend
وcenter
.
تعني محاذاة start
أنّه يجب محو حافة بداية منطقة الانطباق لحاوية التمرير
مع حافة بداية منطقة الانطباق للعنصر. وبالمثل، تعني محاذاة end
وcenter
أنّه يجب إبعاد حافة نهاية منفذ الانطباق لحاوية التمرير أو منتصفها مع حافة نهاية منطقة الانطباق أو الوسط.
توضح الأمثلة التالية كيفية استخدام هذه المفاهيم.
مثال: معرض أفقي
من حالات الاستخدام الشائعة لمحاذاة التمرير هي العرض الدوار للصور. على سبيل المثال، لإنشاء لوحة عرض دوّارة للصور الأفقية تظهر على كل صورة أثناء التمرير، يمكننا تحديد حاوية التمرير لإظهار علامة scroll-snap-type
إلزامية على المحور الأفقي، وضبط كل صورة على القيمة scroll-snap-align: center
لضمان توسيط الصورة في لوحة العرض الدوّارة.
#gallery {
scroll-snap-type: x mandatory;
overflow-x: scroll;
display: flex;
}
#gallery img {
scroll-snap-align: center;
}
<div id="gallery">
<img src="cat.jpg">
<img src="dog.jpg">
<img src="another_cute_animal.jpg">
</div>
نظرًا لارتباط مواضع الانطباق بعنصر، يمكن لخوارزمية الانطباق تحديد وقت وكيفية الانطباق وفقًا للعنصر وحجم حاوية التمرير. على سبيل المثال، ضع في اعتبارك الحالة التي تكون فيها صورة أكبر من العرض الدوار. قد تمنع خوارزمية الالتقاط المبهر المستخدم من الدوران حول الصورة لرؤية الصورة الكاملة. إلا أنّ المواصفات تتطلب عمليات تنفيذ لرصد هذه الحالة والسماح للمستخدم بالتمرير بحرية داخل تلك الصورة التي تظهر عند حوافها فقط.
مثال: صفحة منتج متنقّلة
هناك حالة أخرى شائعة يمكن أن تستفيد من سرعة الانطباق هي الصفحات التي تحتوي على أقسام منطقية متعددة للتمرير عموديًا، مثل صفحة منتج نموذجية. في مثل هذه الحالات، يكون استخدام scroll-snap-type: y proximity;
أكثر طبيعية. لا يتداخل هذا عندما يمرر المستخدم إلى منتصف قسم معين
بل يستقطب أيضًا الانتباه ويجذب الانتباه إلى قسم جديد عند تمريره على مسافة قريبة بما فيه الكفاية.
إليك كيفية تحقيق ذلك:
article {
scroll-snap-type: y proximity;
/* Reserve space for header plus some extra space for sneak peeking. */
scroll-padding-top: 15vh;
overflow-y: scroll;
}
section {
/* Snap align start. */
scroll-snap-align: start;
}
header {
position: fixed;
height: 10vh;
}
<article>
<header> Header </header>
<section> Section One </section>
<section> Section Two </section>
<section> Section Three </section>
</article>
المساحة المتروكة والهامش للتمرير
تتضمّن صفحة المنتج عنوانًا علويًا ثابتًا. طلب التصميم أيضًا أن يظل بعض القسم العلوي مرئيًا عند التقاط حاوية التمرير من أجل توفير إشارة تصميم للمستخدمين حول المحتوى أعلاه.
إنّ السمة scroll-padding
هي خاصية css جديدة يمكن استخدامها لضبط المنطقة
الفعّالة القابلة للعرض لحاوية التمرير أو منفذ الالتقاط، والتي
يتم استخدامها عند حساب محاذاة انطباق التمرير. تحدد الخاصية مساحة داخلية
مقابل مربع المساحة المتروكة لحاوية التمرير. في المثال الذي نقدّمه، تمت إضافة مساحة داخلية 15vh
إضافية إلى الأعلى
لتوجيه المتصفح إلى وضع علامة في موضع أدنى،
15vh
أسفل الحافة العلوية لحاوية التمرير، كحافة البداية العمودية
لمحاذاة التمرير. عند الانطباق، يتم تحريك حافة العنصر المستهدف
الانطباق بهذا الموضع الجديد، وبالتالي يتم ترك مساحة في الأعلى.
تحدِّد السمة scroll-margin
المقدار الإضافي الذي يتم استخدامه لضبط المربّع الفعال لهدف الانطباق على غرار طريقة عمل scroll-padding
في حاوية التمرير
اللبس.
ربما لاحظت أن هاتين الخاصيتين لا تحتويان على كلمة "snap
"
فيهما. وهذا مقصود لأنّهم في الواقع يعدّلون المربّع لجميع عمليات الانتقال ذات الصلة، وليس مجرد انطباق التمرير. على سبيل المثال، يأخذ Chrome
في الاعتبار عند احتساب حجم الصفحة في عمليات الانتقال ضمن الصفحات، مثل
PageDown وPageUp، وكذلك عند احتساب مقدار الانتقال لعملية
Element.scrollIntoView()
.
التفاعل مع واجهات برمجة تطبيقات التمرير الأخرى
واجهة برمجة التطبيقات لتمرير DOM
يحدث محاذاة التمرير بعد جميع عمليات التمرير، بما في ذلك العمليات التي يبدأها النص البرمجي. عند استخدام واجهات برمجة تطبيقات، مثل Element.scrollTo
، سيحسب المتصفّح موضع التمرير المقصود للعملية، ثم يطبّق منطق الانطباق المناسب للعثور على الموضع النهائي للانقطاع. وبالتالي، ليست هناك حاجة إلى النص البرمجي للمستخدم
لإجراء أي عمليات حسابية يدوية للالتقاط.
التمرير السلس
يتحكّم "التمرير السلس" في سلوك عملية الانتقال الآلي، في حين يحدِّد "التمرير السلس" وجهته. نظرًا لأنها تتحكم في الجوانب المتعامدة للتمرير، يمكن استخدامها معًا وتكمل بعضها البعض.
سلوك الانتقال الزائد
واجهة برمجة التطبيقات لسلوك التمرير الزائد تتحكّم في كيفية تسلسل التمرير بين عناصر متعددة ولا تتأثر هذه الواجهة بانتقال التمرير.
المحاذير وأفضل الممارسات
تجنَّب استخدام الانطباق الإلزامي عندما تكون العناصر المستهدفة متباعدة على نطاق واسع. وقد يؤدي هذا إلى تعذُّر الوصول إلى المحتوى الواقع بين مواضع الانطباق.
في كثير من الحالات يمكن إضافة الانطباق التمرير كتحسين بدون الحاجة إلى الكشف عن الميزات.
إذا لزم الأمر، يمكنك استخدام @supports
أو CSS.supports
لاكتشاف التوافق مع CSS Scroll Snap.
تجنَّب استخدام السمة scroll-snap-type
المتوفّرة أيضًا في المواصفات المتوقّفة نهائيًا.
رصد الميزات في CSS
@supports (scroll-snap-align: start) {
article {
scroll-snap-type: y proximity;
scroll-padding-top: 15vh;
overflow-y: scroll;
}
}
رصد الميزات في JavaScript
if (CSS.supports('scroll-snap-align: start')) {
// use css scroll snap
} else {
// use fallback
}
لا تفترض أنّ واجهات برمجة التطبيقات المخصّصة للتمرير الآلي مثل Element.scrollTo
تنتهي دائمًا عند معادلة الانتقال المطلوبة. قد يعدّل الانطباق التمرير إزاحة التمرير بعد اكتمال الانتقال الآلي. لاحظ أن هذا لم يكن افتراضًا جيدًا حتى قبل انطباق التمرير لأن التمرير ربما يكون قد توقف
لأسباب أخرى، ولكن هذا ينطبق بشكل خاص على انطفاء التمرير.
العمل المستقبلي
كانت تجربة التنقّل محور تركيز
استطلاع حديث أجراه فريق Chrome.
حددت نتائج الاستطلاع عدة مجالات تحتاج إلى عمل إضافي
لتقليص الفجوة بين مكتبات المكونات الإضافية وCSS.
سيركّز العمل القادم على "scroll-snap
"، بما في ذلك:
- مدى توفر واجهة برمجة التطبيقات والتوافق عبر المتصفحات.
- يمكنك العمل على واجهات برمجة تطبيقات CSS جديدة، مثل
scroll-start
. - عليك العمل على أحداث JavaScript جديدة، مثل
snapChanged()
.