كيفية إنشاء مقاطع تمرير Snapping باستخدام CSS Scroll-Snap (بديل fullpage.js)

نشرت: 2022-07-19

في هذا البرنامج التعليمي ، سنقوم بإنشاء صفحة يتم التقاطها من قسم ملء الشاشة إلى قسم آخر أثناء قيام المستخدم بالتمرير. تم تعميم هذا التأثير بواسطة مكتبة fullpage.js . ولكن الآن ، هناك خيارات أفضل بسبب تغييرات الترخيص للصفحة الكاملة (تحتاج الآن إلى دفع ثمنها) ، ووحدة CSS التمرير المفاجئة الجديدة ، ودعم المتصفح الكامل لواجهة برمجة تطبيقات مراقب التقاطع.

لذا ، إذا كنت تبحث عن بديل fullpage.js ، فقد لا تحتاج حتى إلى مكتبة كاملة ، يمكنك فقط ترميزها بنفسك!

في الواقع ، تأثير الانجذاب هو 100٪ CSS. يتم استخدام JS فقط لتلاشي العناصر عند عرض الشاشة.

سنستفيد من "عرض التمرير السريع لمنتزه Dinosaur Park" بواسطة Michelle Barker المتاح على CodePen للإلهام:

https://codepen.io/michellebarker/pen/PowYKXJ شاهد العرض التوضيحي المفاجئ لتمرير Pen Dinosaur Park بواسطة Michelle Barker (michellebarker) على CodePen.

تنبيه ، ربما تريد عرض هذا على شاشة أكبر لتجربة تأثير "التمرير المفاجئ" بشكل كامل.

باستخدام CSS إلى جانب Intersection Observer ، سنجعل كل قسم بملء الشاشة من الصفحة سريعة التمرير ، ويتلاشى المحتوى عند دخوله في إطار العرض.

والأفضل من ذلك ، إنها فقط 30 سطرًا من كود JS! الرسوم المتحركة تتم باستخدام CSS ؛ كل ما نحتاج إلى القيام به هو فهم متى تدخل الأقسام والمحتوى في إطار العرض الخاص بنا باستخدام JS.

1) بناء صفحتك

أولاً ، سوف تحتاج إلى إنشاء صفحة ، أو تكوين صفحة موجودة لتكون متوافقة مع هذا التأثير البسيط. هناك شيئان يجب ملاحظتهما هنا:

نحن نستخدم عنصر <main> ، والذي يحتوي على أقسامنا. هذا العنصر الرئيسي هو 100vh ، كما هو الحال مع كل عنصر من عناصر <section> بداخله.

لغة البرمجة:

<main> <section class = "section section-1"> <div class = "section__content" data-content> المحتوى داخل </ div> </section> <section class = "section section-2"> <div class = "section__content" data-content> محتوى داخلي </ div> </section> <section class = "section section-3"> <header class = "section__header"> <h3 class = "section__title"> استكشاف واكتشاف </ h3 > </header> <div class = "section__content" data-content> محتوى داخلي </ div> </section> </main>

CSS:

/ * سلوك التمرير * /media (min-height: 30em) {main {scroll-snap-type: y mandatory؛ الارتفاع: 100 فولت تجاوز- y: التمرير ؛ }}. القسم {اللون: أبيض؛ الموقف: نسبي ؛ محاذاة التمرير المفاجئة: مركز ؛ عرض: فليكس ؛ الاتجاه المرن: العمود. ارتفاع الحد الأدنى: 100vh ؛ }media (min-height: 30em) {.section {height: 100vh؛ }}

2) تكوين Snapping باستخدام CSS

صورة -16-11

هنا يمكننا أن نرى أن هناك عدة أقسام ، كل منها بارتفاع 100vh.

العنصر <main> ، هو أيضًا 100vh ، مع overflow-y: scroll.

بالنسبة للمستخدم ، فإن سلوك التمرير هو نفس سلوك صفحة الويب الافتراضية.

إذا قمت بإضافة CSS المذكورة أعلاه ، فسيكون تأثير الانجذاب قيد التشغيل بالفعل. دعونا نلقي نظرة على كيفية عملها.

أولاً ، يقوم الاستعلام " @media (min-height: 30em) " بتعطيل تأثير الانجذاب لأحجام شاشات الجوال التي تكون قصيرة من حيث الارتفاع. تحت القسم الرئيسي ، هناك خاصية واحدة تتيح الالتقاط:

رئيسي {.... scroll-snap-type: y إلزامي ؛ ....}

هذه خاصية صغيرة رائعة "تحدد مدى دقة تطبيق نقاط الانجذاب على حاوية التمرير في حالة وجود واحدة" (MDN).

ثم تحت أقسامنا ، لدينا:

.section {.... scroll-snap-align: center ؛.section {.... scroll-snap-align: center؛ ....}

تحدد هذه الخاصية "موضع الانجذاب للمربع كمحاذاة لمنطقة المفاجئة الخاصة به (كموضوع المحاذاة) داخل علاقة الحاوية المفاجئة (مثل حاوية المحاذاة)" (MDN).

تعرف على المزيد حول وحدة CSS scroll-snap هنا:

وهي بهذه البساطة. قم بتوجيه العناصر الفرعية داخل الحاوية <الرئيسية> (جميع الأقسام) ، سيتم تمريرها بسرعة إلى مركز الحاوية <الرئيسية>. نظرًا لأن كلا من القسم الرئيسي والقسم 100 فولت في الساعة ، فسيتم التمرير من قسم إلى آخر.

3) تتلاشى المحتوى باستخدام مراقب التقاطع

الآن ، لدينا تأثير تمرير صفحة كاملة ، وإذا كنت لا تريد القيام بأي شيء آخر ، فيمكنك تخطي هذا القسم والاستمتاع بموقع الويب الخاص بك. ومع ذلك ، عندما يتم عرض كل قسم صفحة كاملة في العرض ، أريد أن أتلاشى المحتوى بداخله - تأثير فريد ورائع (وهو أيضًا تأثير ممكن مع fullpage.js).

للقيام بذلك ، سنستخدم مراقب التقاطع لفهم موضع الأقسام في منفذ العرض <الرئيسي>.

أقسام const = [... document.querySelectorAll ("section")] ؛ دع الخيارات = {rootMargin: "0px"، threshold: 0.75،} ؛ const callback = (إدخالات ، مراقب) => {إدخالات.forEach ((إدخال) => {const {target} = entry ؛ if (entry.intersectionRatio> = 0.75) {target.classList.add ("is-visual") ؛} else {target.classList.remove ("is-visual")؛}})؛ } ؛ const Observer = جديد IntersectionObserver (رد اتصال ، خيارات) ؛ section.forEach ((section، index) => {const sectionChildren = [... section.querySelector ("[data-content]"). children]؛ sectionChildren.forEach ((el، index) => {el.style .setProperty ("- delay"، `$ {index * 250} ms`)؛})؛ Observer.observe (section)؛})؛

هناك شيئين يتم القيام به هنا. أولاً ، يحدد متى يكون القسم في منفذ العرض ، وعند دخوله ، يضيف فئة CSS .is-visible . نظرًا لأنه يغادر منفذ العرض ، فإنه يزيل تلك الفئة.

بالإضافة إلى ذلك ، نظرًا لأن هذا القسم يدخل منفذ العرض ، فإنه يحدد خاصية التأخير على التوالي (واحدة تلو الأخرى) لمدة 250 مللي ثانية على كل عنصر من العناصر الفرعية. هذا يجعل من التلاشي المذهل ساري المفعول.

إنه يفعل ذلك فقط للأطفال داخل العناصر التي لها سمة محتوى البيانات. لذلك تحتاج إلى إضافة ذلك إلى الأغلفة حول محتوى صفحاتك إذا كنت تريد أن يصبح التلاشي ساري المفعول.

الآن ، لإنجاح هذا الأمر ، نحتاج إلى إعداد الرسوم المتحركة الخفوت للعناصر التي تمت إضافة فئة .is-visual.

media (min-height: 30em) {.section__content> * {عتامة: 0 ؛ التحويل: translate3d (0، 4rem، 0)؛ الانتقال: عتامة 800 مللي ثانية var (- تأخير) ، تحويل 800 مللي ثانية مكعب بيزير (0.13 ، 0.07 ، 0.26 ، 0.99) var (- تأخير) ؛ }} .is-visual .section__content> * {عتامة: 1 ؛ التحويل: translate3d (0، 1rem، 0)؛ } .is-visual .section__img {عتامة: 0.75؛ }

إذا رجعنا إلى HTML من العرض التوضيحي الأول ، فسترى أن هناك عنصر div يلتف حول المحتوى بفئة .section__content ، وسمة data-content.

<main> <section class = "section section-1"> <div class = "section__content" data-content> المحتوى داخل </ div> </section> <section class = "section section-2"> <div class = "section__content" data-content> محتوى داخلي </ div> </section> <section class = "section section-3"> <header class = "section__header"> <h3 class = "section__title"> استكشاف واكتشاف </ h3 > </header> <div class = "section__content" data-content> محتوى داخلي </ div> </section> </main>

هذا يربط JS و CSS معًا. العتامة هي 0 للمحتوى حتى تتم إضافة فئة .is-visible بواسطة مراقب التقاطع عند دخولها في منفذ العرض. عندما يغادر ، يعود مرة أخرى إلى عتامة 0 ، لذلك بغض النظر عن اتجاه التمرير الخاص بك ، سيكون هناك دائمًا تغذية سارية المفعول.

وأخيرًا ، فإن delay الذي يتم تطبيقه على التوالي على كل عنصر فرعي يؤدي إلى تلاشي تأثير التلاشي.

لاحظ القسم الثالث. عنوان القسم ليس ضمن قسم محتوى البيانات ، لذلك لن يتلاشى (سيكون موجودًا بالفعل).

كل الكود

ها هو العرض:

الخواص -2022-07-15-at-15-00-58

هذا هو كل الكود الذي استخدمناه في العرض التوضيحي الخاص بنا:

لغة البرمجة

<main> <section class = "section section-1"> <div class = "section__content" data-content> <img class = "section__img section__img - left" src = "https: // s3-us-west-2 .amazonaws.com / s.cdpn.io / 85648 / trex.svg "alt =" T-rex "/> <h2> محتوى داخلي </ h2> <p> بلاه بلاه بلاه </ p> </div> < / section> <section class = "section section-2"> <div class = "section__content" data-content> <h2> محتوى داخلي </ h2> <p> بلاه بلاه بلاه </ p> </div> </ section> <section class = "section section-3"> <header class = "section__header"> <h3 class = "section__title"> استكشاف واكتشاف </ h3> </header> <div class = "section__content" data-content > <h2> محتوى داخلي </ h2> <p> بلاه بلاه بلاه </ p> </div> </section> </main>

CSS

media (min-height: 30em) {main {scroll-snap-type: y mandatory؛ الارتفاع: 100 فولت تجاوز- y: التمرير ؛ }}. القسم {اللون: أبيض؛ الموقف: نسبي ؛ محاذاة التمرير المفاجئة: مركز ؛ عرض: فليكس ؛ الاتجاه المرن: العمود. ارتفاع الحد الأدنى: 100vh ؛ }media (min-height: 30em) {.section {height: 100vh؛ }}media (min-height: 30em) {.section__content> * {عتامة: 0 ؛ التحويل: translate3d (0، 4rem، 0)؛ الانتقال: عتامة 800 مللي ثانية var (- تأخير) ، تحويل 800 مللي ثانية مكعب بيزير (0.13 ، 0.07 ، 0.26 ، 0.99) var (- تأخير) ؛ }} .is-visual .section__content> * {عتامة: 1 ؛ التحويل: translate3d (0، 1rem، 0)؛ } .is-visual .section__img {عتامة: 0.75؛ }

شبيبة

أقسام const = [... document.querySelectorAll ("section")] ؛ دع الخيارات = {rootMargin: "0px"، threshold: 0.75،} ؛ const callback = (إدخالات ، مراقب) => {إدخالات.فور كل ((إدخال) => {const {target} = entry ؛ if (entry.intersectionRatio> = 0.75) {target.classList.add ("is-visual") ؛} else {target.classList.remove ("is-visual")؛}})؛ } ؛ const Observer = جديد IntersectionObserver (رد اتصال ، خيارات) ؛ section.forEach ((section، index) => {const sectionChildren = [... section.querySelector ("[data-content]"). children]؛ sectionChildren.forEach ((el، index) => {el.style .setProperty ("- delay"، `$ {index * 250} ms`)؛})؛ Observer.observe (section)؛})؛

استنتاج

هذا هو البديل المثالي fullpage.js الذي لا يتوقف فقط عند الالتقاط بين أقسام ملء الشاشة. استخدمنا أيضًا واجهة برمجة تطبيقات مراقب التقاطع لفهم متى يدخل قسم ما إلى الصفحة ثم نطبق ديناميكيًا رسمًا متحركًا متداخلاً. يمكنك استخدام هذا المثال الأساسي للبناء وإحداث بعض التأثيرات الرائعة حقًا باستخدام الحد الأدنى من Vanilla JS و CSS.