لا شكّ في أنّ الاختلاف والتشابه بين المبدأين المفضّل لديك هو مَن يعشقه. عند استخدامها بحكمة، فإنه يمكن لإضافة العمق والدقة إلى تطبيق الويب. ومع ذلك، تكمن المشكلة في أن تنفيذ اختلاف الأداء بطريقة فعالة يمكن أن يكون تحديًا. في هذه المقالة، لمناقشة حل فعّال ويعمل بنفس القدر من الأهمية عبر المتصفحات.
النص المختصر (TL:DR)
- لا تستخدِم أحداث التمرير أو
background-position
لإنشاء صور متحركة لتطبيق اختلاف المنظر. - استخدم تحويلات CSS ثلاثية الأبعاد لإنشاء تأثير اختلاف أكثر دقة.
- بالنسبة إلى Mobile Safari، استخدم
position: sticky
لضمان تأثير اختلاف أوجه الاختلاف المشروع.
إذا كنت ترغب في الحصول على الحل، يُرجى الانتقال إلى مستودع GitHub لعيّنات عناصر واجهة المستخدم والحصول على تطبيق Parallax helper JS يمكنك مشاهدة عرض توضيحي مباشر لشريط تمرير اختلاف المنظر في مستودع GitHub.
متباينات المشاكل
في البداية، دعونا نلقِ نظرة على طريقتين شائعتين لتحقيق اختلاف في الهدف التأثير، وعلى وجه التحديد، سبب عدم ملاءمتها لأغراضنا.
سيئ: استخدام أحداث التمرير
والمتطلب الرئيسي لتطبيق الاختلاف هو أنه يجب أن يتم الاقتران بالتمرير؛ حيث كل تغيير فردي في موضع التمرير في الصفحة، ويتأثر موضع الإعلان. ورغم أن ذلك يبدو بسيطًا، إلا أن هناك آلية مهمة المتصفحات الحديثة هي قدرتها على العمل بشكل غير متزامن. ينطبق ذلك، في في حالة خاصة، تمرير الأحداث. في معظم المتصفّحات، يتم عرض أحداث التمرير على أنه "أفضل جهد" ولا يتم ضمان عرضها في كل إطار من رسم متحرك التمرير!
تخبرنا هذه المعلومات المهمة لماذا نحتاج إلى تجنب حلّ مستند إلى JavaScript ينقل العناصر بناءً على أحداث التنقّل: لا تضمن JavaScript أن يتوافق الاختلاف مع موضع التمرير في الصفحة في الإصدارات السابقة من Mobile Safari، كانت أحداث الانتقال تسليمه بالفعل في نهاية التمرير، مما جعل من المستحيل إنشاء تأثير التمرير المستند إلى JavaScript تعرض الإصدارات الأحدث أحداث التمرير. أثناء الرسم المتحرك، ولكن كما هو الحال بالنسبة إلى Chrome، يتم بذل "أفضل جهد" بشكل أساسي. إذا كانت سلسلة التعليمات الرئيسية مشغولة بأي عمل آخر، ولن يتم تسليم أحداث التمرير على الفور، مما يعني أنه سيتم فقدان تأثير اختلاف الألوان.
سيئ: جارٍ تحديث background-position
هناك موقف آخر نريد تجنبه وهو الرسم على كل إطار. حلول عديدة
محاولة تغيير background-position
لتوفير مظهر اختلاف المنظر،
إعادة طلاء الأجزاء المتأثرة من الصفحة عند التمرير،
مكلفًا بدرجة كافية لتعطل الرسوم المتحركة بشكل كبير.
إذا أردنا تلبية وعدنا بحركة اختلاف التباين، فنحن نريد شيئًا كخاصية سريعة (والتي تعني في الوقت الحالي الالتزام ومعدل التحويل والتعتيم)، والتي لا تعتمد على أحداث التمرير.
CSS في التصميم الثلاثي الأبعاد
لدى كل من سكوت كيلوم وكيث كلارك بذلت جهدًا كبيرًا في مجال استخدام CSS ثلاثي الأبعاد لإحداث حركة اختلاف التباين، والأسلوب الذي يستخدمونه هو على النحو التالي:
- إعداد عنصر كامل للتمرير باستخدام
overflow-y: scroll
(على الأرجح)overflow-x: hidden
). - طبِّق على العنصر نفسه قيمة
perspective
وperspective-origin
. مضبوطة علىtop left
أو0 0
. - على العناصر الثانوية لهذا العنصر تطبيق ترجمة باللغة Z وتصغيرها لتوفير حركة اختلاف المنظر دون التأثير في حجمها على الشاشة.
تظهر CSS لهذا المنهج على النحو التالي:
.container {
width: 100%;
height: 100%;
overflow-x: hidden;
overflow-y: scroll;
perspective: 1px;
perspective-origin: 0 0;
}
.parallax-child {
transform-origin: 0 0;
transform: translateZ(-2px) scale(3);
}
والتي تفترض وجود مقتطف HTML على النحو التالي:
<div class="container">
<div class="parallax-child"></div>
</div>
ضبط المقياس للمنظور
سيؤدي دفع العنصر الفرعي للخلف إلى تقليل حجمه بما يتناسب مع المنظور. ويمكنك حساب مقدار الحاجة إلى زيادتها باستخدام المعادلة التالية: (منظور - مسافة) / المنظور. نظرًا لأننا على الأرجح نريد أن يظهر العنصر المتباين مع اختلاف في الحجم الذي كتبناه، فستحتاج إلى التوسع بهذه الطريقة، بدلاً من تركها كما هي.
في حالة الرمز البرمجي أعلاه، يكون تنسيق Perspective API هو 1 بكسل،
مسافة parallax-child
لـ Z هي -2 بكسل. هذا يعني أن العنصر سيحتاج
زيادة بمقدار 3 مرّات، ويمكنك الاطّلاع على القيمة المضمّنة في الرمز البرمجي:
scale(3)
بالنسبة إلى أي محتوى لا يتم تطبيق قيمة translateZ
عليه، يمكنك
التعويض عن صفر. يعني ذلك أن المقياس هو (منظور - 0) /
والمنظور، الذي يحدد القيمة 1، ما يعني أنه قد تم تقليصه
ليس لأعلى أو لأسفل. مفيد جدًا،
طريقة عمل هذه الطريقة
من المهم أن نوضّح سبب نجاح ذلك، لأننا سنستخدم ذلك
معرفتها قريبًا. التمرير هو تحويل فعال، وهذا هو السبب في أنه يمكن
accelerated; فهي تشمل في الغالب تغيير الطبقات باستخدام وحدة معالجة الرسومات. في
التمرير النموذجي، وهو واحد بدون أي فكرة عن المنظور، والتمرير
بنسبة 1:1 عند مقارنة عنصر التمرير وعناصره الثانوية.
إذا تمريرت عنصرًا للأسفل بمقدار 300px
، يتم تحويل عناصره الثانوية إلى الأعلى.
بالمبلغ نفسه: 300px
.
ومع ذلك، فإن تطبيق قيمة المنظور على عنصر التمرير يعبثق حول
في هذه العملية؛ يغير المصفوفات التي تستند إليها تحويل التمرير.
والآن يمكن أن يؤدي تمرير 300 بكسل إلى تحريك الأطفال بمقدار 150 بكسل فقط، اعتمادًا على
القيمتان perspective
وtranslateZ
التي اخترتها. إذا كان العنصر يحتوي على
translateZ
بقيمة 0، سيتم الانتقال للأسفل عند الساعة 1:1 (كما كان من قبل)، ولكن يتم الانتقال إلى العنصر الثانوي
يتم دفعها في Z بعيدًا عن مصدر المنظور، وسيتم تمريرها
تقييم! النتيجة الصافية: حركة اختلاف المنظر. والأهم من ذلك، يتم التعامل مع هذا
من جهاز التمرير الداخلي في المتصفح تلقائيًا، أي
لا داعي للاستماع إلى أحداث "scroll
" أو تغيير background-position
.
الذباب في المره: Mobile Safari
هناك محاذير لكل تأثير، وواحد مهم للتحويلات يتعلق الحفاظ على التأثيرات ثلاثية الأبعاد للعناصر الثانوية. إذا كانت هناك عناصر في التسلسل الهرمي بين العنصر ذي المنظور والعناصر الثانوية المتباينة، المنظور الثلاثي الأبعاد "مسطح"، مما يعني فقدان التأثير.
<div class="container">
<div class="parallax-container">
<div class="parallax-child"></div>
</div>
</div>
في رمز HTML أعلاه، تُعتبر علامة .parallax-container
جديدة، وستبدأ بشكلٍ فعّال
لتسطيح القيمة perspective
وسنفقد تأثير اختلاف التباين. الحل،
في معظم الحالات، يكون الأمر واضحًا إلى حد ما: تضيف transform-style: preserve-3d
إلى العنصر، مما يتسبب في نشر أي تأثيرات ثلاثية الأبعاد (مثل منظورنا
) التي تم تطبيقها على مستوى الشجرة.
.parallax-container {
transform-style: preserve-3d;
}
في حالة Mobile Safari، تكون الأمور أكثر تعقيدًا.
يعمل تطبيق overflow-y: scroll
على عنصر الحاوية من الناحية الفنية، ولكن في
تكلفة التنقل عبر عنصر التمرير. الحل هو إضافة
-webkit-overflow-scrolling: touch
، لكنها أيضًا ستعمل على تسطيح perspective
ولن نحقق أي تناقض.
ومن منظور التحسين التدريجي، لا يُعتبر ذلك على الأرجح المشكلة. إذا لم نكن قادرين على الاختلاف في كل موقف، فسيظل تطبيقنا يعمل، ولكنه سيكون من اللطيف إيجاد حل بديل.
position: sticky
لإنقاذه.
وهناك، في الواقع، بعض المساعدة في شكل position: sticky
، والتي تهدف إلى
السماح للعناصر بـ "اللصق" إلى أعلى إطار العرض أو إلى عنصر رئيسي معيّن
أثناء الانتقال للأعلى أو للأسفل. المواصفات، مثل معظمها، كبيرة إلى حد ما، لكنها تحتوي على
جوهرة صغيرة مفيدة داخل:
قد لا يبدو هذا وكأنه يعني الكثير للوهلة الأولى، ولكنه النقطة الرئيسية في هذه الجملة عندما تشير إلى كيف بالضبط أن تماسك العنصر المحسوبة: "يتم حساب الإزاحة بالإشارة إلى أقرب أصل باستخدام مربّع تمرير" بمعنى آخر، إنّ المسافة التي يجب قطعها لتحريك العنصر الثابت (ليظهر مرفقًا بعنصر آخر أو إطار العرض) يتم احتسابها قبل تطبيق أي عمليات تحويل أخرى، وليس بعد. يعني ذلك يشبه إلى حد كبير مثال التمرير السابق، إذا تم حساب الإزاحة عند عرض 300 بكسل، تتوفر فرصة جديدة لاستخدام وجهات النظر (أو أي تحويل آخر) لمعالجة قيمة الإزاحة البالغة 300 بكسل قبل تطبيقها على أيٍ عناصر.
ومن خلال تطبيق position: -webkit-sticky
على العنصر المتباين، يمكننا
"عكس" بفعالية تأثير الاستقامة لـ -webkit-overflow-scrolling:
touch
. وهذا يضمن أن يشير العنصر المتباين إلى أقرب
كيان أصل مع مربّع تمرير، وهو .container
في هذه الحالة. بعد ذلك، يُرجى اتّباع الخطوات التالية:
مثلما الحال سابقًا، تطبّق .parallax-container
القيمة perspective
،
مما يغير إزاحة التمرير المحسوبة وينشئ تأثير اختلاف المنظر.
<div class="container">
<div class="parallax-container">
<div class="parallax-child"></div>
</div>
</div>
.container {
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
.parallax-container {
perspective: 1px;
}
.parallax-child {
position: -webkit-sticky;
top: 0px;
transform: translate(-2px) scale(3);
}
سيؤدي ذلك إلى استعادة تأثير اختلاف المنظر في Mobile Safari، وهو ما يمثل خبرًا ممتازًا. دَوْرَة
تنبيهات بشأن تحديد مواضع الإعلانات الثابتة
ولكن هناك فرق هنا، ولكن: position: sticky
تغير
ميكانيكا اختلاف المنظر يحاول تحديد الموضع اللاصق تثبيت العنصر
حاوية التمرير، في حين أن الإصدار غير الثابت لا يفعل ذلك. وهذا يعني أن
اختلاف المنظر مع اللاصقة ينتهي بها الأمر عكس ذلك الذي ليس له:
- مع
position: sticky
، كلما اقترب العنصر من z=0 قلّ - بدون استخدام
position: sticky
، كلما اقترب العنصر من z=0 زاد المزيد يتحرك.
إذا كان كل هذا يبدو مُجردًا بعض الشيء، يمكنك إلقاء نظرة على هذا العرض التوضيحي من تأليف "روبرت فلاك"، توضح كيف تتصرف العناصر بشكل مختلف مع الألوان الثابتة وبدون للمكانة في السوق. لمعرفة الفرق، يجب استخدام Chrome Canary (وهو الإصدار 56 من Chrome) في وقت الكتابة) أو Safari.
عرض توضيحي من إعداد "روبرت فلاك"
تؤثّر السمة position: sticky
في التمرير في اختلاف التباين.
أخطاء متنوعة وأساليب بديلة
وكما هو الحال مع أي شيء، لا تزال هناك نتوءات ونتوءات يجب ناعم عبر:
- الدعم الثابت غير ثابت. لا يزال الدعم ساريًا في
يفتقر Chrome وEdge إلى الدعم تمامًا، بينما يحتوي Firefox على أخطاء في الرسم عند دمج التثبيت مع تغييرات المنظور. في مثل هذه
فإن الأمر يستحق إضافة رمز صغير لإضافة
position: sticky
فقط (-webkit-
إصدار سابق) عند الحاجة، وهو لمتصفّح Mobile Safari فقط. - التأثير ليس "عادلاً" في Edge. تحاول Edge التعامل مع التمرير عند على مستوى نظام التشغيل، وهو أمر جيد عمومًا، ولكنه في هذه الحالة يمنعه من اكتشاف تغيرات المنظور أثناء التمرير. لحلّ هذه المشكلة، يمكنك إضافة عنصر موضع ثابت، حيث يبدو أنّ هذا يؤدي إلى تبديل Edge إلى طريقة تمرير خارج نظام التشغيل ويضمن أن يأخذ في الحسبان تغيرات المنظور.
- "أصبح محتوى الصفحة ضخمًا جدًا". تراعي العديد من المتصفحات المقياس
عند تحديد حجم محتوى الصفحة، ولكن للأسف، لا يستطيع Chrome وSafari
لا تأخذ وجهة نظرك في الاعتبار. إذًا،
إذا كان هناك - على سبيل المثال - مقياس بثلاث مرات تم تطبيقه على عنصر، فيمكنك
نرى أشرطة التمرير وما شابه ذلك، حتى إذا كان العنصر بعد 1x
تم تطبيق التصنيف "
perspective
". يمكن التغلب على هذه المشكلة عن طريق تغيير حجم العناصر من الزاوية السفلية اليسرى (باستخدامtransform-origin: bottom right
)، لأنّها تؤدي إلى نمو العناصر كبيرة الحجم إلى "المنطقة السلبية" (عادةً ما يكون الجزء العلوي الأيسر) من المنطقة القابلة للتمرير قابل للتمرير لا تسمح لك المناطق بمشاهدة المحتوى في المنطقة السلبية أو الانتقال إليه مطلقًا.
الخاتمة
المنظر هو تأثير ممتع عند استخدامه بعناية. كما ترون، من الممكن لتنفيذ ذلك بطريقة أداء جيدة ومستندة إلى التمرير والتنقّل بين المتصفحات. ونظرًا لأنها تتطلب القليل من التقلب الرياضي، ومقدار قليل من في النص النموذجي للحصول على التأثير المطلوب، أنشأنا مكتبة مساعدة صغيرة والنموذج الذي يمكنك العثور عليه في مستودع GitHub لنماذج عناصر واجهة المستخدم.
استمتع باللعب وأخبرنا بمدى تطورك.