-
المساهمات
164 -
تاريخ الانضمام
-
تاريخ آخر زيارة
نوع المحتوى
ريادة الأعمال
البرمجة
التصميم
DevOps
التسويق والمبيعات
العمل الحر
البرامج والتطبيقات
آخر التحديثات
قصص نجاح
أسئلة وأجوبة
كتب
دورات
كل منشورات العضو ابراهيم الخضور
-
الصندوق المرن Flexbox هو أسلوب تخطيط وحيد الاتجاه لترتيب العناصر في صفحة الويب سواء على سطر واحد أو ضمن عمود واحد. إذ تتمتد العناصر لتشغل مساحة أوسع، أو تتقلص لتتلائم مع مساحة أقل. سنتطرق في هذا المقال إلى جميع الأساسيات التي تغطي هذا المفهوم. عليك قبل البدء في قراءة هذا المقال أن: تطلع على أساسيات HTML كما شرحناها في سلسلة مقالات مدخل إلى HTML. تفهم أساسيات عمل CSS. لماذا نستخدم الصندوق المرن؟ بقيت التخطيطات المعتمدة على خاصيات CSS المتعلقة بتعويم العناصر floats وبتوضعها positioning ولفترة طويلة أكثر التخطيطات موثوقية عبر مختلف المتصفحات، وقد نجح هذا الأمر لكن مع وجود شيء من المحدودية في التنفيذ وشيء من الإحباط أحيانًا. فتخطيطات بسيطة كالتي سنذكرها ستكون إما صعبة التنفيذ أو مستحيلة باستخدام تلك الأدوات وبأسلوب مرن وملائم: توسيط كتلة من المحتوى عموديًا ضمن العنصر الأب. التوزيع المتساوي لاتساع العنصر الأب بين مختلف العناصر الأبناء ضمن حاوية بغض النظر عن مقدار المساحة المتوفرة. ضبط جميع الأعمدة في التخطيط متعدد الأعمدة على نفس الارتفاع إن ضمت كميات مختلفة من المحتوى. وكما سنرى، يساعدنا تخطيط الصندوق المرن في تنفيذ الكثير من المهام بسهولة أكبر، وإليك التفاصيل. مثال تمهيدي بسيط سنمر في هذا المقال بسلسلة من التمارين كي نفهم آلية عمل الصندوق المرن. عليك بداية أن تنسخ ملف التمرين من جيت-هاب إلى جهازك، ثم حمّله ضمن متصفح حديث (كروم أو فايرفوكس) والق نظرة على الشيفرة باستخدام محرر الشيفرة الذي تستخدمه. بإمكان أيضًا الاطلاع على طريقة عمله مباشرة على جيت-هاب. ستلاحظ وجود ترويسة <header> تضم عنوانًا من المستوى الأول، وكذلك العنصر <section> الذي يضم ثلاث عناصر <article>. نستخدم هذه الشيفرة في بناء تخطيط معياري مكون من ثلاث أعمدة. تحديد العناصر التي ينبغي ترتيبها كصناديق مرنة علينا كبداية اختيار العناصر التي سترتب كصناديق مرنة، ولفعل ذلك ضبطنا الخاصية display للعنصر الأب للعناصر التي تريدها أن تتحول لصناديق مرنة (وهي في حالتنا العناصر <article>) على القيمة flex. وبالطبع فإن العنصر الأب هو <section>. section { display: flex; } هكذا يصبح العنصر حاوية مرنة وتصبح العناصر الأبناء عناصر مرنة. وستكون النتيجة شيئًا من هذا القبيل: إذًا، منحنا هذا التصريح بمفرده ما نريد، وهذا أمر رائع! إذ عُرض المحتوى ضمن ثلاث أعمدة لها الاتساع ذاته والارتفاع ذاته. والسبب في ذلك أن أن القيمة الافتراضية للعناصر المرنة (العناصر الأبناء ضمن الحاوية المرنة) تحل هذا النوع من المسائل مباشرة. دعونا نعيد ما حدث حتى يكون كل شيء واضحًا. يعمل العنصر الذي ضبطنا قيمة الخاصية display له على flex كعنصر كتلي من ناحية الطريقة التي يتفاعل فيها مع بقية أجزاء الصفحة، لكن أبناءه قد رُتِّبت كعناصر مرنة. وسنشرح في القسم التالي بتفاصيل أكبر ما يعنيه هذا الكلام. لا حظ أيضًا إمكانية استخدام القاعدة ;display: inline-flex إن أردت توضيع أبناء عنصر معين كعناصر مرنة لكن سيسلك هذا العنصر سلوك العناصر السطرية. نموذج الصندوق المرن عندما تتوضع العناصر بصفتها عناصر مرنة فإنها تتوضع وفق محورين: المحور الأساسي main axis: وله الاتجاه الذي تتوضع وفقه العناصر المرنة (أي على شكل سطر عبر الصفحة أو عمود يتجه لأسفل الصفحة) وتُدعى بداية هذا المحور البداية الأساسية main start وتُدعى نهايته بالنهاية الأساسية main end. المحور القاطع cross axis: هو المحور العمودي على اتجاه توضع العناصر المرنة وله بداية القاطع cross start ونهاية القاطع cross end. يُدعى العنصر الذي تُطبق عليه القاعدة display: flex (العنصر <section> في مثالنا) بالحاوية المرنة flex container. تُدعى العناصر الموجودة داخل الحاوية المرنة بالعناصر المرنة (العناصر <article> في مثالنا). تذكر هذه المصطلحات دائمًا، وعد إليها إن اختلط عليك الأمر في الأقسام القادمة. أعمدة وأسطر يقدم مخطط الصندوق المرن خاصية تُدعى flex-direction تحدد اتجاه المحور الأساسي (الاتجاه التي تُترتب وفقه عناصر الصندوق المرن). تأخذ هذه الخاصية القيمة row افتراضيًا والتي ترتب العناصر في صف باتجاه انسياب اللغة الافتراضية للمتصفح (من اليمين إلى اليسار في العربية و العكس في الإنجليزية). حاول أن تضيف التصريح التالي لقاعدة التنسيق الخاصة بالعنصر <section>: flex-direction: column; سترى أن هذه القاعة ستعيد العناصر إلى تخطيط العمود الواحد كما كان تقريبًا قبل إضافة أية تنسيقات. احذف هذا التصريح من شيفرة مثالنا قبل المتابعة. ملاحظة: بإمكانك إيضًا ترتيب العناصر المرنة عكسيًا باستخدام القيمتين row-reverse و column-reverse. التفاف العناصر من أحد المشاكل التي تظهر عند استخدام تخطيط ثابت الاتساع أو الإرتفاع هو طفحان العناصر في مرحلة ما خارج الحاوية مما يدمر التخطيط. لنلق نظرة على المثال wrap0.html الموجود على جيت-هاب (انسخ هذا المثال على جهازك إن كنت ترغب في تطبيق الأكواد الواردة في هذا المقال) لاحظ هنا كيف خرجت الأعمدة الأبناء خارج الحاوية، ولحل هذه المشكلة يمكن أن نستخدم التصريح التالي ضمن قاعدة تنسيق الكتلة الحاوية <section>: flex-wrap: wrap; أضف أيضًا التصريح التالي إلى قاعدة تنسيق العناصر <article>: flex: 200px; حاول استعراض الشيفرة الآن في المتصفح وسترى أن التخطيط قد تحسّن كثيرًا: لدينا الآن عدة أسطر يضم كلًا منها عدة عناصر أبناء مرنة تشغل تمامًا المساحة المتاحة للسطر، وعند حدوث طفحان يُنقل العنصر إلى السطر التالي. واستخدم التصريح flex: 200px في تنسيق العناصر <article> للدلالة إلى أن اتساع كل عنصر يجب أن يكون على الأقل 200 بكسل، وسنناقش هذه الخاصية بالتفصيل لاحقًا. يمكن أن نلاحظ أيضًا أن آخر العناصر الأبناء في السطر الأخير أكثر اتساعًا كي تشغل مساحة السطر بأكمله. هناك الكثير لنفعله أيضًا! حاول أن تغيّر قيمة الخاصية flex-direction إلى row-reverse وسترى أن تخطيط الأسطر المتعددة بقي كما هو لكن العناصر قد رتّبت بشكل معكوس ابتداءًا من الزاوية الأخرى للمتصفح. الخاصية المختصرة flex-flow تجدر الملاحظة هنا أن الخاصيات المختصرة موجودة للخاصيات flex-direction و flex-wrap و flex-flow. إذ يمكنك مثلًا استبدال التصريح: flex-direction: row; flex-wrap: wrap; بالتصريح التالي: flex-flow: row wrap; التحديد المرن لأبعاد العناصر المرنة لنعد الآن إلى مثالنا الأول لنرى كيف يمكننا التحكم بحجم المساحة الفارغة التي يمكن أن يشغلها العنصر المرن بالنسبة إلى بقية العناصر المرنة. شغّل الملف flexbox0.html أو انسخ الملف flexbox1.html إلى جهازك ليكون نقطة الانطلاق إذا قررت تطبيق ما سنفعله. أضف بداية القاعدة التالية أسفل تصريحات CSS: article { flex: 1; } إن القيمة في التصريح السابق هي قيمة نسبية لا وحدة لها تشير إلى حجم الفراغ المتاح لكل عنصر مرن على امتداد المحور الأساسي موازنة مع غيره من العناصر المرنة. في حالتنا منحنا كل عنصر <article> نفس القيمة وهي 1 كي تأخذ جميع العناصر نفس الكمية من الفراغ الإضافي الذي قد يبقى (الذي لا يتسع لعنصر بأكمله) بعد أن تُحتسب قيم بعض الخاصيات مثل الهوامش والحشوات. تشترك جميع العناصر المرنة بهذه النسبة وحتى لو وضعنا القيمة 40000 بدل القيمة 1 فسيكون لها الأثر ذاته. أضف الآن القاعدة التالية تحت القاعدة السابقة: article:nth-of-type(3) { flex: 2; } عند النقر على زر التحديث في المتصفح، سترى أن العنصر <article> الثالث يشغل ضعفي مساحة العنصرين الباقيين. في هذه الحالة سيكون هناك أربع وحدات تناسبية إجمالًا موزعة على الشكل (4=1+1+2). سيشغل أو عنصرين مرنين ما مقداره وحدة من أصل أربعة أي 1/4 من المساحة المتاحة، وسيشغل العنصر الثالث الربعين الآخرين. بإمكانك أيضًا أن تخصص حدًا أدنى من الحجم لكل عنصر مرن. لترى ذلك، حاول تعديل قواعد تنسيق العنصر <article> كما يلي: article { flex: 1 200px; } article:nth-of-type(3) { flex: 2 200px; } تنص هذه القواعد على أن كل عنصر مرن سيعطى اتساعًا قدره 200 بكسل بداية من المساحة المتوفرة، وبعدها تتقاسم العناصر المساحة الباقية بنفس النسبة. جرّب أن تنقر على زر التحديث في المتصفح وسترى اختلافًا في طريقة تقاسم المساحة الفارغة. تتجلى القيمة الحقيقية لتخطيط الصندوق المرن من خلال مرونته وتجاوبه، فإن غيرّت أبعاد المتصفح أو أضفت عنصر <article> جديد سيبقى التخطيط جميلًا. الخاصية flex المختصرة موازنة بالخاصية المطوّلة يمكن استخدام الخاصية المختصرة flex لتحديد ثلاث قيم على الأكثر: القيمة النسبية التي ليس لها واحدة وقد ناقشناها في الأعلى. بالإمكان ضبط هذه القيمة بمفردها أيضًا من خلال الخاصية المطولة flex-grow. قيمة نسبية أخرى ليس لها واحدة تعبر عنها الخاصية المطوّلة flex-shrink وتظهر أهميتها عندما يحدث الطفحان في الحاوية المرنة. إذ تحدد هذه القيمة مقدار ما يتقلصه العنصر ليمنع الطفحان. لا تُعد هذه الميزة للصندوق المرن متقدمة ولن نغطيها لاحقًا. القيمة التي تحدد الحد الأدنى لاتساع العنصر المرن والتي ناقشناها سابقًا. بالإمكان أن نضبط هذه القيمة أيضًا باستخدام الخاصية المطوّلة flex-basis. لا ننصحك باستخدام الصيغ المطوّلة لخاصيات الصندوق المرن إلا في الحالة التي لا مفر من استخدامها (كأن تلغي قاعدة ما حُدِّدت قيمتها سابقًا). إذ سيزيد استخدام هذه الخاصيات من حجم الشيفرة المكتوبة، وقد تغدو مربكة أحيانًا. المحاذاة الأفقية والعمودية نستطيع أيضًا استخدام خاصيات الصندوق المرن لمحاذاة العناصر المرنة عبر المحور الأساسي أو القاطع. ولتوضيح ذلك، سنلقي نظرة على المثال flex-align0.html الموجود على جت-هاب (بإمكانك متابعته مباشرة) أيضًا)، وسنحاول تحويل محتواه إلى قائمة من الأزرار المرنة الأنيقة. لاحظ بداية وجود شريط قائمة أفقي يضم عدة أزرار محشورة بجوار بعضها ابتداءً من الزاوية اليمينية العليا. جهز نسخة عن هذا الملف على جهازك، ثم أضف الشيفرة التالية إلى أسفل شيفرة CSS: div { display: flex; align-items: center; justify-content: space-around; } انقر على زر "تحديث" في المتصفح وسترى أن الأزرار قد ضبطت لتبدو متمركزة في منتصف القائمة عموديًا وأفقيًا، وقد أنجزنا ذلك باستخدام الخاصيتين التاليتين: الخاصية align-items: وتتحكم بموضع العناصر المرنة على امتداد المحور القاطع: تأخذ هذه الخاصية القيمة stretch افتراضيًا وتوسّع العناصر المرنة لتشغل المساحة المتاحة للعنصر الأب وفق اتجاه المحور القاطع. فإن لم يكن للعنصر الأب ارتفاع محدد وفق اتجاه المحور القاطع، ستأخذ جميع العناصر الأبناء ارتفاع أطول العناصر المرنة. لهذا كان للأعمدة في مثالنا الأول نفس الارتفاع تلقائيًا. أما القيمة التي استخدمناها في الشيفرة السابقة، ستُبقي الأبعاد الأصلية للعناصر كما هي لكن ستجعلها تتمركز وفق اتجاه المحور القاطع. لهذا تجد الأزرار متمركزة عموديًا في مثالنا الحالي. يمكن للخاصية أن تأخذ قيمًا مثل flex-start و flex-end والتي تحاذي العناصر المرنة إلى بداية ونهاية المحور القاطع. بإمكانك إلغاء سلوك الخاصية align-items لعنصر مرن محدد بتطبيق الخاصية align-self عليه. إليك كيف يكون الأمر: button:first-child { align-self: flex-end; } جرب تلك القيم لضبط محاذاة العناصر لترى تأثيرها ثم احذف ما فعلته عندما تنتهي. الخاصية justify-content: وتتحكم بموضع العناصر المرنة على امتداد المحور الأساسي: تأخذ الخاصية القيمة flex-start افتراضيًا مما يجعل جميع العناصر مرتبة ابتداءً من بداية المحور الأساسي. يمكن أن تأخذ الخاصية القيمة flex-end فترتب حينها العناصر من ناحية النهاية. وترتب العناصر حول مركز الحاوية المرنة إن كانت قيمة هذه الخاصية center. استخدمنا في الشيفرة السابقة القيمة space-around والتي توزّع جميع العناصر المرنة بالتساوي على طول المحور الأساسي مع وجود بعض المساحة الفارغة في كلا الطرفين. هنالك قيمة أخرى للخاصية وهيspace-between وهي مشابهة جدًا للقيمة space-around إلا أنها لا تترك أية مسافات فارغة إضافية في البداية والنهاية. أهملت الخاصية justify-items في تخطيط الصندوق المرن ولن نشير إليها، لكننا ننصحك بتجريب القيم السابقة للخاصيتين المتعلقتين بمحاذاة العناصر المرنة قبل متابعة القراءة. ترتيب العناصر المرنة يمتلك تخطيط الصندوق المرن ميزة تغيير ترتيب العناصر المرنة ضمن التخطيط دون التأثير على الترتيب المصدري. وهذا أمر يستحيل إنجازه باستخدام أساليب التخطيط التقليدي. إن الشيفرة الموافقة لهذه الميزة بسيطة، حاول أن تضيف الشيفرة التالية إلى شيفرة مثال شريط الأزرار: button:first-child { order: 1; } انقر على زر التحديث في المتصفح وسترى أن الزر "Smile" قد انتقل إلى نهاية المحور الأساسي، وسنشرح قليلًا كيف حدث هذا: تأخذ الخاصية order القيمة 0 لجميع العناصر المرنة افتراضيًا. ستظهر جميع العناصر ذات القيمة الأعلى لهذه الخاصية في النهاية موازنة بالعناصر التي تحمل قيمة أقل. تحافظ العناصر التي تحمل نفسة القيمة للخاصية order على ترتيب الشيفرة المصدرية. فإن كان لدينا مثلًا أربعة عناصر تحمل القيم 0،1،1،2 على الترتيب سيكون ترتيب عرضها على الشاشة الرابع ثم الثاني والثالث ثم الأول. سيظهر العنصر الثالث بعد الثاني على الرغم من امتلاكهما نفس قيمة الخاصية order إلا أن الثاني جاء قبل الثالث في ترتيب الشيفرة المصدرية. يمكن للخاصية أن تأخذ قيمًا سالبة كي تعرض العناصر التي تحمل هذه القيم قبل العنصر الذي يحمل القيمة 0. يمكننا مثلًا عرض الزر "Blush" في مثالنا في بداية المحور الأساسي باستخدام قاعدة التنسيق التالية: button:last-child { order: -1; } صناديق مرنة متداخلة بإمكانك إنشاء بعض التخطيطات الجميلة والمعقدة باستخدام الصناديق المرنة. فمن الممكن جدًا أن أجعل عنصرًا مرنًا حاويةً مرنةً أيضًا وأن يكون بعض أبناءه أيضًا حاويات مرنة وهكذا. ألق نظرة الآن على المثال complex-flexbox.html على جت-هاب (بإمكانك متابعة التنفيذ المباشر له أيضًا). إن شيفرة HTML لهذا المثال بسيطة، إذ تحتوي الشيفرة على العنصر <section> وضمنه ثلاثة عناصر <article> يحوي آخرها ثلاث عناصر <div> ويضم أول العناصر <div> خمسة أزرار. section - article article article - div - button div button div button button button لنلق نظرة على الشيفرة المستخدمة لتخطيط الصفحة، وسنرى أن أول ما فعلناه هو ضبط العناصر الأبناء للعنصر <section> لتكون صناديق مرنة. section { display: flex; } ثم ضبطنا بعض القيم المرنة للعناصر. وانتبه جيدًا إلى القاعدة الثانية في شيفرة التنسيق والتي جعلت العناصر الأبناء للعنصر <article> الثالث عناصر مرنة أيضًا لكننا رتبناها على هيئة عمود. article { flex: 1 200px; } article:nth-of-type(3) { flex: 3 200px; display: flex; flex-flow: column; } نختار تاليًا أول العناصر <div> ونطبق عليه التنسيق ;flex: 1 100px كي نعطيه ارتفاعًا مقداره 100 بكسل كحد أدنى، ثم نرتب العناصر الأبناء له على شكل عناصر مرنة. سنختار أن تتوضع الأزرار ضمن سطر وتكون قابلة للالتفاف والانتقال إلى سطر آخر في حال الطفحان كما اخترنا أن نعطيها محاذاة إلى مركز العنصر الأب كما فعلنا مع مثال قائمة الأزرار سابقًا: article:nth-of-type(3) div:first-child { flex: 1 100px; display: flex; flex-flow: row wrap; align-items: center; justify-content: space-around; } حاولنا في الخطوة الأخيرة تحديد حجم الأزرار باستخدام القاعدة ;flex: 1 auto. ولهذه القاعدة تأثير مهم، فإن حاولت أن تغير حجم نافذة المتصفح، ستشغل الأزرار أوسع مساحة ممكنة من الحيز المتاح وتبقى في السطر ذاته ما لم يحدث طفحان لتنتقل عندها إلى سطر آخر. button { flex: 1 auto; margin: 5px; font-size: 18px; line-height: 1.5; } توافقية المتصفحات مع تخطيط الصندوق المرن تدعم معظم المتصفحات الحديثة تخطيط الصندوق المرن مثل فايرفوكس وكروم وأوبرا ومايكروسوفت إيدج وإكسبلورر 11 والنسخ الجديدة من نظامي التشغيل أندرويد وأي أو إس. لكن عليك أن تدرك أن البعض يستخدم متصفحات قديمة لا تدعم هذا التخطيط (أو تفعل لكن بأسلوب قديم حقًا). وطالما أنك لا تزال في مرحلة التعلم والتجريب، لا تكترث للأمر كثيرًا. فإن قررت أن تستخدم تخطيط الصندوق المرن في تصميم موقعك، لا بأس إذًا من اختبار شيفرتك وتجريب بعض الحلول حتى تبقى تجربة مستخدمي موقعك مقبولة بأكبر عدد ممكن من المتصفحات. ويبقى تخطيط الصندوق المرن مربكًا موازنة من بعض ميزات CSS. فإن لم يدعم المتصفح مثلًا الظل حول العنصر فلن تتأثر تجربة المستخدمين كثيرًا لكن إن لم يدعم تخطيط الصنوق المرن فسيكسر المتصفح التخطيط بأكمله ولن يستطيع الزائر استخدام الصفحة أصلًا. الخلاصة حاولنا في هذا المقال الإشارة إلى أساسيات الصندوق المرن، ونتمنى أن تكون المعلومات التي وصلتك مفيدة وتساعدك في خطواتك التالية في رحلة التعلم. ترجمة -وبتصرف- للمقال: Flexbox اقرأ أيضًا المقال السابق: الانسياب الاعتيادي Normal Flow لعناصر صفحة الويب مدخل إلى تخطيط صفحات الويب باستخدام CSS التحكم في تخطيط الصفحة وضبط محاذاة العناصر في CSS تحجيم الأشياء في CSS تعرف على أساسيات لغة CSS
-
سنشرح في هذا المقال التصميم الذي يميز محرك ألعاب جودو عن غيره، فكل محرك ألعاب مختلف عن اﻵخر وله تصمصم فريد يلبي احتياجات مختلفة، ويقود هذا اﻷمر إلى سياقات عمل مختلفة وطرق مختلفة في هيكلة اﻷلعاب. نساعدك في هذا المقال على فهم طريقة عمل محرك الألعاب جودو، فما نعرضه ليس قائمة بالميزات ولا مقارنة بين المحركات. ولكي تعرف ما يناسبك من محركات، لابد من اختبارها بنفسك وفهم تصميمها ومحدوديتها. التصميم كائني التوجه يتبنى محرك الألعاب جودو مفهوم التصميم كائني التوجه كأساس له من خلال نظام المشاهد المرن والتسلسل الهرمي للعقد. كما يحاول الابتعاد عن اﻷنماط البرمجية المعقدة كي يقدم طريقة واضحة ومباشرة لهيكلة ألعابك. من خلال استخدام محرك جودو، يمكنك بناء مشاهد متنوعة تكون بمثابة مكونات جاهزة لإعادة استخدامها داخل مشروعك. على سبيل المثال يمكنك إنشاء مشهد لأضواء وامضة BlinkingLight وآخر لمصابيح مكسورة BrokenLantern. يحتوي كل مشهد على خصائصه الخاصة، مثل طريقة تفاعل الضوء مع المشهد أو تغييره لونه، ويمكنك جمع هذه المشاهد في مشهد أكبر. فمثلاً، عند بناء مدينة مليئة بالمصابيح المكسورة، يمكن تغيير خصائص الأضواء الوامضة كاللون أو سرعة الوميض بشكل موحد في جميع المصابيح داخل المدينة. بذلك، يصبح لديك القدرة على التحكم في حالة المصابيح بشكل مركزي، فتعديل الضوء الوامض في مشهد واحد، سيعدل المصابيح المكسورة في كامل المدينة. هذه الطريقة في إدارة المشاهد وتغيير الحالات فعالة وتسهل تطوير ألعاب معقدة. وفوق كل ذلك يدعم جودو الوراثة وهو أحد المبادئ الأساسية في البرمجة كائنية التوجه oop، فقد يكون مشهد جودو سلاحًا أو شخصية أو غرضًا ما أو بابًا أو مستوى أو جزء من مستوى أو أي شيء آخر تريده. ويعمل المشهد عمل الصنف class في الشيفرة الصرفة، ما عدا أنك حر في تصميمه من خلال المحرر مستخدمًا الشيفرة فقط أو مزيجًا من الاثنين. تختلف المشاهد في جودو عن الكائنات الجاهزة prefab في محركات اﻷلعاب ثلاثية اﻷبعاد اﻷخرى مثل محرك Unity في إمكانية الوراثة عنها أو توسيعها. فقد تُنشئ ساحرًا بتوسعة مشهد الشخصية مثلًا. وعند تحديث الشخصية في المحرر ستتحدث معها شخصية الساحر أيضًا. سيمكنك ذلك من بناء مشروعك كي يتطابق التصميم مع هيكلية الشيفرة. وتجدر الملاحظة أن جودو يقدم أنواعًا مختلفة من الكائنات تدعى عقدًا Nodes، ولكل منها غاية محددة. والعقد أجزاء من شجرة وترث دائمًا من العقدة اﻷب وصولًا إلى الصنف الرئيسي Node. وعلى الرغم من وجود عقد في جودو مثل اﻷشكال المتصادمة التي تستخدمها فيزيائية العقدة اﻷب، تُعد معظم العقد مستقلة عن بعضها. وبعبارة أخرى، لا تعمل العقد كما تعمل المكونات components في محركات ألعاب أخرى. فالعقد Sprite2D و Node2D و CanvasItem و Node، تمتلك جميع الخاصيات والميزات للأصناف اﻵباء كالتحويلات أو القدرة على رسم أشكال محددة وتصييرها باستخدام معالج لوني shader محدد. حزم حصرية بالكامل يحاول محرك الألعاب جودو تزويد المستخدمين بأدوات خاصة تلبي معظم احتياجاتهم. إذ يمتلك المحرك فضاء عمل مخصص لكتابة السكربتات، ومحرر رسوميات، ومحرر خرائط، ومحرر معالج لوني، ومنقح، ومحلل أداء، باﻹضافة إلى قدرته على عرض التغييرات مباشرة على جهازك المحلي أو جهاز متصل عبر الشبكة. إن الغاية من ذلك كله تقديم حزمة متكاملة من اﻷدوات ﻹنشاء اﻷلعاب تحسين تجربة المستخدمين مثل Blender لتصميم النماذج ثلاثية الأبعاد، وبإمكانك بالطبع العمل مع برامج خارجية نظرًا لدعمه للإضافات plugin، والتي تستطيع أن تنشئها بنفسك أيضًا لتلبية احتياجات خاصة في المشروع. ويعود وجود لغة GDScript الخاصة بجودو إلى هذا السبب جزئيًا إضافة إلى دعمه لغة #C. فلغة GDScript مصممة لتلائم حاجات المطورين والمصممين ومتكاملة تمامًا مع المحرّك والمحرر. وتتيح لك GDScript كتابة شيفرة اعتمادًا على صياغة اﻹزاحة أو المسافات البادئة indentation، وتتعرف على اﻷنواع، وتزودك بميزة اﻹكمال التلقائي. وتُعد هذه اللغة من لغات برمجة الألعاب وتوفر شيفرة سهلة ومفهومة وتضم أنواعًا مخصصة مثل Vectors و Colors. ومع GDExtension يمكنك كتابة شيفرة عالية اﻷداء باستخدام لغات مصرّفة مثل C و ++C و Rust وبايثون (باستخدام Cython) دون إعادة تصريف المحرّك. ملاحظة: لا يقدم فضاء العمل ثلاثي الأبعاد نفس عدد الميزات التي يقدمها ثنائي اﻷبعاد، ويحتاج إلى برامج خارجية أو إضافات لإنشاء التضاريس، وتحريك شخصيات الألعاب المعقدة وهكذا. مع ذلك، يزودك جودو بواجهة برمجية متكاملة لتوسعة وظائف المحرر باستخدام شيفرة اللعبة. محرك مفتوح المصدر يقدم جودو قاعدة برمجية مفتوحة المصدر بالكامل وفق ترخيص MIT. ويعني ذلك أن كل التقنيات التي تأتي معه هي مفتوحة المصدر أيضًا. وقد طوّرت معظم أجزاء المحرك من الصفر من قبل مساهمين. ويمكن لأي شخص استخدام اﻹضافات المناسبة لمشروعه ولا يعني ذلك أن تشحن هذه اﻹضافات مع المحرك. من اﻷمثلة عليها نجد Google AdMob أو FMOD. وتعني القاعدة البرمجية مفتوحة المصدر من ناحية أخرى أن بإمكانك التعلم من محرك الالعاب وتوسيعه كما تشاء، وتستطيع تنقيح اﻷلعاب بسهولة، إذ يطبع جودو رسائل الخطأ من خلال متتبع المكدس stack tracer. المحرك مُطوَّر من مجتمعه الخاص يُطوّر محرك الألعاب جودو من قبل مجتمعه الخاص، فهو منهم ولهم ولجميع مطوري اﻷلعاب، وحاجات ونقاشات المستخدمين هو اﻷساس الذي يقود تطوير نواته. وتركّز الميزات الجديدة التي يقدمها مطورو النواة على ما يقدم الفائدة لمعظم مستخدميه، والقلة فقط من مطوري النواة يعملون رسميًا بدوام كامل. لكن المشروع يضم أكثر من 600 مساهم حتى لحظة كتابة هذه المقالة. فالمبرمجون المساهمون يعملون على تطوير الميزات التي يحتاجونها لأنفسهم لهذا سترى تحسينات من جميع النواحي عند كل إصدار رئيسي للمحرك. محرر جودو هو في الواقع لعبة جودو محرر جودو هو الأداة التي تستخدمها لبناء ألعابك، وهو يعمل مباشرة على نفس المحرك الذي يشغل اللعبة، وبالتالي عندما تكتب الشيفرة أو تصمم المشاهد، فستتمكن من اختبارها فورًا داخل المحرر أي بإمكانك استخدام نفس الشيفرة في مشاهد ألعابك أو بناء إضافات وتوسيع المحرر ويعطي ذلك مصداقية ومرونة لواجهة المستخدم. فعندما تستخدم التعليمة tool@ ستتمكن من تشغيل شيفرة اللعبة ضمن المحرر. محرر RPG in a Box هو محرر صمم باستخدام جودو 2 ويستخدم واجهة جودو الرسومية لمنظومته البرمجية المبنية على أساس العقد ضع التعليمة tool@ في بداية ملف GDScript وستعمل الشيفرة ضمن المحرر. سيساعدك ذلك على إدراج وتصدير الإضافات وإنشاء إضافة مخصصة مثل محررات مخصصة للمراحل أو إنشاء سكربتات لها نفس العقد وترتبط بنفس الواجهة البرمجية التي تستخدمها في مشروعك. ملاحظة: كُتب محرر جودو بالكامل باستخدام لغة ++C وصُرّف إلى الصيغة الثنائية. ويعني ذلك أنه من غير الممكن إدراجه كمشروع نمطي على شكل ملف project.godot. يوفر جودو محركين ثنائي الأبعاد وثلاثي الأبعاد يوفّر جودو محركين مخصصين ثنائي وثلاثي البعد. وكنتيجة لذلك ستكون وحدة القياس اﻷساسية للمشهد ثنائي البعد هي البكسل. وعلى الرغم من أن المحركين منفصلين، فيمكنك تصيير المشهد ثنائي البعد في المحرك ثلاثي البعد والعكس صحيح، كما يمكنك كذلك تضمين الشخصيات والواجهات ثنائية البعد في العالم ثلاثي اﻷبعاد. الخلاصة بهذا تكون قد وصلت لنهاية مقال اليوم الذي ألقينا فيه نظرة عامة عن تصميم محرك الألعاب مفتوح المصدر جودو Godot، ووضحنا أسلوب التصميم المتبع في هذا المحرك وكيفية استخدامه في تطوير الألعاب، وأهم الميزات التي يدعمها مثل التصميم كائني التوجه والوراثة، بالإضافة إلى الأدوات والميزات الحصرية المتوفرة في المحرك، ودعمه لتصميم الألعاب ثنائية وثلاثية الأبعاد مع إمكانية تفاعلهما معًا في تطوير الألعاب، وسلطنا الضوء على الجهود المبذولة من قبل مجتمع مطوري جودو في تطوير المحرك وتحسينه باستمرار لضمان أفضل تجربة استخدام. ترجمة -وبتصرف- لمقال: Godot's design philosophy اقرأ أيضًا تعلم الميزات الجديدة في محرك الألعاب جودو وطرح الأسئلة حوله إعداد محرك الألعاب جودو Godot للعمل مع قاعدة البيانات SQLite تعرف على أهمية صناعة الألعاب الإلكترونية أشهر أنواع الألعاب الإلكترونية
-
بعد أن اطلعنا في مقال سابق على مفهوم جافا سكريبت وما يمكنها فعله، سنتابع في مقالنا هذا فكرة إنشاء تطبيق بسيط باستخدام جافا سكربت من خلال جولة إرشادية عملية نبني من خلالها تطبيق "خمّن الرقم Guess the number" خطوةً بخطوة. عليك قبل البدء بقراءة هذا المقال أن تٌلّم بأساسيات العمل على الحاسوب وأساسيات HTML و CSS وكذلك فهم طبيعة جافا سكريبت. ولا بد أيضًا من اﻹشارة إلى ما يجب أن تتوقعه بعد قراءة هذا المقال، فلا تتوقع أن تتعلم جافا سكريبت أو حتى أن تفهم كل الشيفرة التي نطلب منك كتابتها، بل كل ما نريده هو إعطاؤك فكرة عن طريقة عمل ميزات جافا سكريبت مع بعضها، وكيف تبدو كتابة شيفرة جافا سكريبت. سنعود في مقالات تالية إلى كل الميزات التي نستعرضها في هذا المقال بتفاصيل أكثر. لذا لا تقلق إن لم تفهم كل شيء مباشرةً. ملاحظة: إن الكثير من ميزات شيفرة جافا سكريبت هي نفسها تقريبًا في لغات البرمجة اﻷخرى مثل الدوال functions والحلقات loops وغيرها. فقد تبدو صياغة الشيفرة مختلفة لكن المفهوم يبقى ذاته. فكّر مثل مبرمج من أصعب اﻷمور التي تصادفك عند تعلم البرمجة هو طريقة تطبيق قواعد اللغة لحل مشاكل فعلية وليس تعلّم هذه القواعد. فعليك إذًا أن تتعلم كيف تفكّر مثل المبرمجين، ويتضمن ذلك الاطلاع على وصف ما يتطلّبه برنامجك ثم تقدير ميزات الشيفرة التي تستخدمها ﻹنجاز المطلوب وكيف ستربط بين هذه الميزات. يتطلب اﻷمر مزيجًا من العمل الجاد والخبرة بصياغة اللغة والتدريب، إضافة إلى لمسة من الإبداع. وكلًما كتبت شيفرة أكثر ستتمكن منها أكثر. لن نعدك بالطبع أن تكوّن دماغ مبرمج في خمس دقائق، لكن سنتيح لك فرص عديدة كي تمارس تفكير المبرمج لنلق نظرة إذًا على المثال الذي نبنيه في مقالنا ونراجع الغاية العامة من تقسيمه إلى مهام. تطبيق -خمّن الرقم Guess the number- نعرض في هذا التطبيق كيفية بناء لعبة بسيطة كما في المثال الحي التالي: حاول أن تجرّب اللعبة وتعتاد عليها قبل أن نتابع، ثم لنتخيل أن مديرك قد أعطاك الوصف الموجز التالي للعبة كي تبنيها: بعد الاطلاع على الموجز السابق، لا بد أولًا من تقسيم العملية إلى مهام أصغر قابلة للتنفيذ إستنادًا إلى عقلية المبرمج قدر اﻹمكان: توليد رقم عشوائي بين 1 و 100. تسجيل رقم المحاولة التي وصلها اللاعب ابتداءً من 1. إعطاء اللاعب طريقة ليسجًل العدد الذي يخمّنه. تسجيل العدد الذي خمّنه اللاعب وعرضه في مكان ما كي يرى محاولاته السابقة. التحقق من صحة التخمين. إن كان التخمين صحيحًا: عرض رسالة تهنئة. منع اللاعب من إدخال أية تخمينات أخرى (لأن ذلك يسيء إلى اللعبة). عرض آلية تتيح للاعب اللعب مجددًا. إن كان التخمين خاطئًا: إخبار اللاعب أن تخمينه خاطئ وإن كان التخمين قريبًا جدًا أو بعيدًا جدًا. السماح للاعب بإدخال تخمين جديد. زيادة عدّاد المحاولات بمقدار 1. إن كان التخمين خاطئًا وتجاوز اللاعب عدد المحاولات المتاحة: إبلاغ اللاعب بانتهاء اللعبة. منع اللاعب من إدخال أية تخمينات أخرى (لأن ذلك يسيء إلى اللعبة). عرض آلية تتيح للاعب اللعب مجددًا. التأكد عند إعادة اللعبة أن منطق اللعبة وواجهة المستخدم قد عادا إلى الوضع اﻷصلي، ثم العودة إلى الخطوة 1. سنحاول اﻵن التفكير بآلية لتحويل هذه الخطوات إلى شيفرة صحيحة ثم بناء اللعبة واكتشاف ميزات جافا سكريبت أثناء تقدم العمل. اﻹعدادات اﻷساسية لنبدأ العمل على كتابة الشيفرة البرمجية للعبة تخمين الأرقام والتي ستعمل كما موضح في الصورة التالية. تحتاج في البداية لتحضير نسخة محلية خاصة بك من الملف number-guessing-game-start.html كما تستيطع أن تختبره مباشرة ضمن المستودع المخصص له على جيت-هب. افتح الملف ضمن المتصفح وضمن المحرر النصي. سترى للوهلة الأولى ترويسة بسيطة وفقرة نصية توضح التعليمات ونموذج لإدخال التخمين، لكن التطبيق لن يعمل حاليًا. سنضع كل شيفرة اللعبة ضمن العنصر <script> في نهاية شيفرة HTML: <script> // Your JavaScript goes here </script> إضافة متغيرات لتخزين البيانات أضف بداية الأسطر التالية ضمن العنصر <script>: let randomNumber = Math.floor(Math.random() * 100) + 1; const guesses = document.querySelector(".guesses"); const lastResult = document.querySelector(".lastResult"); const lowOrHi = document.querySelector(".lowOrHi"); const guessSubmit = document.querySelector(".guessSubmit"); const guessField = document.querySelector(".guessField"); let guessCount = 1; let resetButton; يهيئ هذا القسم من الشيفرة المتغيرات والثوابت التي نحتاجها لتخزين البيانات اللازمة لبرنامجنا. تُعرّف المتغيرات variables مبدئيًا بأنها أسماء لقيم مثل اﻷعداد أو النصوص. ويمكنك إنشاء متغير باستخدام التعليمة let يليها اسم المتغير. وتُعرّف الثوابت constant بأنها أسماء لقيم أيضًا لكن لا يمكن تغيير هذه القيم بمجرد أن نهيئها. نستخدم في حالتنا الثوابت لتخزين مراجع إلى عناصر من واجهة المستخدم. وقد يتغير النص ضمن تلك العناصر لكن الثوابت تشير دائمًا إلى العنصر نفسه الذي ضُبطت عليه في البداية. يمكن إنشاء الثابت باستخدام التعليمة const يليها اسم الثابت. يمكن إسناد قيمة إلى الثابت أو المتغير باستخدام الإشارة (=) تليها القيمة التي تريد. في مثالنا: يُسند إلى المتغير اﻷول randomNumber عدد عشوائي بين 1 و 100 يُحسب من خلال خوارزمية رياضية. أنشئت الثوابت الثلاث اﻷولى لتخزين مراجع إلى المقاطع النصية الخاصة بالنتائج في شيفرة HTML وتستخدم ﻹدراج نصوص ضمن هذه الفقرات برمجيًا، ولاحظ أنها ضمن عنصر <div>والذي يُستخدم لاختيار المقاطع الثلاث لتصفيرها (إعادتها إلى وضعها اﻷصلي) لاحقًا عن إعادة اللعبة إلى وضعها اﻷصلي. <div class="resultParas"> <p class="guesses"></p> <p class="lastResult"></p> <p class="lowOrHi"></p> </div> يُخّزن الثابتان التاليان مرجع إلى عنصر اﻹدخال النصي في النموذج وإلى زر اﻹرسال وتُستخدمان للتحكم بإرسال العدد الذي يُخمنه اللاعب. <label for="guessField">Enter a guess: </label> <input type="number" id="guessField" class="guessField" /> <input type="submit" value="Submit guess" class="guessSubmit" /> يٌخزّن المتغيران اﻷخيران القيمة 1 لعدد محاولات اللعب (ويُستخدم لتتبع عدد المحاولات التي قام بها اللاعب) ومرجعًا إلى زر إعادة الضبط الذي لا يظهر حاليًا (لكنه سيظهر لاحقًا). ملاحظة: سنتعلم أكثر عن المتغيرات والثوابت لاحقًا في سلسلة المقالات هذه عن جافا سكريبت. الدوال أضف تاليًا الشيفرة التالية تحت الشيفرة السابقة: function checkGuess() { alert("I am a placeholder"); } الدوال هي كتل من الشيفرة يمكن استخدامها مجددًا، إذ يمكن كتابتها مرة واحدة وتنفيذها مرارًا وتكرارًا موفرين عناء كتابة الشيفرة من جديد، وهذا أمر غاية في اﻷهمية.وهنالك عدد من الطرق في تعريف الدوال لكننا سنركز الآن على نوع بسيط. نستخدم في مثالنا الكلمة المفتاحية function متبوعةً باسم الدالة وبعدها قوسين معقوصين{}. نضع الشيفرة التي تنفذها الدالة عند استدعائها داخل القوسين المعقوصين. وعندما نريد تنفيذ الشيفرة، تكتب اسم الدالة يليها قوسين () لنجرب ذلك اﻵن، احفظ التغييرات التي أجريتها على الملف وحدّث الصفحة ضمن المتصفح. انتقل بعد ذلك إلى (طرفية جافا سكريبت ضمن أدوات مطوري ويب ثم أدخل السطر التالي: checkGuess(); من المفترض أن ترى بعد الضغط على المفتاح Enter/Return رسالة تنبيه نصها I am a placeholder، ﻷننا عرفنا دالة في شيفرتنا تعيد هذه الرسالة كلما استدعيناها. ملاحظة: سنتعلم أكثر عن الدوال لاحقًا في سلسلة المقالات هذه. العوامل تسمح العوامل Operators في لغة جافا سكريبت بإجراء اختبارات وتنفيذ العمليات الرياضية وضم السلاسل النصية إلى بعضها وغيرها من اﻷشياء. فإن لم تكن قد فعلت ذلك مسبقًا، احفظ التغييرات على ملفك ثم أعد تحميل الصفحة في المتصفح وانتقل إلى طرفية جافا سكريبت في أدوات مطوري ويب. حاول أن تنفذ اﻷمثلة المذكورة في الجدول التالي، منتبهًا إلى نقل المثال حرفيًا كما هو ثم انقر Enter بعد كل عملية لترى نتيجتها: العامل اسمه مثال + الجمع 6 + 9 - الطرح 20 - 15 * الضرب 3 * 7 / القسمة 10 / 5 هنالك أيضًا بعض العوامل المختصرة تُدعى عوامل اﻹسناد المركّبة compound assignment operators، فإن أردت مثلًا إضافة عدد جديد إلى عدد موجود وإعادة النتيجة، إليك الطريقة: let number1 = 1; number1 += 2; وهذا مشابه لعمل الشيفرة: let number2 = 1; number2 = number2 + 2; وعند تنفيذ اختبارات نتيجتها (صحيح أو خاطئ) وذلك ضمن العبارات الشرطية (سنراها لاحقًا) نستخدم عوامل الموازنة comparison operators مثل: العامل الاسم مثال === مساواة تامة (هل يساويه تمامًا؟) 5===2+4 // خاطئ، chris===pop// خاطئ، 5===2+3 // صحيح، 2==='2' // خاطئ موازنة رقم بنص ==! لا مساواة تامة (هل هما غير متساويين؟) 5==!2+4 // صحيح، chris!==pop// صحيح، 5==! 2+3 // خاطئ، 2==!'2' // صحيح موازنة رقم بنص < أقل من 10>6 // صحيح، 10>20 //خاطئ > أكبر من 10<6 // خاطئ، 10<20 //صحيح السلاسل النصية تستخدم السلاسل النصية لتمثيل النصوص، وقد رأينا سابقًا متغير نصي في الشيفرة "I am a placeholder": function checkGuess() { alert("I am a placeholder"); } يمكن التصريح عن سلسلة نصية باستخدام إشارتي التنصيص المزدوجتين (" ") أو المفردتين (' ')، لكن ينبغي عليك استخدام أحد اﻷسلوبين من بداية السلسلة إلى نهايتها فلا يمكن أن تكتب مثلًا" "I am a placeholder'. باﻹمكان أيضًا تعريف السلسلة النصية بين علامتي اقتباس مائلتين (``) وتُدعى السلاسل المعرّفة بهذا الشكل بالقوالب المفسّرة template literals التي تحمل بعض الخاصيات المميزة وتحديدًا إمكانية وضع متغيرات أخرى أو تعابير برمجية ضمن السلسلة النصية لتتحول قيمها إلى جزء من النص: const name = "Mahalia"; const greeting = `Hello ${name}`; يمنحك هذا اﻷمر أسلوبًا لضم السلاسل النصية معًا. العبارات الشرطية بالعودة إلى الدالة ()ckeckGuess نجد أنه من المنطقي ألا تكون وظيفتها طباعة رسالة فقط، بل من المفترض أن تتحقق من صحة العدد الذي يخمّنه اللاعب وتعيد الجواب الملائم. لنستبدل اﻵن بالشيفرة التالية ما كان موجودًا ضمن الدالة ()ckeckGuess: function checkGuess() { const userGuess = Number(guessField.value); if (guessCount === 1) { guesses.textContent = "Previous guesses:"; } guesses.textContent = `${guesses.textContent} ${userGuess}`; if (userGuess === randomNumber) { lastResult.textContent = "Congratulations! You got it right!"; lastResult.style.backgroundColor = "green"; lowOrHi.textContent = ""; setGameOver(); } else if (guessCount === 10) { lastResult.textContent = "!!!GAME OVER!!!"; lowOrHi.textContent = ""; setGameOver(); } else { lastResult.textContent = "Wrong!"; lastResult.style.backgroundColor = "red"; if (userGuess < randomNumber) { lowOrHi.textContent = "Last guess was too low!"; } else if (userGuess > randomNumber) { lowOrHi.textContent = "Last guess was too high!"; } } guessCount++; guessField.value = ""; guessField.focus(); } ما وضعناه كمية كبيرة من الشيفرة بالفعل، لكن سنمر على كل قسم منها ونشرحه: يعرّف السطر اﻷول متغيرًا يُدعى userGuess وتُسند إليه القيمة التي أُدخلت ضمن المربع النصي في النموذج. نمرر بعد ذلك هذه القيمة إلى الدالة ()Number المدمجة في جافا سكريبت وذلك للتأكد أن هذه القيمة عدد بالفعل. وطالما أننا لن نغيّر هذا العدد فقد قررنا أن يكون ثابتًا const. نواجه بعد ذلك أول كتلة شرطية، وتُستخدم الكتل الشرطية لتنفيذ الشيفرة انتقائيًا إن تحقق شرط معين أو لم يتحقق. قد تبدو العبارة الشرطية شبيهة بالدالة لكنه ليست كذلك. تبدأ أبسط أشكال الكتل الشرطية بالكلمة المحجوزة if يليها بعض اﻷقواس ثم بعض اﻷقواس المعقوصة. يوضع الشرط أو الاختبار بين اﻷقواس العادية، فإن أعاد تنفيذ الشرط النتيجة true تُنفَّذ الشيفرة الموجودة ضمن اﻷقواس المعقوصة، وإن لم يكن اﻷمر كذلك، فلن تنفَّذ تلك الشيفرة وينتقل التنفيذ إلى القسم اﻵخر من الشيفرة. يختبر الشرط فيما لو كانت قيمة المتغيّر guessCount مساويًا للقيمة 1 (أي إذا كانت هذه المحاولة اﻷولى للاعب أم لا): guessCount === 1; إن تحقق ذلك، نجعل النص المحتوى ضمن الفقرة النصية guesses مساويًا Previous guesses، وإن لم يتحقق لا نفعل ذلك. نستخدم بعد ذلك قالبًا مفسّرًا لضم قيمة المتغّير userGuess إلى نهاية النص في الفقرة النصية guesses مع وجود مسافة فارغة بينهما. تُنفِّذ الشيفرة التالية عدة اختبارات: تتحق العبارة الشرطية اﻷولى {}()if إن كان التخمين الذي أدخله اللاعب مساويًا قيمة المتغيّر randomNumber الذي ضُبطت قيمته في بداية الشيفرة. فإن كان تخمين اللاعب صحيحًا، ربح اللعبة، لهذا نعرض رسالة تهنئة بلون أخضر ونمسح محتويات صندوق المعلومات الذي يشير إلى بعد أوقرب التخمين الخاطئ عن القيمة الصحيحة، ثم تُنفَّذ الدالة ()setGameOver التي سنناقشها لاحقًا. نربط بعد ذلك اختبارًا آخر في نهاية اﻷول من خلال البنية {}()else if والتي تتحقق إن كان الدور الذي لعبه اللاعب هو آخر دور له. فإن كان كذلك، يكرر ما فعلناه في الكتلة السابقة لكن مع رسالة تشير إلى نهاية اللعبة بدلًا من رسالة التهنئة. أما الكتلة اﻷخيرة التي نربطها بسابقتها فهي الكتلة {}else التي تضم شيفرة تُنفَّذ فقط إن فشل الاختباران في الكتلتين السابقتين (أي اللاعب لم يخمن العدد، ,ولم ينهي جميع محاولاته). نخبره في هذه الحالة أن تخمينه خاطئ ثم ننفذ اختبارًا آخر يتحقق إن كان تخمينه أكبر بكثير أو أقل بكثير من العدد الصحيح ثم نعرض رسالة أخرى بطريقة مناسبة ﻹخبار اللاعب بذلك. تحضر اﻷسطر الثلاث اﻷخيرة من الدالة (من 26 إلى 28) إرسال لتخمين التالي. إذ تضيف 1 إلى المتغير guessCount كي يستنفذ اللاعب دورًا جديدًا (العامل ++ هو عامل يزيد قيمة المتغير بمقدار 1). وتفرّغ قيمة المربع النصي في النموذج وتعطيه تركيز الدخل مجددًا، وبهذا يصبح اللاعب جاهزًا ﻹدخال التخمين التالي. اﻷحداث ما فعلنا حتى اﻵن هو إنجاز الدالة لكنها لن تفعل شيئًا لأننا لم نستدعها بعد. ومن المنطقي أن نستدعي هذه الدالة عند النقر على زر "Submit guess"، ولإنجاز ذلك، نحتاج إلى ما يُدعى حدثًا event. فاﻷحداث هي أشياء تحدث في المتصفح مثل نقر زر أو تحميل صفحة أو تشغيل فيديو وغيرها. ولكي ينفّذ المتصفح كتلة من الشيفرة كاستجابة لحدث ما نحتاج إلى مترصّد أحداث event listener يراقب أحداث معينة ويستدعي معالج أحداث event handler مناسب، والمعالج هو كتل من الشيفرة تعمل استجابةً لوقوع حدث في المتصفح. أضف السطر التالي تحت الدالة ()checkGuess: guessSubmit.addEventListener("click", checkGuess); أضفنا هنا مترصّد أحداث إلى الزر، وهو تابع يأخذ قيمتين (تُدعيان وسيطين arguments)، اﻷول هو نوع الحدث الذي نترصده فهو حدث (النقر click) وله قيمة نصية، والثاني هو الشيفرة التي تُنفَّذ عند وقوع الحدث وهي في حالتنا الدالة ()checkGuess. ولاحظ أنه لا حاجة لوضع القوسين عند كتابة الدالة كوسيط لمترصد الحدث ()addEventListener جرّب حفظ التغييرات على الملف ثم إعادة تحميل الصفحة في متصفحك وسيعمل التطبيق إلى حد معين. وما سيحدث أنه لو خمّنت العدد الصحيح أو أنهيت كل محاولاتك ستنهار اللعبة لأننا لم نعرّف بعد الدالة ()setGameOver التي من المفترض أن تُستدعى عند نهاية اللعبة. لهذا سنضيف الشيفرة الناقصة ﻹكمال اللعبة إنهاء جميع وظائف اللعبة لنضف اﻵن الدالة ()setGameOver إلى أسفل الشيفرة التي كتبتها حتى اﻵن ثم نشرح ما تفعله: function setGameOver() { guessField.disabled = true; guessSubmit.disabled = true; resetButton = document.createElement("button"); resetButton.textContent = "Start new game"; document.body.append(resetButton); resetButton.addEventListener("click", resetGame); } يعطّل أول سطرين عمل عنصر اﻹدخال النصي في النموذج وعمل الزر بضبط الخاصية disabled على القيمة trueلكل منهما. وهذا اﻷمر ضروري، لأن اللاعب سيتمكن من إرسال قيم تخمين أخرى رغم إنتهاء اللعبة، وسيجعل ذلك اللعبة فوضوية. توّلد اﻷسطر الثلاث التالية زرًا جديدًا <button>بعنوان "Start new game" ومن ثم تضيفه إلى شيفرة HTML الموجودة. يضبط السطر اﻷخير مترصّد أحداث للزر الجديد كي يترصد حدث النقر عليه ويستدعي الدالة ()resetGame. علينا اﻵن كتابة الشيفرة الخاصة بالدالة اﻷخيرة، لهذا ضع الشيفرة التالية في آخر ما كتبته: function resetGame() { guessCount = 1; const resetParas = document.querySelectorAll(".resultParas p"); for (const resetPara of resetParas) { resetPara.textContent = ""; } resetButton.parentNode.removeChild(resetButton); guessField.disabled = false; guessSubmit.disabled = false; guessField.value = ""; guessField.focus(); lastResult.style.backgroundColor = "white"; randomNumber = Math.floor(Math.random() * 100) + 1; } هذه الكتلة من الشيفرة طويلة نوعًا ما وتعيد كل شيء إلى وضعه اﻷصلي عند بداية اللعبة، وبالتالي يصبح اللاعب قادرًا على المتابعة من جديد، فهي: تعيد قيمة المتغير guessCount إلى 1. تفرّغ كل ما هو موجود في الفقرات النصية. فقد اخترنا جميع الفقرات النصية ضمن العنصر <div class="resultParas"></div> ثم تفقدنا من خلال حلقة كل فقرة وضبطنا الخاصية textContent لكل منها على' ' (سلسلة فارغة). تزيل زر إعادة الضبط من الشيفرة. تفعّل عناصر النموذج وتفرّغ الفقرات النصية وتعطي تركيز الدخل إلى مربع اﻹدخال النصي في النموذج كي يصبح جاهزًا لتلقي تخمين جديد من قبل اللاعب. تزيل لون خلفية الفقرة النصية lastResult. توّلد رقم عشوائي جديد كي لا تخمّن نفس الرقم العشوائي السابق. لقد اكتملت اللعبة اﻵن، تهانينا! وكل ما بقي لنا في هذا المقال هو الحديث عن بعض الميزات الهامة التي رأيناها في شيفرة اللعبة والتي ربما لم تدركها. الحلقات من أهم أجزاء الشيفرة التي كتبناها، والتي لا بد من الحديث عنها هي حلقة (for…of). فالحلقات هي مفاهيم برمجية غاية في اﻷهمية تتيح لك تنفيذ جزء من الشيفرة مرارًا وتكرارًا حتى يتحقق شرط معين. وكي نبدأ تتبع عمل الحلقات انتقل إلى طرفية جافا سكريبت في أدوات مطوري ويب، ثم أدخل الشيفرة التالية: const fruits = ["apples", "bananas", "cherries"]; for (const fruit of fruits) { console.log(fruit); } ما الذي حدث؟ لقد طبعت الكلمات 'apples', 'bananas', 'cherries' على الشاشة كنتيجة لتنفيذ الحلقة. لاحظ السطر التالي: ;['const fruits = ['apples', 'bananas', 'cherries يُنشئ هذا السطر مصفوفة (سنتعرف عليها لاحقًا في مقال لاحق) وهي مبدئيًا مجموعة من العناصر (سلاسل نصية في حالتنا). وتزوّدك الحلقة for...of بطريقة للحصول على كل عنصر من المصفوفة وتطبيق شيفرة جافا سكريبت عليه، فما يفعله السطر (for (const fruit of fruits هو التالي: الحصول على أول عناصر المصفوفة fruits. ضبط قيمة المتغيّر fruit لتكون قيمة العنصر اﻷول، ثم تنفيذ شيفرة جافا سكريبت الموجودة داخل القوسين {}. الحصول على العنصر التالي من المصفوفة fruits. في هذه الحالة، تطبع الشيفرة قيمة المتغيّر fruit على الشاشة. لنلق نظرة اﻵن على الحلقة الموجودة في لعبة "خمّن الرقم" وتحديدًا ضمن الدالة ()resetGame: const resetParas = document.querySelectorAll(".resultParas p"); for (const resetPara of resetParas) { resetPara.textContent = ""; } توّلد هذه الشيفرة متغيّرًا يضم قائمة بجميع الفقرات النصية الموجودة ضمن العنصر <div class="resultParas"> باستخدام التابع ()querySelectorAll ومن ثم يتفقد كل فقرة باستخدام حلقة ويزيل المحتوى النصي لها. وتجدر الملاحظة أن ثوابت مثل resetParas يمكن إزالة المحتوى النصي لها. مناقشة سريع لمفهوم الكائن Object في جافا سكريبت سنضيف تحسينًا أخيرًا إلى اللعبة قبل الدخول في هذا النقاش وهو سطر يجب وضعه تحت السطر ;let resetButton بالقرب من بداية شيفرة جافا سكريبت ثم نحفظ التغيرات: guessField.focus(); يستخدم هذا السطر التابع ()focus الذي يجعل مؤشر الدخل ضمن عنصر اﻹدخال النصي <input> حالما تُحمّّل الصفحة، وهكذا يصبح اللاعب جاهزًا لكتابة تخمينه مباشرة دون الحاجة إلى النقر داخل مربع اﻹدخال النصي. صحيح أنها إضافة صغيرة لكنها تحسن استخدام اللعبة وتمنح اللاعب فكرة عما سيفعله تاليًا حتى يبدأ اللعب. لنحلل ما يجري هنا بمزيد من التفصيل. إذ نتعامل غالبًا في جافا سكريبت مع الكائنات objects، والكائن هو مجموعة مترابطة من الوظائف المخزّنة في شيء واحد. بإمكانك بالطبع إنشاء كائنات خاصة بك، لكن اﻷمر متقدم قليلًا ولن نغطيه في مقالنا. أما ما نناقشه اﻵن باختصار فهي الكائنات المدمجة مع اللغة والتي يتضمنها متصفحك وتسمح لك بتنفيذ العديد من الأمور المفيدة. في هذه الحالة الخاصة، أنشأنا ثابتًا يخزّن مرجعًا إلى عنصر اﻹدخال النصي الموجود في نموذج HTML، وستجد السطر التالي ضمن التصريحات في بداية الشيفرة: const guessField = document.querySelector(".guessField"); وللحصول على هذا المرجع، استخدمنا التابع ()querySelector العائد إلى الكائن document. ويأخذ هذا التابع معلومة واحدة وهي محدد CSS الذي يُستخدم ﻹنتقاء العنصر الذي تريد إنشاء مرجع إليه. ولأن الثابت guessField يحتوي مرجعًا إلى العنصر <input>، فلديه القدرة اﻵن على الوصول إلى خصائصه (تُخزَّن المتغيرات أساسًا ضمن كائنات، ولا يمكن تغيير قيم بعضها) وتوابعه (وهي أساسًا دوال مخزّنة ضمنه). ومن أحد توابع عنصر اﻹدخال النصي نجد ()focus لهذا يمكننا استخدام السطر التالي لنقل تركيز الدخل إلى هذا العنصر: guessField.focus(); لا يمكن استخدام التابع ()focus على المتغيرات التي لا تضم مراجعًا إلى عناصر، فالثابت guesses مثلًا يضم مرجعًا إلى العنصر <p> والمتغير guessCount يضم عددًا. التعامل مع كائنات المتصفح لنعمل قليلًا مع بعض كائنات المتصفح: افتح ملف اللعبة أولًا ضمن المتصفح. افتح أدوات مطوري ويب في متصفحك (من زر القائمة>أدوات إضافية>أدوات مطوري ويب "في متصفح فايرفكس"). وتأكد من وصولك إلى طرفية جافا سكريبت. اكتب في الطرفية guessField وستعرض لك حينها أن هذا المتغيّر يضم العنصر <input>، وستلاحظ أيضًا أن الطرفية تعرض لك تلقائيًا أسماء جميع الكائنات الموجودة ضمن بيئة التنفيذ بما في ذلك متغيّراتك التي صرحت عنها. اكتب اﻵن مايلي: guessField.value = 2; تمثل الخاصية value القيمة الحالية المُدخلة إلى مربع النص، وسترى أن تنفيذ اﻷمر السابق يغيّر النص الموجود في مربع النص. جرّب أن تكتب guesses في الطرفية ثم اضغط المفتاح "Enter" وسترى أن هذا المتغير يتضمن العنصر <p>. جرّب كتابة اﻷمر التالي: guesses.value وسيعيد المتصفح القيمة undefined لأن الفقرة النصية لا تمتلك الخاصية value لتغيير النص داخل الفقرة النصية جرّب الأمر التالي: "?guesses.textContent="Where is my paragraph ولكي تجرب أشياء أخرى، اكتب اﻷسطر التالية: guesses.style.backgroundColor = "yellow"; guesses.style.fontSize = "200%"; guesses.style.padding = "10px"; guesses.style.boxShadow = "3px 3px 6px black"; لكل عنصر في الصفحة خاصية تُدعى style تضم بحد ذاتها كائنًا له خاصيات تتضمن جميع تنسيقات CSS السطرية المطبقة على العنصر. ويسمح لنا ذلك ضبط تنسيقات جديدة للعنصر ديناميكيًا من خلال جافا سكريبت. الخلاصة هكذا نكون قد بنينا تطبيقًا بسيط باستخدام جافا سكريبت، استمتع بتجريب ما فعلته أو جرّب النسخة الجاهزة من اللعبة على جيت-هاب كما يمكنك تحميل شيفرتها المصدرية أيضًا. ترجمة -وبتصرف- للمقال Afirst splash into JavaScript اقرأ أيضًا المقال السابق: تعرّف على لغة جافا سكريبت من منظور عام تعلم لغة جافا سكريبت من الصفر حتى الاحتراف أساسيات لغة جافاسكربت العبارات الشرطية واتخاذ القرار في جافا سكريبت مدخل إلى جافاسكريبت كائنية التوجه (Object-Oriented JavaScript)
-
نتابع في سلسلة المقالات هذه تغطية أساسيات جافاسكريبت وميزاتها، وتحديدًا أنواع البنى البرمجية التي نصادفها بكثرة في الشيفرة مثل العبارات الشرطية والحلقات والدوال والأحداث. وقد اطلعنا على هذه النقاط بشكل مبسط في سلسلة المقالات السابقة لكننا سنناقشها هنا بشيء من التفصيل. ننصحك قبل أن تبدأ العمل معنا في هذه السلسلة أن تطلع على: أساسيات علوم الحاسب. أساسيات HTML. أساسيات عمل CSS أساسيات جافاسكربت كما شرحناها في سلسلة المقالات السابقة. ملاحظة: إن كنت تستخدم حاسوب أو جهاز لوحي أو غيره من الأجهزة التي لا تمكّنك من إنشاء ملفاتك الخاصة، جرِّب الشيفرة التي ستجدها في الأمثلة من خلال برامج كتابة شيفرة على الإنترنت مثل Glitch أو JSBin. نتحدث في هذا المقال عن مفهوم العبارات الشرطية في جافاسكريبت إذ لا بد من اتخاذ قرارات عند كتابة الشيفرة في أية لغة برمجة ومن ثم تنفيذ بعض اﻹجراءات وفقًا لمعطيات الدخل المختلفة. فلو أخذنا لعبة ما كمثال، سنجد أن اللعبة تنتهي عندما يصبح عدد المحاولات المسموحة 0، ونأخذ كمثال آخر تطبيقًا للطقس يعرض صورة شروق الشمس في الصباح ويعرض صورة قمر ونجوم في ساعات الليل. هذا اﻷفعال تقرر من خلال استخدام البنى الشرطية وستكون موضوع هذا المقال. لماذا نستخدم عبارات شرطية في جافا سكريبت؟ يتخذ البشر (وكائنات حية أخرى) باستمرار قرارات تؤثر على حياتهم منها البسيطة (كان تقرر تناول قطعة أو قطعتي بسكويت) أو قرارات مصيرية (هل سأبقى في بلدي والعمل في مزرعة أبي أو أن أسافر لأكمل دراستي). وهذا ما تمثله العبارات الشرطية في جافا سكريبت تمامًا، سواء لاتخاذ قرار (أكل قطعة بسكويت واحدة مثلًا) أو معالجة نتائج هذه القرارات (إن اكل قطعة واحد فقد لا أشعر بالشبع، وإن أكلت أكثر فقد أشعر بالتخمة). العبارة الشرطية if...else نلقي نظرة في هذا القسم على العبارة الشرطية if...else، وهي أكثر العبارات الشرطية شيوعًا في جافا سكريبت. الصياغة القواعدية اﻷساسية للعبارة if...else تبدو هذه العبارة بالشكل التالي: if (condition) { /* code to run if condition is true */ } else { /* run some other code instead */ } لدينا هنا: الكلمة المحجوزة if ويليها قوسان عاديان(). شرط يجري اختباره يوضع ضمن القوسين ( مثل هل قيمة ما أكبر من قيمة أخرى أو هل لهذه القيمة وجود؟). وتستخدم الشرط في صياغته عادة عوامل مقارنة تعيد إحدى النتيجتين صحيح true أو خاطئ false. مجموعة من اﻷقواس المعقوصة {} وضمنها بعض الشيفرة، وقد تكون هذه الشيفرة أي شيء نريده وتُنفَّذ إن تحقق الشرط. الكلمة المحجوزة else. مجموعة أخرى من اﻷقواس المعقوصة، وضمنها بعض الشيفرة التي تُنفَّذ فقط إن لم يتحقق الشرط (كانت نتيجته false). يمكن بسهولة قراءة الشيفرة السابقة التي تقول "إذا أعاد الشرط النتيجة true نفّذ الشيفرة A وإلا نفّذ الشيفرة B. وتجدر الملاحظة أنه ليس من الضروري تضمين القسم else، فالشيفرة التالية صحيحة تمامًا: if (condition) { /* code to run if condition is true */ } /* run some other code */ لكن لا بد من الانتباه في هذه الحالة إلى أن العبارة الشرطية في هذه الحالة لن تتحكم بكتلة الشيفرة التي تليها والتي ستُنفَّذ أيًا كانت نتيجة الشرط. ولا نعني بذلك أن هذا أمر سيء لكن قد لا يتحقق ما تريده بالطريقة المتوقعة، لأنك غالبًا ما تريد تنفيذ أحد كتلتين من الشيفرة في الحالات الشرطية وليس كلاهما. وأخيرًا قد تجد العبارة الشرطية دون أقواس معقوصة مع أنه أمر غير مرغوب إطلاقًا: if (condition) /* code to run if condition is true */ else /* run some other code instead */ لا يوجد بالطبع خطأ في الصياغة السابقة لكن وجود اﻷقواس يجعل الشيفرة أكثر وضوحًا، فهي توضح حدود الشيفرة التي تتحكم بها العبارة الشرطية، كما أن استخدام أسطر متعددة مع إزاحة مناسبة يسهّل قراءة الشيفرة أكثر. مثال واقعي لفهم صياغة العبارة الشرطية بصورة أفضل، لنتخيل في هذا المثال الواقعي طفلًا يطلب مساعدة أمه أو أبيه في مهمة ما. فقد يقول الوالد أو الوالدة "إن ساعدتني في التسوق سأعطيك مصروفًا إضافيًا كي تشتري اللعبة التي تريد". يمكن أن نمثل اﻷمر في جافا سكريبت كالتالي: let shoppingDone = false; let childsAllowance; if (shoppingDone === true) { childsAllowance = 10; } else { childsAllowance = 5; } تجعل الشيفرة السابقة قيمة المتغير shoppingDone دائمًا false وهذا يعني أن ظن الطفل سيخيب. لكن بالطبع يمكننا اقتراح آلية على الوالدين لتصبح قيمة المتغير shoppingDone هي true إن ساعد الطفل الوالد في التسوق. التعليمة else if يزودنا المثال السابق بخيارين أو نتيجتين، لكن ماذا لو أردنا خيارات أكثر؟ توجد طريقة لربط عدة خيارات أو نتائج إلى العبارة if...else باستخدام التعليمة else if التي تضم كتلة إضافية من الشيفرة بين الكتلتين {}()if و {} else. لنلق نظرة على المثال التالي الذي يصلح أن يكون جزءًا من تطبيق للأحوال الجوية: <label for="weather">Select the weather type today: </label> <select id="weather"> <option value="">--Make a choice--</option> <option value="sunny">Sunny</option> <option value="rainy">Rainy</option> <option value="snowing">Snowing</option> <option value="overcast">Overcast</option> </select> <p></p> const select = document.querySelector("select"); const para = document.querySelector("p"); select.addEventListener("change", setWeather); function setWeather() { const choice = select.value; if (choice === "sunny") { para.textContent = "It is nice and sunny outside today. Wear shorts! Go to the beach, or the park, and get an ice cream."; } else if (choice === "rainy") { para.textContent = "Rain is falling outside; take a rain coat and an umbrella, and don't stay out for too long."; } else if (choice === "snowing") { para.textContent = "The snow is coming down — it is freezing! Best to stay in with a cup of hot chocolate, or go build a snowman."; } else if (choice === "overcast") { para.textContent = "It isn't raining, but the sky is grey and gloomy; it could turn any minute, so take a rain coat just in case."; } else { para.textContent = ""; } } See the Pen js-making decisions1 by Hsoub Academy (@HsoubAcademy) on CodePen. لدينا في الشيفرة السابقة العنصر <select> الذي يسمح لنا باختيار أحد التوقعات الجوية إضافة إلى فقرة نصية بسيطة. نخزّن في شيفرة جافا سكريبت مرجعًا إلى العنصر <select> وآخر للفقرة النصية <p> ونضيف مترصد أحداث إلى <select> كي يستدعي الدالة ()setWeather عندما تتغير قيمته (يتغير الخيار). عندما تُنفَّذ هذه الدالة، تُسند إلى المتغير choice قيمة العنصر <select> ثم نستخدم عبارة شرطية لعرض نصوص مختلفة ضمن الفقرة النصية وفقًا لقيمة المتغير choice. لاحظ كيف اختُبرت كل الشروط باستخدام الكتلة {}()else if ما عدا الشرط اﻷول الذي استخدمنا في اختباره {}()if. أما آخر الخيارات فقد وضع ضمن الكتلة {} else ليكون الملاذ اﻷخير الذي تُنفّذ الشيفرة التي يضمها إن فشلت جميع الاختبارات السابقة. إذ تفرغ شيفرة هذه الكتلة النص الموجود في الفقرة النصية إن لم يختار المستخدم أيًا من خيارات العنصر <select> أي أعاد استخدام الخيار "--Make a choice--" الذي يُعرض افتراضيًا. ملاحظة حول عوامل المقارنة تُستخدم عوامل المقارنة للتحقق من صحة شرط العبارة الشرطية. ولو عدنا إلى المقال الذي يشرح [العوامل الرياضية]() سنجد الخيارات التالية: === و !== لاختبار تطابق قيمة أو عدم تطابقها مع قيمة أخرى. < و > لاختبار ما إذا كانت قيمة ما أكبر تمامًا أو أصغر تمامًا من أخرى. <= و >= لاختبار ما إذا كانت قيمة ما أكبر أو تساوي أو أصغر أو تساوي قيمة أخرى. نريد هنا اﻹشارة بشكل خاص إلى اختبار القيم المنطقية (true و false) ونموذج شائع الاستخدام في ذلك. تُعيد أية قيمة ليست إحدى القيم التالية: false أو undefined أو null أو 0 أو NaN أو ('') القيمة true عندما تستخدم كشرط في عبارة شرطية، وبالتالي بإمكانك استخدام اسم لمتغير لاختبار وجوده أو إن كانت قيمته true. إليك مثالًا: let cheese = "Cheddar"; if (cheese) { console.log("Yay! Cheese available for making cheese on toast."); } else { console.log("No cheese on toast for you today."); } وبالعودة إلى مثالنا السابق حول الطفل الذي يؤدي عملًا لوالديه، يمكن إعادة كتابة المثال كالتالي: let shoppingDone = false; let childsAllowance; //'shoppingDone === true' لا نريد أن نقول صراحة أن if (shoppingDone) { childsAllowance = 10; } else { childsAllowance = 5; } كتل if..else متداخلة باﻹمكان وضع الكتلة if...else ضمن كتلة if...else أخرى. إذ يمكننا مثلًا كتابة تمرين التوقعات الجوية ليعرض مجموعة أخرى من الخيارات وفقًا لدرجة الحرارة أيضًا: if (choice === "sunny") { if (temperature < 86) { para.textContent = `It is ${temperature} degrees outside — nice and sunny. Let's go out to the beach, or the park, and get an ice cream.`; } else if (temperature >= 86) { para.textContent = `It is ${temperature} degrees outside — REALLY HOT! If you want to go outside, make sure to put some sunscreen on.`; } } ستعمل الشيفرة ككل بتناسق مع بعضها، لكن كل عبارة if...else تعمل بشكل منفصل تمامًا عن اﻷخرى. العوامل المنطقية: AND و OR و NOT إن أردت اختبار عدة شروط دون أن تكتب عبارات متداخلة، يمكنك استخدام العوامل المنطقية وهي: العامل AND &&: يسمح لك بربط عبارتين أو أكثر وينبغي أن تكون نتيجة جميع هذه العبارات true حتى تعيد العبارة الشرطية النتيجة true. العامل OR ||: يسمح لك بربط عبارتين أو أكثر وينبغي أن تكون نتيجة إحدى هذه العبارات true حتى تعيد العبارة الشرطية النتيجة true. وللتعرف على عمل AND، سنعيد كتابة المثال السابق باستخدامها: if (choice === "sunny" && temperature < 86) { para.textContent = `It is ${temperature} degrees outside — nice and sunny. Let's go out to the beach, or the park, and get an ice cream.`; } else if (choice === "sunny" && temperature >= 86) { para.textContent = `It is ${temperature} degrees outside — REALLY HOT! If you want to go outside, make sure to put some sunscreen on.`; } تُنفَّذ الكتلة البرمجية اﻷولى إن أعاد الاختبار (choice === 'sunny' and temperature < 86) النتيجة true. لنلق نظرة اﻵن على مثال سريع عن استخدام OR: if (iceCreamVanOutside || houseStatus === "on fire") { console.log("You should leave the house quickly."); } else { console.log("Probably should just stay in then."); } أما النوع اﻷخير من العوامل المنطقة NOT والذي يعبّر عنه بالمحرف !، فيُستخدم لنفي عبارة، إليك المثال السابق بوجود عامل النفي: if (!(iceCreamVanOutside || houseStatus === "on fire")) { console.log("Probably should just stay in then."); } else { console.log("You should leave the house quickly."); } فإن أعادت العبارة OR القيمة true سينفيها العامل NOT وستعيد العبارة الكاملة القيمة false. بإمكانك دمج العدد الذي تساء من العوامل المنطقية مع بعضها إن أردت ووفقًا للبنية البرمجية التي تريدها. إليك مثالًا تُنفَّذ فيه شيفرة الكتلة إذا أعادت كلتا عبارتي OR القيمة true أي عندما تعيد العبارة الكلية AND القيمة true. if ((x === 5 || y > 3 || z <= 10) && (loggedIn || userName === "Steve")) { // run the code } من اﻷخطاء الشائعة المرتكبة عند استخدام العامل OR في العبارات الشرطية هو كتابة المتغير الذي تريد التحقق من حالته، ثم كتابة قائمة من القيم التي تريد موازنتها بالمتغير يفصل بينها العامل OR (||) كما في المثال التالي: // OR استخدام خاطئ للعامل if (x === 5 || 7 || 10 || 20) { // run my code } في هذه الحالة ستكون نتيجة الشرط داخل ()if صحيحة دائمًا لأن الرقم 7 أو أي عدد غير معدوم سيعطي النتيجة true ويُفهم اﻷمر على النحو " إذا كان x مساويًا 5 أو 7 ستكون النتيجة true" وهذا أمر محقق دائمًا (كون x متغير غير محدد القيمة). لكنك لا تريد هذه النتيجة منطقيًا، وعليك تصحيح الكود السابق على النحو التالي: if (x === 5 || x === 7 || x === 10 || x === 20) { // run my code } عبارة الاختيار المتعدد switch تؤدي عبارة if واجبها تمامًا في اختبار الشروط، لكن لا يخلو اﻷمر من بعض السلبيات. فهي أسلوب جيد عندما تكون أمام خيارات محدودة يتضمن كل منها كمية معقولة من الشيفرة، أو عندما يكون الشرط مركبًا ويضم عدة عوامل موازنة منطقية. لكن في الحالات التي تريد فيا إسناد قيمة إلى متغير أو طباعة عبارة محددة عند تحقق شرط معين، ستكون الشيفرة طويلة وخاصة إن كان أمامك عدد كبير من الخيارات. تظهر في حالات كهذه فائدة البنية switch التي تأخذ عبارة أو قيمة واحدة ثم تبحث عن هذه القيمة أو الشرط بين الخيارات المتعددة المتاحة حتى تجد المطلوب وتنفذ عندها الشيفرة التي يضمها الخيار المطابق. إليك قالب استخدام switch: switch (expression) { case choice1: // run this code break; case choice2: // run this code instead break; // include as many cases as you like default: // actually, just run this code break; } لدينا في الكود السابق: الكلمة المحجوزة switch يليها قوسان. عبارة أو قيمة ضمن القوسين. الكلمة المحجوزة case يتبعها خيار يمثل ما يمكن أن تكونه العبارة أو القيمة التي تشير إليها. شيفرة تُنفَّذ إن طابق الخيار العبارة أو القيمة. الكلمة المحجوزة break تليها فاصلة منقوطة كي يتوقف المتصفح عن التحقق من بقية الخيارات عندما يجد الخيار المطابق ويتابع تنفيذ الشيفرة ما بعد الكتلة switch. تكرار للبنية case وفقًا لعدد الخيارات الموجودة. الكلمة المحجوزة default يليها نمط الشيفرة الموجود في أي حالة case أخرى ما عدا أن default لا يتبعها خيار محدد ولا تحتاج إلى التعليمة break لأنها آخر ما يُنفّذ في عبارة switch ويمثّل الخيار الافتراضي إن أخفق التطابق مع جميع الخيارات المتاحة. ملاحظة: لا حاجة لوجود الجزء default وبإمكانك حذفه إن كنت متأكدًا تمامًا من وجود حالة تطابق. لكن إن أمكن وجود حالة عدم تطابق لا بد من تضمينها لمعالجة الحالات المجهولة. مثال عن كتلة switch لنلق نظرة اﻵن على مثال واقعي، يُظهر استخدام الكتلة switch في تطبيق الأحوال الجوية: <label for="weather">Select the weather type today: </label> <select id="weather"> <option value="">--Make a choice--</option> <option value="sunny">Sunny</option> <option value="rainy">Rainy</option> <option value="snowing">Snowing</option> <option value="overcast">Overcast</option> </select> <p></p> const select = document.querySelector("select"); const para = document.querySelector("p"); select.addEventListener("change", setWeather); function setWeather() { const choice = select.value; switch (choice) { case "sunny": para.textContent = "It is nice and sunny outside today. Wear shorts! Go to the beach, or the park, and get an ice cream."; break; case "rainy": para.textContent = "Rain is falling outside; take a rain coat and an umbrella, and don't stay out for too long."; break; case "snowing": para.textContent = "The snow is coming down — it is freezing! Best to stay in with a cup of hot chocolate, or go build a snowman."; break; case "overcast": para.textContent = "It isn't raining, but the sky is grey and gloomy; it could turn any minute, so take a rain coat just in case."; break; default: para.textContent = ""; } } العامل الثلاثي Ternary operator نريد أخيرًا المرور على صيغة أخيرة للعبارات الشرطية قبل الانتقال إلى التمارين وهي العامل الثلاثي الذي يختبر شرطًا واحدًا ويعيد قيمة أو عبارة إن كان الشرط محققًا وقيمة أو عبارة أخرى إن لم يكن محققًا. لهذا العامل فائدته في بعض الحالات ويحتاج إلى شيفرة أقل من كتلة if...else في حال كان لديك خيارين اثنين لانتقاء أحدهما وفقًا لنتيجة من الشكل true/false. condition ? run this code : run this code instead إليك مثالًا بسيطًا: const greeting = isBirthday ? "Happy birthday Mrs. Smith — we hope you have a great day!" : "Good morning Mrs. Smith."; تعرض الشيفرة متغيرًا يُدعى isBirthday فإن كانت قيمته true يُحييا الضيف برسالة معايدة بعيد ميلاده، أما إن كانت قيمته false فيُحييا بالتحية الاعتيادية. مثال عن العامل الثلاثي لا تُستخدم المتغيرات فقط مع العامل الثلاثي، بل يستطيع أن ينفذ دوال أو أسطر متعددة من الشيفرة. ولتوضيح الأمر، يعرض المثال التالي برنامجًا لاختيار سمة لتنسيق موقع ويب باستخدام العامل الثلاثي: <label for="theme">Select theme: </label> <select id="theme"> <option value="white">White</option> <option value="black">Black</option> </select> <h1>This is my website</h1> const select = document.querySelector("select"); const html = document.querySelector("html"); document.body.style.padding = "10px"; function update(bgColor, textColor) { html.style.backgroundColor = bgColor; html.style.color = textColor; } select.addEventListener("change", () => select.value === "black" ? update("black", "white") : update("white", "black"), ); See the Pen js-making-decisions2 by Hsoub Academy (@HsoubAcademy) on CodePen. لدينا في الشيفرة السابقة العنصر <select> الذي يُستخدم في اختيار سمة (أحد اللونين اﻷبيض أو اﻷسود)، إضافة إلى عنصر عنوان من المستوى اﻷول <h1> لعرض عنوان صفحة الويب. كما لدينا الدالة ()update التي تأخذ لونين كمعاملين لها. تضبط الدالة لون خلفية الصفحة لتصبح اللون الأول ولون النص هو اللون الثاني. نلاحظ أخيرًا استخدام مترصّد اﻷحداث onChange الذي ينُفِّذ الدالة مع معاملين هما اللونين اﻷسود واﻷبيض. يبدأ البرنامج بالعبارة الشرطية select.value === 'black' وبعدها تُنفّذ الدالة ()update ومعاملاها اللونان اﻷسود واﻷبيض، إذا كانت النتيجة true وبالتالي تصبح الخلفية سوداء والنص أبيض. أما إن أعاد الشرط السابق القيمة false، تُنفَّذ الدالة ()update ومعاملاها اللونان الأبيض واﻷسود فتكون الخلفية بيضاء والنص أسود اللون. مثال عل إنشاء تقويم زمني بسيط سننشئ تطبيق تطبيق تقويم زمني بسيط يتيح للمستخدم الاختيار بين اﻷشهر المختلفة المستخدم ليعرض تقويم مناسب للشهر. إذا كان لدينا تصميم الصفحة التالية: <h2>Live output</h2> <iframe id="output" width="100%" height="600px"></iframe> <h2>Editable code</h2> <p class="a11y-label"> Press Esc to move focus away from the code area (Tab inserts a tab character). </p> <textarea id="code" class="playable-code" style="height: 400px;width: 95%"> const select = document.querySelector('select'); const list = document.querySelector('ul'); const h1 = document.querySelector('h1'); select.addEventListener('change', () => { const choice = select.value; // ADD CONDITIONAL HERE createCalendar(days, choice); }); function createCalendar(days, choice) { list.innerHTML = ''; h1.textContent = choice; for (let i = 1; i <= days; i++) { const listItem = document.createElement('li'); listItem.textContent = i; list.appendChild(listItem); } } createCalendar(31, 'January'); </textarea> <div class="playable-buttons"> <input id="reset" type="button" value="Reset" /> <input id="solution" type="button" value="Show solution" /> </div> لنضف بعض التنسيقات كما يلي: html { font-family: sans-serif; } h2 { font-size: 16px; } .a11y-label { margin: 0; text-align: right; font-size: 0.7rem; width: 98%; } body { margin: 10px; background: #f5f9fa; } هذا كود جافا سكريبت المطلوب لعمل التقويم الزمني بالشكل المناسب: const select = document.querySelector("select"); const list = document.querySelector("ul"); const h1 = document.querySelector("h1"); select.addEventListener("change", () => { const choice = select.value; let days = 31; if (choice === "February") { days = 28; } else if ( choice === "April" || choice === "June" || choice === "September" || choice === "November" ) { days = 30; } createCalendar(days, choice); }); function createCalendar(days, choice) { list.innerHTML = ""; h1.textContent = choice; for (let i = 1; i <= days; i++) { const listItem = document.createElement("li"); listItem.textContent = i; list.appendChild(listItem); } } createCalendar(31, "January"); كما تلاحظ في الكود أعلاه فقد استخدمنا معالج أحداث onchange يرصد تغيّر قيمة العنصر الذي يختاره المستخدم من العنصر <select>، وكتبنا عبارة شرطية ضمن دالة معالج الأحداث onchange مهمتها ما يلي: النظر إلى الشهر المختار المُخزَّن في المتغير choice وهو قيمة العنصر <select>. ضبط المتغيّر days كي يكون مساويًا لعدد أيام الشهر المختار. وهذه النتيجة التي ستحصل عليها: تطبيق عملي: خيارات لونية أكثر ستحوّل في هذا التمرين العامل الثلاثي الذي تعرفنا عليه سابقًا إلى عبارة switch كي نتمكن من تطبيق خيارات أكثر على موقع الويب البسيط الذي نعمل عليه. لاحظ أن العنصر <select> لا يضم خيارين فقط بل خمسة، لهذا لا بد من استخدام switch هذه المرة تحت التعليق ADD SWITCH STATEMENT//: يجب أن تقبل العبارة المتغير choice ليكون عبارة الدخل. يجب أن تُوازن قيمة المتغير choice في كل حالة مع أحد الخيارات <option> وهي white أو black أو purple أو yellow أو psychedelic. يجب تنفيذ الدالة ()update في كل حالة وذلك بتمرير قيمتين لونيتين لها تمثّل اﻷولى لون الخلفية والثانية لون النص، وتذكر أن هذه القيم نصيّة ولا بد من وضعها ضمن إشارتي تنصيص. إذا ارتكبت خطأ، يمكنك دائمًا إعادة تعيين المثال باستخدام زر "Reset" الموجود في نهاية الإطار التالي، وإذا واجهتك مشكلة في حل السؤال بنفسك، فاضغط على زر "Show solution" لرؤية الحل الصحيح. See the Pen js-making-decisions4 by Hsoub Academy (@HsoubAcademy) on CodePen. الخلاصة قدمنا في هذا المقال كل ما تحتاج معرفته حاليًا عن البنى الشرطية في جافا سكريبت، راجع المقال مرارًا لترسّخ المعلومات التي حصلت عليها في ذهنك أو بإمكانك طرح اﻷسئلة التي تشاء في نقاش صفحة المقال ضمن أكاديمية حسوب. ترجمة -وبتصرف- لمقال: Making decisions in your code-conditionals اقرأ أيضًا المقال السابق: المصفوفات في جافا سكريبت تعرّف على لغة جافا سكريبت من منظور عام تعلم لغة جافا سكريبت من الصفر حتى الاحتراف المعاملات المنطقية في جافاسكربت الجمل الشرطية if/else في جافاسكريبت
-
من أكثر الأخطاء كارثيةً على الإنتاجية هو عدم التطابق بين أهداف فريق العمل وتوقعات المديرين. وستجد دائمًا وجهين عندما يتعلق الأمر بتأسيس قناة فعالة للتواصل في مقر العمل: الأول هو رأي المدير أو توجيهاته إلى الموظفين، والآخر هو آراء الموظفين وردودهم الموجهة إلى المدير. إنّ هكذا قناة ثنائية الاتجاه قادرة على خلق العديد من الفرص التي تزيد من إنتاجية الفريق وتعزز اندماج الموظفين في العمل. لقد جمعنا في هذا المقال 12 مثالًا عن الطريقة التي يخاطب فيها الموظف مديريه حول أمر ما والتي قد تستفيد منها لاحقًا في تحديد وحل أي طارئ. ما الأهمية الحيوية للإفادات الموجهة إلى المديرين لا أحد يريد أن يسمع ردود أفعال سلبية مهما تكون بناءةً ودقيقة. لقد بينت الدراسات أن 37% من الموظفين لا يعدون أنفسهم مقربين من مديريهم، وأنّ 64% منهم يرغبون بردود فعل أفضل، لهذا لا بدّ من إيصال آراء الموظفين وردود أفعالهم إلى مديريهم لتعزيز نمو الشركة. سيشعر الموظف بقيمته إن كان لرأيه أهمية، وهذا سيقود بدوره إلى حافز أعلى للعمل والمشاركة، وبالتالي إلى إنتاجية أفضل، فقد لا يعلم الكثير من المديرين بوجود مشاكل، وقد لا يعرفون بها حتى تنفجر أمامهم إن أهملوا الاطلاع على آراء الموظفين ومتطلباتهم أو تجاهلوها. قد تؤثر ديناميكية السلطة بين الموظفين والمديرين على إيصال الآراء إلى المدير وجعلها أمرًا محفوفًا بالمخاطر، فقد يساهم المدير الأقل استعدادًا للاستماع مباشرةً في تلويث بيئة العمل مما يؤثر سلبًا على كل من فيها. تعطي القدرة على تبادل الآراء فهمًا أفضل للمشاكل المحتملة ولأداء الفريق بالكامل. عليك أن تبني إذًا ثقافة تبادل الآراء في شركتك كي يشعر كل شخص بالراحة عندما يحاول أن يقدم رأيًا. 12 مثال عن الردود البناءة للمديرين من السهل أن تقول ما تريد قوله لمديرك أمام المرآة، لكنه أمر غير مريح عندما ينتقل الأمر إلى أرض الواقع، ولهذا نظمنا فيما يأتي قائمةً بأمثلة عن التظلمات والطلبات والآراء وكيفية إيصالها إلى المدير. 1. الحاجة إلى التوجيه يلقي بعض المديرين العمل بأكمله على الفريق دون أن يتدخلوا بالتفاصيل وهذا أمر جيد بالنسبة للموظفين الطموحين، لكنه قد يسبب نقصًا في التوجيه وشعورًا بعدم الثقة. أحد الأمثلة لمقاربة هذه الحالة: "أعرف أنك كثير المشاغل، فهل يمكننا بطريقة ما وضع جدول كي تتأكد دوريًا أنّ عملي على المسار الصحيح في هذا المشروع؟ وبمجرد أن أكوِّن فكرةً أفضل عما تتوقعه من نتائج وعن مسار الإنجاز المبدئي للمشروع بأكلمه، أعتقد أني سأكون قادرًا على المتابعة بنفسي." يظهر هذا النوع من الطلبات استعدادك للعمل الاستباقي والمستقل لكن مع حاجة لبعض التواصل في بعض النقاط. 2. مدير شديد التدقيق يشعر الموظف على نقيض الحالة السابقة بأن المدير لا يثق بمهاراته أو خبراته أو أحكامه. وقد تشعر بعض الفرق بأن عليهم ترك العمل للمدير بأكمله طالما أنه سيتدخل في كل صغيرة وكبيرة أيًا ما فعلوا. وكنتيجة لذلك، ستنخفض الروح المعنوية للفريق ويقل اندماجهم في العمل. أحد الأمثلة لمقاربة هذه الحالة: "أقدر كثيرًا ملاحظاتك وإرشاداتك، لكن أعتقد أني سأتعلم وأنجز أفضل إن استطعت تصوّر الهدف وكيفية بلوغه بنفسي. وعلى الرغم من استمتاعي بمشاعر إنجاز المهام الموكلة إلي، فإني أقضي وقتًا أكبر في كتابة التقارير بدلًا من التركيز على مشروعي. هل بإمكاننا الانتقال إلى أسلوب التقرير الأسبوعي أو الشهري؟" 3. الحاجة إلى توضيح الوجهة قد يفترض المدير أحيانًا أنّ فريقه يفهم تمامًا ما يتوقعه من مشروع معين، فلا يزوّدهم بكل التفاصيل المطلوبة. يمكن لضبابية الوجهة أن تؤثر على أداء بعض أعضاء الفريق وتبطئ تنفيذ المشروع، فقد يرتكب الفريق أخطاءً من الممكن تفاديها لو أنّ الأهداف أكثر وضوحًا. أحد الأمثلة لمقاربة هذه الحالة: "أود أن أشكرك على الثقة التي منحتها للفريق كي يفكّر بحرية في طريقة إنجاز هذا المشروع وأهدافه، لكني لاحظت أثناء العمل عدم وضوح الأولوية في ترتيب الأهداف، فهل يمكنك تقديم بعض الإيضاحات عن الأولوية التي تريدها لأهداف المشروع رجاءً؟". 4. لا تحصل على التقدير الذي تستحقه من المدير لا شيء أسوأ من بذل قصارى جهدك في المشروع ثم لا تلقى أي تقدير لما فعلته من مديرك أو زملائك. عندما يشعر الموظف بقلة التقدير سيقلل اندماجه في المشروع إلى الحد الأدنى الذي يتفادى معه الطرد، في حين يشعر في المقابل من يتلقى مكافآت على ما يبذله من جهد بالاندفاع الشديد نحو العمل. فإن كنت تشعر بأنك لا تلقى التقدير الذي تستحقه من مديرك ولا ردود فعل إيجابية، فحاول أن تستفسر عن الأمر بالشكل التالي: "لقد قدمت الكثير من الإضاءات الرائعة على أداء فريقنا في المشروع السابق، لكنني لاحظت أنك أخرجت عددًا من أعضاء الفريق في مرحلة مبكرة. هل بإمكاننا أن نبدأ الاجتماع بإظهار التقدير للفريق بأكمله قبل الانتقال إلى النقاط التي ينبغي تحسينها؟ فقد يعزز ذلك الروح المعنوية ويزيد اهتمام وحماسة الجميع للمشروع القادم". 5. الشعور بالإرهاق لهذا الشعور أسباب كثيرة وأهمها هو كثافة العمل الملقى على عاتق موظف واحد. على المدير أن يتابع حجم العمل المخصص لكل عضو من أعضاء الفريق أسبوعيًا، لكن مشاغلهم قد تبعدهم عن هذا الموضوع. من المهم ألا تخجل من الإشارة إلى كم العمل الذي تنجزه إن كان مرهقًا. إحدى الطرق للإشارة إلى رغبتك في متنفس أوسع: "بعد تقييمي لمهامي الحالية خلال هذا الشهر، رأيت أني أقضي 25 ساعة أسبوعيًا على المشروع "أ" بالإضافة إلى 10 ساعات إضافية. ستؤثر أية مهام إضافية على عملي الحالي ولن أتمكن من تقديم الأداء المطلوب فيها. هل يمكنني مقابلتك لمناقشة كم العمل الذي يمكنني إنجازه كي أقدم الأداء الأمثل؟". 6. الموازنة بين العمل ومشاغل الحياة يعتقد بعض المديرين أن أولويات موظفيهم هي نفسها أولوياتهم، وهذا ما يقود إلى الصراع بين العمل ومشاغل الحياة. قد يكون إبداء رأيك في الأمر بنّاءً كالتالي: "أحترم اندفاعك لإنجاز العمل وأقدر طريقتك في تنفيذ الأمر، لكنها بدأت بالتأثير سلبًا على حياتي الشخصية. هل يمكننا ترتيب لقاء كي نناقش به طريقة أكثر فعالية في التواصل "وضمن أوقات الدوام" المحددة؟". 7. حل المشاكل داخل الفريق ستظهر الخلافات في مرحلة ما داخل الفريق. وعلى الرغم من أنّ مهارات القائد في حل المشاكل وقوة شخصيته كافيان لحل هذه النزاعات، لكن لا بد من معرفته بها أولًا: ابدأ الحديث كالتالي: "ظهرت بعض الخلافات مؤخرًا بين أعضاء الفريق وقد تؤثر على أدائنا وعملنا الجماعي. ما رأيك في ترتيب آلية تراها مناسبة وبإشرافك لتدارك الأمر، كي نستفيد من إمكانياتك في إرشادنا إلى أفضل طريقة للتصرف؟". 8. تفضيل موظف على آخر قد يؤثر ذلك على الروح المعنوية ويقلل من رغبة الموظفين في المساهمة في العمل، كما قد ينمي بيئة عمل عدائية. يمكن أن تنقل هذه المشكلة إلى الموارد البشرية في شركتك، لكن إن كنت واثقًا من قوة علاقتك بمديرك، فيمكنك أن تبدأ كالتالي: "أتطلع باستمرار إلى تحسين مهاراتي في العمل مع عميل جديد، فهل يمكنك أن توضح لي سبب عدم اختياري؟". 9. كلمات التشجيع حال المديرين كالموظفين، فهم يرغبون بالتشجيع والتقدير ويحبون تلقي الردود الإيجابية على كافة مستوياتهم. وعندما يطوّر المديرون العلاقة مع موظفيهم سيزيد احتمال تلقيهم ردودًا إيجابية. بإمكانك توجيه الشكر إلى مديرك سرًا أو علنًا بأسلوب مشابه للتالي: "شكرًا جزيلًا على التقدير الذي أبديته لفريقنا عند إنجازه المشروع الأخير. لم نكن لننجز ما أنجزناه دون إرشادك وتوجيهك. ونتطلع قدمًا للعمل على تحدٍ جديد ورفع أدائنا إلى مستوىً أعلى". 10. إبداء آراء بناءة في الوقت المناسب لا يشعر موظف من بين أربعة تقريبًا بأنه يتلقى آراءً كافية على عمله تساعده في التقدم. وقد تكثر مشاغل المديرين فيغفلون هذه الناحية. إن لم تستطع لقاء مديرك سوى أثناء جلسات تقييم الأداء، فيمكنك أن تطرح الموضوع على الشكل التالي: "أعلم أن مشاغلك كثيرة، لكن إن استطعنا عقد جلسات أكثر لتبادل الآراء، فسيعزز ذلك الروح المعنوية للفريق. وبهذا الشكل نضبط أداءنا بدقة أكبر ونزيد من إنتاجيتنا الحالية". 11. الحصول على أفكار للنمو والتطور إن شعرت بأنك مقيّد في مهمة ما لا تجد فيها أبدًا فرصة للتطور، فقد حان الوقت لترتيب لقاء مع مديرك. إن كنت تبذل جهدك في عمل ما ولا ترى النتائج المتوقعة، ففكر في مخاطبة المدير كالتالي: "أحب عملي الحالي كثيرًا، لكني أرغب في الحصول على فرص أخرى لتنمو قدراتي وتتطور. هل يمكنني مقابلتك لنناقش إمكاناتي وأسمع رأيك عما يمكنني فعله لأترقى أكثر في الشركة؟". 12. مخاوف متعلقة بإدارة الوقت سيؤثر حجم المهام التي تُلقى على عاتقك سواءً كثيرة جدًا أو قليلةً جدًا على جودة عملك، وسيؤثر ذلك بدوره على الروح المعنوية لديك. ابدأ الحديث كالتالي: " بدأت أعاني مؤخرًا في عملي لأنني غير قادر على تخصيص الوقت الكافي لكل مهمة كما يجب. هل يمكنني لقاؤك لتحديد أولوية المهام الموكلة إلي وتوزيع المهام بالتساوي على كامل أعضاء الفريق؟". أفضل الممارسات في إبداء الآراء للمديرين لإبداء الآراء في غير مكانها انعكاسات سلبية، إذ لا بد من تحضير النقاط التي ستطرحها في محادثتك لأن أهميتها توازي أهمية رد المدير على موظفيه. إليك بعض الطرق التي تضمن إيصال رأيك إلى المدير بفعالية والحصول على النتائج الإيجابية المتوقعة: اسأل عن رغبة المدير في الاطلاع على رأيك يؤمن العديد من المدراء بفكرة الإدارة وحيدة الاتجاه من الأعلى إلى الأدنى، ولا يرغبون بالاستماع إلى الآراء أو تبادلها، خاصةً فيما يتعلق بقرارات الإدارة أو أساليبها. في هذه الحالة توجه إلى قسم الموارد البشرية كي لا تؤثر على تطور مهنتك ونمو قدراتك. قد تكون المسألة برمتها مسألة وقت فقط نظرًا لانشغال المديرين، لذا حاول في هذه الحالة اختيار الوقت المناسب لطرح الموضوع. اسألهم قبل البدء إن كان الوقت مناسبًا لطرح موضوعك، أو إن كان بالإمكان تحديد وقت لاحق للحديث. ابدأ بالوقائع ينبغي أن تكون طروحات الموظفين حياديةً وتركّز على أمثلة محددة. لن ترغب في الوصول إلى موضوع حساس أو قاسي وأنت تحاول أن تقدم رأيًا صريحًا، لأن هذا يمنع مديرك من تقبل ما تقول؛ لذا حاول أن توضح دائمًا أنّ ما تقوله مبني على تجاربك الشخصية وأنك لست مطلعًا على صورة الموقف بأكملها. جد الهدف المشترك تأكد من أنك في صف مديرك وركز على الأشياء المهمة بالنسبة إليه. استفد من حوارك معه في تحديد أهداف واستراتيجيات مشتركة وعزز الحوار بالتركيز على الاهتمامات المشتركة. اجعل ردود الفعل الإيجابية إطارًا لتعزيز الروح المعنوية تتلخص أفضل طريقة في تقديم نقد بناء ضمن حديثك بالخطوات التالية: ابدأ بمديح السلوك الإيجابي. ادخل بعد ذلك في صلب الموضوع. أنهِ بعبارة إيجابية أيضًا. تقبل الرفض قد يعارض مديرك ما تقوله، خاصةً إن قدمت رأيًا سلبيًا. لهذا تعلم أن تتراجع بهدوء وأن تتفهم أنك لا ترى الموضوع من نفس المنظور الذي يراه مديرك. اعرض رأيك على شكل أسئلة ستُظهر بهذه الطريقة تفهمك لمشاعر المدير بوضع نفسك مكانه، وستجبره صياغة طلبك على شكل أسئلة أن يرد بأجوبة قد تنطوي على الحلول المطلوبة. هل ينبغي التوجه إلى المدير بآراء صريحة حتى لو كانت سلبية؟ في عالم مثالي، قد يكون الجواب نعم. لتبادل الآراء بين الطرفين منافع كثيرة وأهمية كبرى لكلا الطرفين على حد سواء، مع ذلك لن يقدّر بعض المديرين الآراء غير المرغوب بها أو التي تنطوي على نقد سلبي لأدائهم. في هذه الحالة اتبع حدسك دائمًا، واسأل مديرك إن كان يرغب في سماع ما ستقوله أو أنّ الوقت مناسب لمثل هذا الحديث، خاصةً إن كان أساس حديثك إظهار السلبيات في الإدارة. ترجمة -وبتصرف- للمقال 12 Manager feedback examples for employees لصاحبته Rachel Steben. اقرأ أيضًا فوائد استطلاع آراء الموظفين أهمية تبادل الآراء مع الموظفين ما يتوقعه الموظفون من المديرين وفقا لآراء الموظفين الدليل الشامل للمديرين حول كيفية إعطاء الملاحظات للموظفين هل يشعر الموظفون بالراحة عند إعطاء آرائهم؟
-
يشرح هذا المقال الانسياب الاعتيادي للعناصر أو الطريقة التي تُرتّب فيها تلك العناصر ضمن صفحة الويب أي المواضع التي ستأخذها بشكل تلقائي إن لم يتغير تخطيطها. عليك قبل البدء في قراءة هذا المقال أن تكون على اطلاع بالمفاهيم التالية: أساسيات HTML. أساسيات عمل CSS. تُرتب العناصر في صفحة الويب كما شرحنا في المقال السابق مدخل إلى تخطيط صفحات ويب ضمن تخطيط تلقائي يُعرف بالانسياب الاعتيادي Normal Flow إن لم تُطبق أي تنسيقات CSS لتغيير هذا السلوك. وكما رأينا، يمكننا تغيير سلوك العناصر بتغيير موقعها في الانسياب الاعتيادي أو إزالتها من هذا الانسياب كليًا. وبالطبع فإن البدء بإنشاء مستند HTML متماسك ومهيكل بطريقة متينة وله انسياب اعتيادي واضح هي الطريقة الأنسب لتبدأ العمل على صفحة ويب. ستضمن بهذه الطريقة أن الصفحة مقروءة وواضحة بالنسبة لأي متصفح أو جهاز محدود الإمكانيات مثل قارئات الشاشة التي تقرأ للزائر محتويات الصفحة. إضافة إلى ذلك، فإن العمل مع تصميم الانسياب الاعتيادي الموجّة لإنشاء مستندات سهلة القراءة أفضل بكثير من العمل ضده عندما تبدأ بتعديل التخطيط بالشكل الذي تريده. لهذا السبب سنستعرض سريعًا في مقال اليوم بعض الأشياء التي مرّت معنا سابقًا والمتعلقة بالانسياب الاعتيادي قبل أن نتعمق في تفاصيل التخطيطات الأخرى. كيف تُرتب العناصر افتراضيًا في صفحة ويب؟ تبدأ عملية ترتيب العناصر التي تضيفها لصفحة الويب بشكل صناديق، وهذا ما يُدعى نموذج الصندوق Box model وهو نموذج يستخدم لتحديد وتصميم ترتيب وتخطيط العناصر في صفحة الويب. ويتكون النموذج من مربع يحيط بكل عنصر في الصفحة بحيث نحدد لكل مربع أربعة مكونات أساسية هي: الهامش Margin، والحاشية Padding، والإطار Border، والمحتوى Content كما تلاحظ في الصورة التوضيحية التالية: ولفهم المزيد عن ترتيب عناصر صفحة الويب عليك أن تفهم بشكل جيد ما هي المساحة التي سيشغلها كل عنصر تضيفه على الصفحة، فهناك نوعان مختلفان من عناصر HTML هما العناصر السطرية Inline-level والعناصر الكتلية Block-level، ويشغل كل نوع مساحة محددة من صفحة الويب، ويكمن الفرق الأساسي بين العناصر الكتلية والعناصر السطرية بأن العناصر الكتلية تعرض على أسطر منفصلة وتأخذ مساحة كاملة أفقيًا ورأسيًا، بينما تعرض العناصر السطرية على نفس السطر مع العناصر الأخرى وتأخذ مساحة تبعًا لحجم محتواها. حيث يملأ محتوى العناصر الكتلية block-level element افتراضيًا الفراغ الموافق لكامل السطر في العنصر الأب، وتنمو أو تتوسع هذه العناصر على طول البعد الرأسي أو ارتفاع الكتلة لاستيعاب محتواها، أما أبعاد العناصر السطرية inline-level elements فتتطابق مع أبعاد المحتوى. بالإمكان ضبط ارتفاع height أو اتساع width العناصر التي تأخذ فيها الخاصية display القيمة inline افتراضيًا مثل <img>، لكن تبقى قيمة display كما هي. وإن أردت التحكم بقيم الخاصية display للعناصر السطرية بهذه الطريقة، يمكن أن تستخدم CSS لجعلها تسلك سلوك العناصر الكتلية (مثل ;display: block أو ;display: inline-block التي تمزج ميزات كلا النوعين). ويفسر ذلك كيفية هيكلة العناصر كلًا على حدى، لكن ماذا عن هيكلتها عندما تكون معًا؟ هنا يظهر الانسياب الاعتيادي الذي أشرنا إليه سابقًا الذي يوضّع العناصر ضمن نافذة العرض الخاصة بالمتصفح. إذ ترتب العناصر الكتلية باتجاه الكتلة الذي يرتبط بدوره بنمط الكتابة (عادة أفقي horizontal-tb). يظهر كل عنصر في سطر مستقل تحت العنصر الذي يسبقه وتفصل بينهما الهوامش المخصصة لكل منها. ففي اللغة العربية أو الإنكليزية (أو أية لغة نمط الكتابة فيها أفقي)، سترتب العناصر الكتلية عموديًا. من ناحية أخرى، تسلك العناصر السطرية inline elements سلوكًا مختلفًا، فلا تظهر في أسطر مستقلة، بل تشغل السطر نفسه مع أي محتوى نصي مجاور أو ضمن عنصر حاوٍ طالما أن هناك فراغًا كافيًا ضمن المساحة الذي يشغلها العنصر الكتلي الأب. وإن لم يكن هناك فراغًا كافيًا فستنتقل العناصر التي تطفح عن السطر إلى سطر جديد. إن كان لأي عنصرين متجاورين عموديًا قيمة معينة للهامش وتلامس هامشيهما، سيبقى الهامش الأكبر فاصلًا بينهما ويختفي الهامش الأصغر، وهذا ما يُعرف بانكماش الهوامش margin collapsing، ويحدث فقط في الاتجاه العمودي. لنلق نظرة على المثال البسيط التالي الذي يشرح كل ما ذكرناه: <h1>Basic document flow</h1> <p> I am a basic block level element. My adjacent block level elements sit on new lines below me. </p> <p> By default we span 100% of the width of our parent element, and we are as tall as our child content. Our total width and height is our content + padding + border width/height. </p> <p> We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both. </p> <p> Inline elements <span>like this one</span> and <span>this one</span> sit on the same line along with adjacent text nodes, if there is space on the same line. Overflowing inline elements will <span>wrap onto a new line if possible (like this one containing text)</span>, or just go on to a new line if not, much like this image will do: <img src="long.jpg" alt="snippet of cloth" /> </p> body { width: 500px; margin: 0 auto; } p { background: rgba(255, 84, 104, 0.3); border: 2px solid rgb(255, 84, 104); padding: 10px; margin: 10px; } span { background: white; border: 1px solid black; } يوضح الكود السابق الطريقة الأساسية التي تتدفق بها العناصر والمحتوى في صفحة HTML تتضمن عنصر عنوان رئيسي h1، وأربع فقرات نصية p . لاحظ تأثير تطبيق نموذج الصندوق لتوضع هذه العناصر والقيم التي منحناها لتعديل الهامش والحدود والحشو للفقرات الأربعة p باستخدام تنسيقات CSS، سيكون الخرج على النحو التالي: See the Pen normal-flow-css by Hsoub Academy (@HsoubAcademy) on CodePen. الخلاصة تعلمنا في هذا المقال أساسيات الانسياب الاعتيادي أو الطبيعي Normal Flow للعناصر على صفحة الويب، وهو تخطيط CSS الافتراضي لترتيب العناصر. وبفهم السلوك الافتراضي للعناصر الكتلية والسطرية والهوامش، سيكون من السهل تعديلها في المستقبل، وسنعرفك في مقالات لاحقة على طرق وتقنيات أخرى لتنظيم العناصر على صفحات الويب مثل طريقة العناصر العائمة Floats والتخطيط الشبكي Grids والصندوق المرن Flexbox التي توفر لك أساليب مختلفة تساعدك على تحقيق تخطيطات منوعة لعناصر صفحات الويب واختيار ما يناسب احتياجات تصميم واجهات موقعك من بينها. ترجمة -وبتصرف- للمقال: Normal flow اقرأ أيضًا المقال السابق: مدخل إلى تخطيط صفحات الويب باستخدام CSS التحكم في تخطيط الصفحة وضبط محاذاة العناصر في CSS بعض العناصر والمفاهيم المهمة في لغة HTML عرض محتوى صفحات الويب بتجاوب على الأجهزة المتعددة تعرف على أساسيات لغة CSS
-
يُعد جودو محرّك ألعاب غني بالميزات، وهنالك الكثير لتتعلمه. لهذا سنشرح في هذا المقال كيفية استخدام دليل العمل على اﻹنترنت، والمراجع إلى الشيفرة والانضمام إلى مجتمع جودو لتعلم ميزات وتقنيات جديدة. الاستفادة القصوى من هذا المقال ما سنوضحه في هذا المقال هو طريقة التعامل دليل الاستخدام "user manual" الخاص بمحرك ألعاب جودو والذي يوثّق جميع مفاهيم محرّك الألعاب وميزاته المتاحة. فعندما تتعلم موضوعًا جديدًا، يمكنك البدء في تصفح القسم المخصص لهذا الموضوع في دليل المستخدم هذا. إذ تتيح لك القائمة اليمينية استكشاف مواضيع عامة عن محرك الألعاب، بينما يساعدك شريط البحث على إيجاد صفحات محددة. فإن وجدت صفحة خاصة بالموضوع ستكون مرتبطة غالبًا بصفحات أخرى متعلقة به يترافق هذا الدليل مع مراجع للأصناف "class reference" تشرح لك كل صنف أو دالة أو خاصية متاحة في جودو. فبينما يتحدث الدليل عن الميزات العامة والمفاهيم وكيفية استخدام المحرر، يتحدث مرجع اﻷصناف عن طريقة استخدام الواجهة البرمجية المستخدمة في كتابة سكربتات جودو Godot. وبإمكانك الوصول إلى معلومات هذا المرجع عبر اﻹنترنت أو محليًا. فكي تتمكن من تصفحها محليًا عبر محرر جودو كل ما عليك هو بالانتقال إلى "مساعدة Help" > "البحث في المساعدة Search Help" أو بالضغط على المفتاح F1: أما إن أردت البحث عن طريق اﻹنترنت انتقل إلى قسم مرجع اﻷصناف، وستدلك صفحة المرجع على ما يلي: أين هو موقع الصنف في التسلسل الهرمي، إذ يمكنك النقر على الروابط العليا للانتقال إلى الأصناف اﻵباء والاطلاع على الخاصيات والتوابع الموروثة. ملخص عن وظيفة الصنف وتوضيح حالات استخدامه. شرح خاصيات الصنف وتوابعه و إشاراته و معداته وثوابته. الربط مع صفحات الدليل التي تشرح الصنف أكثر. ملاحظة: إن كان دليل المستخدم أو مرجع الأصناف مفقودًا أو لم يحو على معلومات كافية، يمكنك فتح طلب من مستودع توثيق جودو على جيت هب للإبلاغ عن اﻷمر. بإمكانك النقر مع الضغط على المفتاح Ctrl على أية رابط نصي يمثل اسم صنف أو خاصية أو تابع أو إشارة أو ثابت للانتقال إليه. تعلم التفكير مثل المبرمجين إن موضوع تعلم أساسيات البرمجة وطريقة تفكير مطوري اﻷلعاب خارج سياق توثيق جودو لكنه أمر أساسي لك إن اردت أن تصبح مطور ألعاب . لذا إن كنت جديدًا في عالم البرمجة وكنت مهتمًا بتخصص برمجة وصناعة الألعاب الإلكترونية فننصحك بأن تُلمَّ قبل ذلك بأياسيات البرمجة قبل البدء، ويمكنك الاعتماد على أحد المصدرين التاليين: أكاديمية حسوب التي تقدم لك كمًا كبيرًا من المقالات المتخصصة بتعلم مختلف لغات البرمجة إضافة إلى دورات تدريبية عملية تبدأ بك من الصفر وحتى الاحتراف صممها وقدمها مبرمجون محترفون على دراية كاملة بمتطلباتك وتطلعاتك. موسوعة حسوب التي تعد أكبر مرجع باللغة العربية لتوثيق أشهر لغات البرمجة ومن بينها Python و JavaScript والعديد من اللغات والتقنيات الأخرى. التعلّم من خلال مجتمع جودو يتميز محرّك جودو بمجتمع يتطور ويزداد تعداده باستمرار. فإن واجهتك مشكلة ما وأردت المساعدة في فهم طريقة عمل شيء ما، بإمكانك سؤال مستخدمين آخرين ينتمون إلى أي من مجتمعات جودو النشطة. وأفضل مكان لطرح اﻷسئلة وإيجاد حلول لاسئلة طرحت مسبقًا هو الموقع الرسمي للأسئلة واﻷجوبة ask.godotengine . إذ تظهر الإجابات في نتائج محرّك البحث وتُخزّن ليستفيد اﻵخرون من النقاشات التي تدور في المنصة. وبمجرد أن تطرح سؤالًا، بإمكانك أن تستخدم رابطه لمشاركته في منصات أخرى. لكن قبل أن تطرح سؤالًا، تأكد من وجود أجوبة مسبقة عنه في هذه المنصة أو ابحث عنها باستخدام محرّك البحث الذي تفضلّه. الطريقة الصحيحة لطرح الأسئلة حول محرك جودو إن طرحك للسؤال بشكل جيد وتقديم تفاصيل دقيقة يساعد اﻵخرين في اﻹجابة عن سؤالك بسرعة. وننصحك عند طرح السؤال أن يتضمن المعلومات التالية: وصف الغاية من السؤال: يجب أن تشرح ما الذي تحاول فعله من وجهة نظر تصميمية. فإن لم تتمكن من تصور طريقة لتطبيق الحل، قد تكون هناك حلول أخرى أبسط لتحقيق نفس الغاية. مشاركة رسالة الخطأ كما هي تمامًا: إن كان هناك خطأ. انسخ رسالة الخطأ بدقة من المنقح بالنقر على أيقونة "انسخ الخطأ Copy Error". فمعرفة رسالة الخطأ تساعد أعضاء المجتمع في تحديد السبب الذي أدى لوقوع المشكلة. مشاركة عينة من الشيفرة: إن كان الخطأ في الشيفرة. فلن يتمكن اﻵخرون من مساعدتك في حل المشكلة دون رؤية الشيفرة. لذا شارك الشيفرة على شكل نص مباشرة بنسخ ولصق جزء من الشيفرة في رسالتك أو استخدام مواقع مثل Pastebin لمشاركة الملفات الطويلة. مشاركة لقطة شاشة: لحاوية المشهد في المحرر إضافة إلى شيفرتك. فالشيفرة التي تكتبها تؤثر على عقد عقد المشاهد. إذًا عليك التفكير بالمشاهد كجزء من شيفرتك المصدرية. كذلك لا تستخدم هاتف محمول لالتقاط الصور، فالدقة المنخفضة والانعكاسات قد تُصعّب فهم الصورة. لهذا استخدم الأداة التي يوفّرها نظام التشغيل لديك لالتقاط صورة للشاشة (مثل الزر Print Screen). كما يمكنك استخدام ShareX في ويندوز مثلًا أو FlameShot في لينكس. مشاركة فيديو للعبتك وهي تعمل: أمر مفيد جدّا. يمكنك استخدام برامج مثل OBS Studio أو Screen to GIF لالتقاط فيديو لسطح مكتبك، ثم استخدام خدمات مثل streamable أو مزوّد سحابي لرفع ومشاركة الفيديو. اﻹشارة إلى نسخة جودو التي تستخدمها: وخاصة إن لم تكن النسخة مستقرة stable version. لأن الجواب قد يختلف نتيجة لتغير الميزات والواجهة باستمرار. باتباعك اﻹرشادات السابقة ستزيد فرص حصولك على الجواب الدقيق الذي تبحث عنه، وسيوفر وقتك ووقت اﻷشخاص الذين يساعدونك في حل مشكلتك. مصادر تعليمية حول محرك الألعاب جودو إن كنت تبحث عن دورات حول إنشاء نوع لعبة إلكترونية مثل خطوات إنشاء لعبة تقمص الأدوار "Role-Playing Games" أو غيرها من أنواع الألعاب الإلكترونية، ننصحك بالاطلاع على قسم المصادر والدورات التعليمية Tutorials and resources الذي يعرض محتوى متخصصًا يقدمه مجتمع جودو. وإذا كنت مهتمًا بمعرفة المزيد من التفاصيل عن محرك ألعاب جودو Godot أو لغة برمجة الألعاب GDScript وطريقة تطوير الألعاب ثنائية الأبعاد وثنائية الأبعاد باللغة العربية، فننصحك بالاطلاع على سلسلة المقالات المنشورة في أكاديمية حسوب تحت وسم godot، كما يمكنك الاطلاع على العديد من المقالات المفيدة في قسم مقالات صناعة الألعاب الذي ينشر بصورة دورية العديد من المقالات التي تفيدك كمطور ألعاب. ويمكنك كذلك طرح أي سؤال أو مشكلة تعترضك خلال برمجة لعبتك الخاصة في قسم الأسئلة والأجوبة في الأكاديمية أو في مجتمع حسوب IO. الخلاصة تعرفنا في مقال اليوم على طريقة الاستفادة من الميزات الجديدة التي يوفرها لك محرك الألعاب جودو Godot وأهمية التفكير البرمجي لك كمطور ألعاب وكيفية طرح سؤال حول أي مشكلة تقنية تصادفك خلال صناعة لعبتك بطريقة صحيحة وحلها بسرعة وكفاءة، وأخيرًا ختمنا المقال بمصادر تعليمية مفيدة حول Godot وتطوير الألعاب. ترجمة -وبتصرف- لمقال: Learning new features من توثيق جودو الرسمي اقرأ أيضًا دليلك الشامل إلى بناء كاميرا خاصة بشاشات اللمس في محرّك اﻷلعاب جودو تعرف على محرر محرك اﻷلعاب جودو Godot إعداد محرك الألعاب جودو Godot للعمل مع قاعدة البيانات SQLite تشغيل محرك الألعاب جودو على بعض أنواع العتاد غير المدعوم تعرف على أشهر لغات برمجة الألعاب
-
سنلقي نظرة في هذا المقال على جافا سكريبت JavaScript من منظور عام ونجيب على أسئلة مثل "ما هي جافا سكريبت؟" و "ماذا تفعل هذه اللغة؟" لنتأكد أنك تملك الفهم الجيد لهذه اللغة بالعموم قبل الغوص في التفاصيل الأكثر تعقيدًا. لن تحتاج أية معرفة مسبقة بلغة جافا سكربت لتتابع معنا، لكن عليك قبل البدء بقراءة هذا المقال أن تمتلك بعض المعرفة بالأمور التالية: معرفة ببعض أساسيات HTML و CSS، لهذا ننصحك بالاطلاع على بعض المقالات السابقة مثل: أساسيات HTML. أساسيات عمل CSS. عالم الويب ومعاييره. ملاحظة: إن كنت تعمل على حاسوب أو جهاز لوحي أو أجهزة أخرى لا تسمح لك بإنشاء ملفات خاصة بك، يمكن تجريب معظم الأمثلة والشيفرات ضمن محرر برمجي عبر الإنترنت مثل JSBin أو Glitch. ما هي لغة جافا سكريبت لغة جافا سكريبت هي لغة برمجة تسمح لك بتنفيذ ميزات عديدة في صفحات الويب. ترى ذلك في الصفحات التي لا تكتفي بعرض معلومات ثابتة أو تلك التي تحدّث محتواها تلقائيًا مع الوقت أو تعرض خرائط تفاعلية أو رسوم ثنائية وثلاثية البعد. تُعد جافا سكريبت الطبقة الثالثة من طبقات الكعكة التي تمثّل تقنيات الويب المعيارية أما الطبقتان الباقيتين فهما HTML و CSS، وقد غطينا المفاهيم المتعلقة بهما في مقالات سابقة من سلسلة تعلم تطوير الويب. HTML: لغة توصيف تُستخدم لهيكلة صفحات الويب وإعطاء معنى لمحتواها. فهي تعرّف مثلًا المقاطع النصية والعناوين وجداول البيانات والصور والفيديو. CSS: هي لغة تنسيق تُطبق قواعد تنسيق محددة على محتوى HTML مثل ضبط ألوان الخلفية وخطوط الكتابة وترتيب المحتوى ضمن عدة أعمدة جافا سكريبت: لغة برمجة تمكّنك من إنشاء محتوى يُحدّّث ديناميكيًا على صفحات الويب، والتحكم بالوسائط المتعددة وتحريك الصور وكل ما يجعل صفحة الويب تفاعلية (ليس كل شيء تمامًا، لكنها ستذهلك بما يمكن أن تفعله شيفرة مكوّنة من أسطر قليلة) تُبنى هذه الطبقات فوق بعضها بأناقة، ولنأخذ عنوان نصي بسيط كمثال. سنوصّف ذلك من خلال لغة HTML التي تعطيه الشكل وتصف الغاية منه: <p>Player 1: Chris</p> يمكننا بعد ذلك إضافة بعض تنسيقات CSS لكي نحسّن المظهر: p { font-family: "helvetica neue", helvetica, sans-serif; letter-spacing: 1px; text-transform: uppercase; text-align: center; border: 2px solid rgb(0 0 200 / 0.6); background: rgb(0 0 200 / 0.6); color: rgb(255 255 255 / 1); box-shadow: 1px 1px 2px rgb(0 0 200 / 0.4); border-radius: 10px; padding: 3px 10px; display: inline-block; cursor: pointer; } وأخيرًا يمكننا إعطاء ديناميكية للصفحة بإضافة شيفرة جافا سكريبت بسيطة على النحو التالي: const para = document.querySelector("p"); para.addEventListener("click", updateName); function updateName() { const name = prompt("Enter a new name"); para.textContent = `Player 1: ${name}`; } See the Pen javascript1 by Hsoub Academy (@HsoubAcademy) on CodePen. جرّب أن تنقر على العنوان النصي بنسخته الأخيرة وراقب ما سيحدث. ما تفعله جافا سكريبت حقيقة أكثر من ذلك بكثير، سنستعرض ذلك بتفاصيل أوفى في الفقرات التالية. ما الذي تستطيعه جافا سكريبت حقيقةً؟ تتكون لغة جافا سكريبت التي تعمل من ناحية العميل من بعض الميزات البرمجية البنيوية التي تسمح لك بتنفيذ الكثير من الأشياء مثل: تخزين قيم مهمة ضمن المتغيرات. فما فعلناه في المثال السابق مثلًا أننا طلبنا إدخال اسم جديد ثم خزّنا القيمة المُدخلة في متغيّر سميناه name. العمل على جزء من نص وهو ما يعرف برمجيًا بالسلسلة النصية String فإذ أخذنا في المثال السابق السلسلة النصية " :Player1" وأضفنا إليها قيمة المتغيّر name يمكننا إنشاء عنوان نصي كامل مثل "Player 1: Chris". تنفيذ شيفرة برمجية استجابةً لحدث معين يقع في صفحة الويب، فقد استخدمنا في المثال السابق الحدث click لالتقاط عملية النقر على العنوان النصي ومن ثم نفذنا الشيفرة التي تُحدّث العنوان بعد إضافة الاسم عليه. وهناك الكثير من الأشياء التي تقوم بها لغة جافا سكريبت أيضًا! ولعل أكثر الأمور إثارة، هي القدرة الوظيفية الكبيرة لهذه اللغة من طرف العميل والتي تُعرف بواجهة التطبيق البرمجية Application programming Interface واختصارًا API والتي تعطي قوة كبيرة في استخدام الشيفرة. فواجهات API هي مجموعة معدة سلفًا من الشيفرة التي تسمح للمطور بتنفيذ برامج من الصعب أو المستحيل إنجازها. وما تقدمه هذه الواجهات للشيفرة يشابه ما يمنحه الأثاث والتجهيزات المنزلية للمنزل. فمن السهل أن تأخذ قطع خشبية مقصوصة وجاهزة ثم تجمّعها بالبراغي لتحصل على رف كتب مثلًا بدلًا من أن تصمم كل شيء بنفسك، إذ عليك حينها أن تجد نوع الخشب المناسب ثم تقطع الأخشاب وفق القياس الصحيح والشكل المطلوب وأن تجد البراغي المناسبة ومن ثم تجميعها لتحصل على رف الكتب المطلوب. وتصنّف واجهات API عمومًا ضمن فئتين أساسيتين: واجهات API الخاصة بالمتصفح واجهات API يقدمها طرف آخر Third party API وسنشرح تاليًا آلية عمل كل منهما بمزيد من التفصيل. واجهات API الخاصة بالمتصفح وهي برمجيات مدمجة في بنية المتصفح، قادرة على التعامل مع البيانات في البيئة الحاسوبية أو أن تقوم ببعض العمليات المعقدة المفيدة مثل: واجهة DOM (أو DOM API) وتسمح بالتعامل مع ملفات HTML و CSS كإنشاء وحذف وتغيير شيفرات HTML ديناميكيًا وتطبيق تنسيقات جديدة، فكل مرة ترى فيها نافذة منبثقة تُعرض على المتصفح أو ظهور محتوى جديد في الصفحة هي من فعل واجهة DOM. واجهة الموقع الجغرافي (Geolocation API) تستخلص برمجيات الواجهة معلومات جغرافية عن موقعك، لهذا يستطيع تطبيق خرائط جوجل العثور على موقعك وإظهاره على الخريطة. واجهتا canvas و webGL: اللتان تساعدانك على إنشاء رسومات متحركة ثنائية وثلاثية الأبعاد، وتستطيع تنفيذ أشياء رائعة باستخدامهما. واجهات الفيديو والصوتيات مثل HTMLMediaElement و WebRTC: التي تسمح لك بتنفيذ أشياء مميزة مع الوسائط المتعددة مثل تشغيل مقاطع الصوت والفيديو في صفحة الويب مباشرة أو التقاط بث كاميرا الويب وعرضها على حاسوب آخر. ملاحظة: يُفضّل عند تجريب استخدام الواجهات البرمجية استخدام متصفحات حديثة مثل فايرفوكس أو كروم أو إيدج أو أوبيرا. كما عليك الأخذ بعين الاعتبار فكرة اختبار الشيفرة على اكثر من متصفح وخاصة عند الوصول إلى مرحلة تسليم شيفرة الإنتاج بعد إنهاء الشيفرة التجريبية. واجهات API يقدمها طرف ثالث لا تُبنى هذه الواجهات ضمن المتصفح افتراضيًا، وعادة ما تحصل على شيفرتها من الويب. ومن الأمثلة عليها واجهة تويتر Twitter API: وتسمح لك بعرض آخر تغريداتك ضمن موقع الويب الخاص بك مثلًا وغيرها من الأشياء. واجهة خرائط جوجل وواجهة OpenStreetMap API وتسمحان لك بإدراج خرائط ضمن موقعك الإلكتروني وغيرها من الوظائف. ملاحظة: إن الواجهات البرمجية موضوع متقدم، ولن نغطي أيًا منها في حديثنا عن جافا سكريبت، لكن هناك الكثير أيضًا لتتعلمه حول لغة جافا سكريبت، فلا تأخذك الحماسة المفرطة. فلن تكون قادرًا على بناء فيسبوك أو خرائط جوجل أو إنستغرام بعد دراستك جافا سكريبت مدة 24 ساعة! فهنالك الكثير من الأساسيات التي عليك معرفتها أولًا، وهذا ما ستوفره لك سلسلة المقالات التالية حول جافا سكريبت. ما الذي تفعله جافا سكريبت في صفحة الويب سنلقي هنا نظرة على بعض الشيفرة، ونستعرض ما يحدث حقيقةً عندما تنفّذ شيفرة جافا سكريبت في صفحتك. لنستذكر سريعًا ما يحدث عند تحميل صفحة ويب في متصفح . عندما تحمّل صفحة ويب في متصفحك فإنك تنفّذ شيفرتك (HTML و CSS وجافا سكريبت) ضمن بيئة تنفيذية (نافذة المتصفح)، وهذا أمر مماثل لمعمل يستقبل موادًا أولية (الشيفرة) ويخرج منتجًا (صفحة الويب). إن أكثر الاستخدامات شيوعًا لجافا سكريبت هو تعديل شيفرة HTML و CSS ديناميكيًا لتغيير الواجهة من خلال الواجهة البرمجية DOM API. ولاحظ أن شيفرة صفحات الويب تُحمّل عمومًا وتنفذ وفق ترتيب ظهورها في الصفحة. وقد تحدث أخطاء إن حُمّلت شيفرة جافا سكريبت ونُفِّذت قبل شيفرة HTML و CSS التي ستُعدّل. سنتعلم لاحقًا في مقالنا كيف نلتف على الموضوع. أمان المتصفح لكل نافذة من نوافذ المتصفح جيب خاص لتنفيذ الشيفرة ويُعرف هذا الجيب ببيئة التنفيذ. ويعني ذلك عمومًا أن الشيفرة في كل نافذة تعمل بشكل منفصل تمامًا عن شيفرة النوافذ الأخرى ولا يمكن أن تؤثر الشيفرة في النافذة مباشرة على الشيفرة التي تجري في النافذة الأخرى أو على موقع ويب آخر. يُعد هذا الأمر مقياسًا جيدًا للأمان، فلو لم يكن الأمر كذلك سيكتب القراصنة شيفرات لسرقة معلومات من مواقع أخرى وغيرها من الأفعال الضارة. ملاحظة: هنالك طريقة لإرسال الشيفرة والبيانات من مختلف المواقع أو النوافذ بطريقة آمنة لكنها تقنيات متقدمة لن نغطيها في هذا المقال لكن يمكنك الاطلاع على مقال التخاطب بين نوافذ المتصفح عبر جافا سكريبت في أكاديمية حسوب. ترتيب تنفيذ شيفرة جافا سكريبت عندما يصادف المتصفح كتلة من شيفرات جافا سكريبت، سينفّذها عادة بالترتيب من الأعلى إلى الأسفل. ويعني هذا ضرورة الانتباه إلى الترتيب الذي تضع وفقه الأشياء. لنعد على سبيل المثال إلى شيفرة جافا سكريبت في المثال الأول: const para = document.querySelector("p"); para.addEventListener("click", updateName); function updateName() { const name = prompt("Enter a new name"); para.textContent = `Player 1: ${name}`; } نختار في السطر الأول مقطعًا نصيًا ثم نضيف مترصّد للحدث (مستمع للحدث) في السطر الثالث كي تُنفّذ شيفرة الكتلة البرمجية ()updteName (الأسطر من 5-8). تسأل الكتلة البرمجية ()updateName (يُدعى هذا النوع القابل للاستخدام المتكرر من الكتل البرمجية دوال functions) أن يُدخل المستخدم اسمًا جديدًا ومن ثم تضع الاسم ضمن الفقرة النصية وتحدّث ما يُعرض على الشاشة. فإن بدلت ترتيب أول سطرين، لن تعمل الشيفرة، بل ستحصل على خطأ تعرضه طرفية المطوّر في المتصفح وهي typeError: para is undefined. ويعني هذا أن الكائن para غير موجود بعد، ولا يمكن إضافة مترصّد أحداث إليه. ملاحظة: هذا الخطأ شائع الحدوث، لهذا انتبه إلى وجود الكائن في الشيفرة قبل أن تحاول العمل معه. الشيفرة المفسّرة والمصرّفة ربما سمعت بالمصطلحين "مفسّر interpreted" و "مصرّف compiled" في سياق تعلمك للبرمجة. ففي اللغات المفسّرة تنفّذ الشيفرة من الأعلى إلى الأسفل وتُعاد نتيجة تنفيذ الشيفرة مباشرة، ولا حاجة لنقل الشيفرة إلى شكل آخر قبل أن يُنفّذها المتصفح. إذ يستقبل الشيفرة بشكلها النصي المفهوم من قبل المبرمج ثم يعالجها مباشرة. بينما تحوّل الشيفرة في اللغات المصرّفة إلى شكل آخر قبل أن يُنفّذها الحاسوب. إذ تحوّل مثلًا شيفرة لغتي C أو ++C إلى لغة الآلة التي ينفذها الحاسوب بعد ذلك. وينفّذ البرنامج انطلاقًا من صيغته الثنائية التي تنتج عن تصريف شيفرته المصدرية. جافا سكريبت هي لغة برمجة مفسّرة خفيفة الحجم، يتلقى المتصفح شيفرتها بشكلها النصي وينفّذه. وإذا أردنا الحديث تقنيًا يمكننا القول أن مفسرّات جافا سكريبت الحديثة تستخدم تقنية تّدعى التصريف عند التنفيذ Just-in-time compiling لتحسين الأداء. إذ تُصرّف شيفرة جافا سكريبت المصدرية إلى شكل ثنائي أسرع في نفس الوقت الذي تُنفّذ فيه الشيفرة وهذا ما يجعل التنفيذ أسرع ما يمكن. مع ذلك لا تزال جافا سكريبت في عداد اللغات المفسّرة لأن التصريف يجري أثناء التنفيذ بدلًا من تصريف الشيفرة مسبقًا. ولكلا نوعي اللغات ميزاته، لكن لن نناقش هذا الموضوع الآن. شيفرة طرف العميل موازنة مع شيفرة طرف الخادم لربما سمعت أيضًا بمصطلحي "طرف الخادم server-side" و "طرف العميل client-side" وخاصة في سياق تعلم تطوير الويب. تُنفّذ شيفرة طرف العميل على حاسوب العميل أو المستخدم، فما يحدث عند استعراض صفحة الويب هو أن المتصفح سينزّل شيفرة طرف العميل ثم ينفذها ويعرضها. وما سنتحدث عنه في سلسلة مقالات جافا سكريبت هو استخدام جافا سكريبت من طرف العميل فقط. تُنفّذ شيفرة طرف الخادم بالمقابل على الخوادم ثم تُنزّل نتيجة التنفيذ وتُعرض في المتصفح. ومن لغات ويب التي تعمل من طرف الخادم نذكر PHP و Python و Ruby و ASP.NET وكذلك لغة جافا سكريبت. إذ يمكن استخدام جافا سكريبت كلغة برمجة من طرف الخادم في بيئة Node.js الشهيرة. الشيفرة الديناميكية موازنة مع الشيفرة الساكنة تُستخدم كلمة ديناميكي لوصف شيفرة جافا سكريبت من طرف العميل ولغات طرف الخادم، وتشير إلى إمكانية تحديث صفحة الويب أو التطبيق ليعرض أشياء مختلفة في ظروف مختلفة، وتوليد محتوى جديد حسب الحاجة. إذ توُلّد لغات طرف الخادم محتوى جديدًا على الخادم عن طريق سحب البيانات من قواعد البيانات مثلًا، بينما تولّد شيفرة جافا سكريبت المحتوى ديناميكيًا ضمن متصفّح العميل، كأن تنشأ جداول HTML وتملأها بالبيانات التي تطلبها من الخادم ومن ثم تعرض هذه الجداول ضمن صفحة الويب التي يراها المستخدم. قد يكون هناك اختلاف بسيط بين سياقي العمل لكنهما متعلقان ببعضهما، وكلا النهجين (طرف العميل وطرف الخادم) يعملان معًا عادة. عندما لا تُحدَّث صفحة الويب ديناميكيًا بمحتوى جديد ندعوها ساكنة static، فهي تعرض نفس المحتوى دائمًا. كيف تضيف شيفرة جافا سكريبت إلى صفحتك؟ تُضاف شيفرة جافا سكريبت إلى صفحة HTML بنفس الأسلوب الذي تُضاف به شيفرة CSS. إذ تستخدم CSS العنصر <link> لتطبيق ورقة تنسيق خارجية و العنصر <style> لتطبيق ورقة تنسيق داخلية على شيفرة HTML، بينما لا تحتاج جافا سكريبت سوى العنصر <script>. لنلق نظرة على عمله. شيفرة جافا سكريبت داخلية قبل كل شيء، أنشئ نسخة من الملف apply-javascript.html على جهازك وخزّنها في مكان مناسب. افتح الملف في متصفحك وضمن المحرر النصي في نفس الوقت. سترى أن شيفرة HTML قد أنشأت صفحة ويب بسيطة تضم زرًا يمكن النقر عليه. اضف الشيفرة التالية ضمن الترويسة في المحرر النصي وقبل وسم النهاية <head/>: <script> // JavaScript goes here </script> سنضيف الآن بعض شيفرة جافا سكريبت ضمن الوسم <script> وتحت عبارة "JavaScript goes here//" لنجعل الصفحة أكثر حيوية: document.addEventListener("DOMContentLoaded", () => { function createParagraph() { const para = document.createElement("p"); para.textContent = "You clicked the button!"; document.body.appendChild(para); } const buttons = document.querySelectorAll("button"); for (const button of buttons) { button.addEventListener("click", createParagraph); } }); احفظ الملف وحدّث المتصفّح، وستلاحظ ظهور فقرة نصية تحت الزر عند النقر عليه. ملاحظة: إن رأيت أن المثال لا يعمل كما هو مطلوب، راجع الخطوات السابقة بتأنٍ وتحقق أنك فعلت كل شيء بالشكل الصحيح. هل خزنت الملف بلاحقة html.؟ هل وضعت الوسم <script> قبل وسم النهاية <head/>؟ هل أدخلت شيفرة جافا سكريبت كما هي تمامًا؟ وانتبه إلى أن جافا سكريبت حساسة لحالة الأحرف وعليك إضافة الشيفرات كما هي تمامًا وإلا لن تعمل. شيفرة جافا سكريبت خارجية تعمل الشيفرة السابقة جيدًا، لكن ماذا لو أردت أن تضع تلك الشيفرة في ملف خارجي منفصل؟ أنشئ ملفًا جديدًا في نفس المكان الذي خزّنت فيه ملف HTML ثم سمّه script.js. تأكد أن لاحقة الملف هي js. لأنها الطريقة التي يُعرف بها ملف جافا سكريبت. استبدل الوسم <script> بالوسم التالي: <script src="script.js" defer></script> ضع الشيفرة التالية في ملف script.js: function createParagraph() { const para = document.createElement("p"); para.textContent = "You clicked the button!"; document.body.appendChild(para); } const buttons = document.querySelectorAll("button"); for (const button of buttons) { button.addEventListener("click", createParagraph); } احفظ الملف وحدّث المتصفّح وسترى الشيء ذاته، لكن شيفرة جافا سكريبت في هذه الحالة موجودة في ملف خارجي. وهذا عمومًا أمر جيد من ناحية تنظيم الشيفرة وجعلها قابلة للاستخدام ضمن جميع صفحات الموقع، إضافة إلى أن ملفات HTML أسهل قراءة في هذه الحالة دون وجود قطع من الشيفرة مزروعةً ضمنها. معالجات جافا سكريبت السطرية قد تصادف في بعض الحالات شيفرة جافا سكريبت ضمن شيفرة HTML، وسيبدو الأمر مشابهًا لما يلي: function createParagraph() { const para = document.createElement("p"); para.textContent = "You clicked the button!"; document.body.appendChild(para); } <button onclick="createParagraph()">Click me!</button> جرب هذه النسخة في المحرر التفاعلي: See the Pen javascript2 by Hsoub Academy (@HsoubAcademy) on CodePen. لهذه النسخة العمل ذاته كما في النسختين السابقتين، إلا أن العنصر <button> يضم معالجًا سطريًا هو onclick يفعّل عمل الدالة عند النقر على الزر. ننصحك بأن لا تفعل ذلك، فمن السيء أن تلوّث شيفرة HTML يشيفرة جافا سكريبت، إضافة إلى أنها طريقة غير فعّالة أن تضيف السمة "()onclick="createParagraph في كل زر تريده أن ينفّذ الوظيفة ذاتها. استخدام الدالة addEvenetListerer بدلًا من وضع شيفرة جافا سكريبت ضمن وسوم HTML، من الأفضل استخدام بناء جافا سكريبت صرف. إذ تسمح الدالة ()querySelectorAll بانتقاء كل أزرار الصفحة، ومن ثم إسناد معالج أحداث لكل زر من خلال الدالة ()addEventListener. إليك الشيفرة اللازمة: const buttons = document.querySelectorAll("button"); for (const button of buttons) { button.addEventListener("click", createParagraph); } قد تبدو الشيفرة أطول بقليل موازنة باستخدام السمة onclick، لكنها ستعمل مع جميع أزرار الصفحة مهما كان عددها أو مهما أضفت أو أزلت أزرارًا، دون الحاجة إلى تغيير شيفرة جافا سكريبت. ملاحظة: جرّب أن تعدّل في شيفرة الملف apply-javascript.html بإضافة بضعة أزرار إضافية، سترى عندها وبعد تحديث الصفحة أن النقر على أي زر منها سينشئ فقرة نصية. استراتيجيات تحميل السكربتات في صفحات الويب تصادفنا بعض المشاكل تتعلق بتوقيت تحميل السكربتات في صفحة الويب. فلا شيء بالبساطة التي يبدو عليها. ومن المشاكل الشائعة هي تحميل شيفرة HTML كاملة وبالترتيب الذي تظهر عليه ضمن الملف. فإن استخدمت جافا سكريبت للتعامل مع عناصر الصفحة (أو شجرة DOM بدقة)، لن تعمل الشيفرة إن حُّملت وفُسِّرت قبل أن يُحمّل عنصر HTML الذي تستهدفه. وما حدث في الأمثلة الماضية سواء باستخدام جافا سكربت داخليًا أو خارجيًا هو تحميل الشيفرة وتنفيذها ضمن ترويسة الملف وقبل تفسير أي عنصر من عناصر جسم الملف. قد ينتج عن هذا الأمر خطأ لهذا استخدمنا أسلوبًا للالتفاف حول المشكلة. لاحظ الأسلوب المستخدم في مثال الشيفرة الداخلية: document.addEventListener("DOMContentLoaded", () => { // … }); إن مترّصد الأحداث والذي يصغي إلى الحدث DOMContentLoaded في المتصفح، سينتظر اكتمال تحميل وتفسير جسم ملف HTML، ولن تعمل شيفرة جافا سكريبت ضمن هذه الكتلة قبل ذلك. وبهذه الطريقة نتفادى الخطأ. وفي مثال الشيفرة الخارجية، نستخدم ميزة أكثر حداثة لجافا سكريبت لحل المشكلة من خلال السمة defer التي تخبر المتصفح أن عليه إكمال تحميل شيفرة HTML عندما يصل إلى السمة <script>: <script src="script.js" defer></script> ستُحمّل شيفرة HTML و جافا سكريبت بالتوازي في هذه الحالة وستعمل الشيفرة جيدًا. ملاحظة: لا حاجة لاستخدام الحدث DOMContentLoaded في الشيفرة الخارجية لأن السمة defer تحل المشكلة. ولم نستخدم السمة defer في الشيفرة الداخلية لأنها تعمل فقط مع السكربت الخارجي. ومن الحلول القديمة التي استخدمت لحل لهذه المشكلة هو وضع شيفرة جافا سكريبت في نهاية الملف وقبل الموسم <body/> وبالتالي تُحمّل الشيفرة بعد إنتهاء تحميل وتفسير عناصر HTML. أما مشكلة هذا الحل هو إيقاف عمل شيفرة جافا سكريبت حتى يكتمل تحميل شجرة DOM الخاصة بملف HTML، وهذا ما يسبب مشكلة أداء كبيرة في مواقع الويب الأكبر، وسيبطئ الموقع. السمة async والسمة defer توجد في الواقع طريقتان عصريتان لتفادي مشكلة حجب الشيفرة باستخدام السمتين async و defer، وسنلقي نظرة عليهما. ستُحمّل السكربتات باستخدام async دون إيقاف تحميل الصفحة أثناء تقدم تحميل السكربت. لكن بمجرد اكتمال تحميل السكربت سيُنفَّذ هذا السكربت مما يمنع تصيير الصفحة، ولن تضمن بأي شكل تنفيذ السكربتات بترتيب محدد. ومن الأفضل استخدام هذه السمة عندما لا تتعلق السكربتات في الصفحة ببعضها البعض ولا بأي سكربت آخر في الصفحة. وبالنسبة للسكربتات التي تُحمّل باستخدام defer ستُحمّل بالترتيب الذي تظهر فيه ضمن الصفحة، ولن تعمل حتى يكتمل تحميل الصفحة، وهذا مفيد في السكربتات التي تتطلب اكتمال تكوين شجرة DOM الخاصة بالملف (وكمثال عليها السكربتات التي تعدّل عنصر أو أكثر في الصفحة). إليك تمثيلًا بصريًا لأساليب تحميل السكربتات وما الذي تعنيه لصفحتك: فلو كان لديك مثلًا عناصر <script> التالية: <script async src="js/vendor/jquery.js"></script> <script async src="js/script2.js"></script> <script async src="js/script3.js"></script> لا يمكنك الاعتماد على ترتيب تحميل العناصر السابقة، فقد يُحمّل jquery.js قبل أو بعد script2.js و script3.js، وإن حدث ذلك، ستوّلد أية دالة ضمن السكربتين الأخيرين خطأً إن اعتمدت على السكربت jquery لأنه قد لا يكون معرّفًا عند تنفيذها. لهذا استخدم السمة async إن كان لديك مجموعة من السكربتات التي تعمل في الخلفية وتريد فقط أن تضعها في مكانها المناسب بالسرعة الممكنة. فقد يكون لديك مثلًا ملفات بيانات خاصة بلعبة وتريدها أن تكون جاهزة عندما تبدأ اللعبة فعلًا، إذ لا بد من عرض مقدمة اللعبة وعناوينها والمساهمين فيها دون أن تُحجب حتى يُحمّل السكربت وأثناء ذلك يُحمّل السكربت بهدوء في الخلفية. وإن أردت تنفيذ السكربتات وفق تسلسل ظهورها (كما في الأسفل)، استخدم السمة defer، وستُنفَّذ حالما يُحمّل السكربت ومحتوى الصفحة: <script defer src="js/vendor/jquery.js"></script> <script defer src="js/script2.js"></script> <script defer src="js/script3.js"></script> نضمن في المثال الثاني أن jquery.js سيُحمّل قبل script2.js الذي يُحمّل قبل script3.js. ولن تُنفَّذ السكربتات حتى يكتمل تحميل الصفحة، وهذا أمر مفيد إن اعتمدت السكربتات على وجود شجرة DOM جاهزة وفي مكانها. باختصار: تخبر السمتان async و defer المتصفح أن يحمّل السكربتات في خيط منفصل بينما تحمّل بقية محتويات الصفحة في خيط مختلف في نفس الوقت وبالتالي لن يُحجب عرض محتوى الصفحة أثناء عملية إحضاره. تُنفّذ السكربتات التي تستخدم السمة async حالما ينتهي تحميلها، وسيحجب هذا عرض محتوى الصفحة أثناء التنفيذ ولا يمكن أن تضمن ترتيب السكربتات التي ستُنفَّذ. تُحمّل السكربتات التي تستخدم السمة defer بالترتيب الذي تظهر فيه وتُنفَّذ بمجرد انتهاء تحميل كل شيء. إن كان لابد من تنفيذ السكربت مباشرة بعد تحميله ولا يتعلق تنفيذه بسكربتات أو عناصر أخرى يفضّل استخدام async. إن كان لا بد من الانتظار حتى ينتهي تفسير الملف واعتمد السكربت على سكربتات أخرى أو على تكوين شجرة DOM الخاصة بالملف، استخدم defer وضع السكربتات (العناصر <script>) بالترتيب الذي تريده حتى يُنفذها المتصفح بنفس الترتيب. التعليقات في جافا سكريبت من الممكن كتابة تعليقات ضمن شيفرة جافا سكريبت كما هو الحال في HTML و CSS، وتُكتب هذه التعليقات لتزويد المطوّرين الذين يقرؤون الشيفرة (أو لك شخصيًا إن عدت إليها بعد فترة) بإرشادات عن طريقة عمل الشيفرة، وبالطبع يتجاهل المتصفح هذه التعليقات ولا يحللها. يُنصح باستخدام التعليقات ما أمكن فهي مفيدة وخاصة في التطبيقات الضخمة، وهنالك طريقتين لإدراج التعليقات: على شكل سطر وحيد بعد إشارتي شرطة أمامية //. // I am a comment أسطر متعددة مكتوبة بين النصين */ و /*. /* I am also a comment */ فمثلًا، يمكن إضافة التعليقات التالية إلى آخر مثال شرحناه: // Function: creates a new paragraph and appends it to the bottom of the HTML body. function createParagraph() { const para = document.createElement("p"); para.textContent = "You clicked the button!"; document.body.appendChild(para); } /* 1. Get references to all the buttons on the page in an array format. 2. Loop through all the buttons and add a click event listener to each one. When any button is pressed, the createParagraph() function will be run. */ const buttons = document.querySelectorAll("button"); for (const button of buttons) { button.addEventListener("click", createParagraph); } ملاحظة: كثرة التعليقات أفضل عادة من التعليقات القليلة، لكن انتبه إن رأيت نفسك تكتب تعليقات كثيرة لتشرح المتغيرات مثلًا (والتي يجب أن تكون واضحة وبديهية) أو لتشرح عمليات بسيطة (عندها قد تكون شيفرتك معقدة). خلاصة هكذا نكون قد خطونا أولى خطواتنا في جافا سكريبت. فقد بدأنا بتمهيد نظري لنمنحك فكرة عن استخدامات جافا سكريبت واﻷشياء التي يمكن أن تفعلها بها. كما رأينا خلال تقدم المقال بعض اﻷمثلة عن كتابة الشيفرة وتعلمنا كيف نضع الشيفرة في مكانها المناسب ضمن بقية شيفرة موقع الويب، إضافة إلى أشياء عديدة أخرى. قد تبدو جافا سكريبت صعبة قليلًا للوهلة الأولى، لكن لا تقلق فما نتعلمه في سلسلة المقالات التالية، سيأخذك خطوة خطوة وبأسلوب واضح حتى تصل إلى المرحلة التي تبني فيها أمثلتك الخاصة باستخدام جافا سكريبت ترجمة -وبتصرف- لمقال What's JavaScript اقرأ أيضًا تعلم لغة جافا سكريبت أساسيات لغة جافاسكربت تعلم جافا سكريبت من الصفر للاحتراف الدليل السريع إلى لغة البرمجة جافاسكريبت JavaScript
-
نراجع في هذا المقال بعض ميزات تخطيط الصفحات في CSS مثل القيم المختلفة للخاصية display وبعدها سنتعرف على بعض المفاهيم التي نغطيها تباعًا في سلسلة المقالات هذه، ونستعرض بإيجاز الخطوط العامة لتقنيات تخطيط الصفحات والتي نتوسع فيها مقالاتنا اللاحقة. عليك قبل البدء في قراءة هذا المقال أن: تطلع على أساسيات HTML كما شرحناها في سلسلة المقالات أساسيات HTML. تتفهم أساسيات CSS كما شرحناها في سلسلة المقالات خطواتك الأولى في CSS. تتيح لك تقنيات تخطيط الصفحات المعتمدة على CSS احتواء عناصر الصفحة والتحكم في موضعها بالنسبة إلى موقعها الافتراضي في الانسياب الاعتيادي أو التقليدي للعناصر أو بالنسبة إلى موضع بقية العناصر المحيطة بها أو بالنسبة إلى الحاوية الأم أو بالنسبة إلى نافذة العرض الأساسية أو نافذة المتصفح. وسنغطي في هذا المقال التقنيات التالية بشيء من التفصيل: الانسياب الاعتيادي للعناصر Normal flow الخاصية Display الصندوق المرن Flexbox تخطيط الشبكة Grid تعويم العناصر Floats توضيع العناصر Positioning تخطيط الجدول Table layout التخطيط متعدد الأعمدة Multiple-column layout لكل تقنية من هذه التقنيات استخداماتها وإيجابياتها وسلبياتها، ولم تصمم أي تقنية لتعمل بمفردها، وبالتالي حين تفهم سبب تصميم تخطيط معين ستمتلك القدرة على اتخاذ قرار استخدام التخطيط المناسب للمهمة التي تواجهك. الانسياب الاعتيادي لعناصر الصفحة وهو الأسلوب الذي يستخدمه المتصفح افتراضيًا في ترتيب العناصر في صفحات HTML عندما لا تتخذ أي خطوة لترتيب هذه العناصر. لنلق نظرة على المثال التالي: <p>I love my cat.</p> <ul> <li>Buy cat food</li> <li>Exercise</li> <li>Cheer up friend</li> </ul> <p>The end!</p> سيرتب المتصفح عناصر الصفحة السابقة افتراضيًا كالتالي: See the Pen css-layout-1 by Hsoub Academy (@HsoubAcademy) on CodePen. لاحظ كيف يعرض المتصفح عناصر HTML وفق ترتيب ظهورها في الشيفرة تمامًا ومتلاصقة عنصرًا فوق الآخر. إذ يعرض أولًا الفقرة النصية ثم القائمة غير المرتبة ومن ثم يعرض الفقرة النصية الثانية. تُدعى العناصر التي تُرتب فوق بعضها بالعناصر الكتلية block elements، بينما تُدعى العناصر التي تظهر إلى جانب بعضها في السطر ذاته -مثل الكلمات الموجودة في الفقرة- بالعناصر السطرية inline elements. ملاحظة: يُدعى الاتجاه الذي تُرتب فيه العناصر الكتلية (من الأعلى للأسفل في مثالنا) باتجاه الكتلة والذي قد يكون عموديًا في المحتوى المكتوب باللغة الإنكليزية أو العربية مثلً لأن اتجاه الكتابة فيها أفقي. كما يكون اتجاه الكتلة أفقيًا عندما يُكتب المحتوى بلغة تنساب حروفها من الأعلى للأسفل مثل اليابانية. أما الاتجاه السطري فهو اتجاه انسياب الكلمات في المحتوى. سيزود الانسياب الاعتيادي التخطيط المناسب للكثير من العناصر بالطريقة ضمن الصفحة، لكن ستحتاج في التخطيطات الأكثر تعقيدًا إلى تغيير هذا السلوك مستخدمًا بعض الأدوات التي تتيحها CSS. مع ذلك، عليك أن تبدأ من صفحة HTML مهيكلة جيدًا كي تكون قادرًا على التعامل مع الطريقة التي تُرتب فيها العناصر افتراضيًا بدلًا من معارضتها. تُستخدم الأساليب التالية في CSS لتغيير الترتيب الافتراضي للعناصر: الخاصية display: تغيّر القيم الأساسية لهذه الخاصية وهي block أو inline أو inline-block كيفية سلوك العناصر في الانسياب الاعتيادي، كأن يجعل عنصرًا كتليًا مثلًا يسلك سلوك عنصر سطري (نموذج الصندوق في CSS وستجد أيضًا أساليب كاملة للتخطيط تُفعّل عند اختيار قيم معينة للخاصية display مثل grid و flexbox أو التي تغيّر توضّع العنصر داخل العنصر الأب). التعويم floats: وذلك بتطبيق الخاصية، فاختيار القيمة left لهذه الخاصية مثلًا تدفع العناصر لتلتف نحو الجانب اليساري للعنصر كما في الصور التي يحاذيها نص إلى اليسار في مجلة. الخاصية position: تتيح لك هذه الخاصية ضبط موقع صندوق العنصر ضمن صناديق أخرى ضبطًا دقيقًا. يُعد الوضع static وضعًا افتراضيًا في الانسياب الاعتيادي، ومن الممكن أيضًا وضع العنصر بشكل مختلف باستخدام القيم الأخرى لهذه الخاصية، كأن يكون موقع العنصر ثابتًا أعلى المتصفح. تخطيط الجدول: يمكن استخدام الميزات التي تسمح بتنسيق جداول HTML مع العناصر الأخرى من خلال الخاصية display والقيمة table والخاصيات الأخرى المرتبطة بها. التخطيط متعدد الأعمدة: توضّع خاصيات الأعمدة -columns محتوى الكتلة ضمن أعمدة بشكل مشابه لما تراه في الصحف. الخاصية display تعتمد الأساليب الرئيسية في تخطيط الصفحات باستخدام CSS على استخدام قيم الخاصية display، إذ تسمح هذه القيم في تغيير الطريقة الافتراضية التي تُعرض بها الأشياء. ولكل عنصر قيمة افتراضية لهذه الخاصية في الانسياب الاعتيادي، أي الطريقة الاعتيادية التي يسلكها هذا العنصر. فعناصر الفقرة النصية <p> المكتوبة باللغة العربية مثلًا تتوضع فوق بعضها لأن التنسيق الافتراضي للعرض هو display: block. ولو أنشأت رابطًا ضمن فقرة نصية فسيبقى الرابط على نفس السطر مع بقية كلمات الفقرة ولن يقفز إلى السطر الثاني لأن التنسيق الافتراضي لعرض هذا العنصر هو display: inline. بالإمكان تغيير العرض التقليدي بتغيير قيم الخاصية display. فعنصر القائمة مثلًا <li> يسلك سلوك الكتلة افتراضيًا، أي تظهر هذه العناصر في المحتوى المكتوب بالعربية أو الانجليزية تحت بعضها. وعندما نضبط الخاصية display على inline، ستُعرض العناصر إلى جانب بعضها كفقرة نصية اعتيادية. تظهر أهمية هذه الطريقة في تغيير طريقة عرض أي عنصر من عناصر HTML دون المساس بدلالته (أي الغرض من استخدامه). بالإضافة إلى إمكانية تغيير طريقة عرض العناصر من كتلية إلى سطرية وبالعكس، ستجد الكثير من أساليب التخطيط التي تبدأ باستخدام الخاصية display. لكن ما يحدث عادة هو الحاجة إلى استخدام قيم أخرى لهذه الخاصية، وأكثرها أهمية في سياق مناقشتنا هما القيمتان display: flex و display: grid. مفهوم الصندوق المرن Flexbox يأتي مصطلح الصندوق المرن Flexbox كاسم مختصر لوحدة من وحدات CSS تُعرف بتخطيط الصندوق المرن Flexible Box Layout، وقد صممت هذه الوحدة لتسهيل ترتيب الأشياء في اتجاه واحد كأن تكون في صفٍ أو عمود. ولاستخدام الصندوق المرن لابد من تطبيق الخاصية display:flex على العنصر الأب الذي ترغب في ترتيب العناصر ضمنه بشكل مرن، وبالتالي ستصبح هذه العناصر مرنة. وسنرى ذلك في المثال البسيط التالي: ضبط قيمة الخاصية display على flex تعرض شيفرة HTML السابقة عنصرًا حاويًا <div> يمتلك صنف التنسيق wrapper ويضم داخله ثلاث عناصر من نفس النوع. ستُعرض هذه العناصر افتراضيًا كعناصر كتلية تحت بعضها البعض طالما أن لغة الكتابة سطرية مثل الإنكليزية في هذا المثال. لكن عند إضافة الخاصية display: flex إلى تنسيق العنصر الأب، سترتب العناصر نفسها على شكل أعمدة ثلاث، إذ تصبح هذه العناصر عناصر مرنة وتتأثر ببعض القيم الأساسية التي يطبقها الصندوق المرن على العنصر الأب. وقد ظهرت تلك العناصر ضمن سطر واحد وثلاث أعمدة لأن القيمة الأساسية للخاصية flex-direction في العنصر الأب هي row. وتمتد هذه العناصر أيضًا من ناحية الارتفاع لأن القيمة الأساسية للخاصية align-items للعنصر الأب هي stretch، أي أن العناصر تمتد بالاتجاه العمودي لتشغل ارتفاع العنصر الحاوي (العنصر الأب) والذي يحدده في هذه الحالة ارتفاع العنصر الأطول من بين العناصر الثلاث. تصطف العناصر إلى جانب بعضها بدءًا من طرف الحاوية وتترك أية مساحات فارغة لم يشغلها أي من هذه العناصر لتأتي بعدها وحتى نهاية السطر. .wrapper { display: flex; } <div class="wrapper"> <div class="box1">One</div> <div class="box2">Two</div> <div class="box3">Three</div> </div> سيرتب المتصفح عناصر الصفحة السابقة الآن كالتالي: See the Pen css-layout-2 by Hsoub Academy (@HsoubAcademy) on CodePen. ضبط خاصيات المرونة إضافة إلى الخاصيات التي يمكن تطبيقها على الحاوية المرنة، ستجد بعض الخاصيات التي يمكن تطبيقها على العناصر المرنة داخله أيضًا. يمكن لهذه الخاصيات بمشاركة أشياء أخرى أن تغيّر ترتيب العناصر المرنة كي تتمكن من التمدد والتقلص وفقًا للمساحة المتاحة لها. كمثال على ذلك، يمكن إضافة الخاصية flex إلى جميع الأبناء وإعطائها القيمة 1 مما يجعل العناصر تتمدد لتملأ العنصر الأب بدلًا من ترك مساحات فارغة في نهاية السطر. فإن كانت هناك مساحات إضافية ستغدو هذه العناصر أوسع وتتقلص إن لم تكن هناك مساحات كافية. وإن أضفت عناصر إضافية إلى الحاوية سيصغر حجم جميع العناصر لتوفر مكانًا للعنصر الجديد وستشغل العناصر كلها كامل مساحة الحاوية. .wrapper { display: flex; } .wrapper > div { flex: 1; } <div class="wrapper"> <div class="box1">One</div> <div class="box2">Two</div> <div class="box3">Three</div> </div> سنحصل على النتيجة التالية: See the Pen css-layout-3 by Hsoub Academy (@HsoubAcademy) on CodePen. ملاحظة: ما ذكرناه مقدمة مختصرة جدًا عما يمكن فعله في تخطيط الصندوق المرن وسنرى تفاصيل أوفى في مقال قادم. وكما صُمم تخطيط الصندوق المرن ليرتب العناصر باتجاه واحد، صُمم تخطيط الشبكة لترتيبها باتجاهين أي ضمن صفوف وأعمدة. ضبط الخاصية display على القيمة grid كما هو الحال في الصندوق المرن، نطبّق تخطيط الشبكة بإسناد القيمة الخاصة به إلى خاصية العرض display:grid. يستخدم المثال التالي نفس شيفرة HTML التي استخدمناها في المثال السابق. وإضافة إلى استخدام الخاصية display: grid، سنعرف بعض مسارات الصفوف والأعمدة في العنصر الأب باستخدام الخاصيتين grid-template-rows و grid-template-columns على التوالي. وقد عرفنا ثلاث أعمدة اتساع كل منها 1fr (جزء واحد من كل) وصفين ارتفاع كل منهما 100px. لا حاجة لوضع أي قواعد تنسيق للعناصر الأبناء لأنها تُرتب تلقائيًا ضمن الشبكة: .wrapper { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: 100px 100px; gap: 10px; } <div class="wrapper"> <div class="box1">One</div> <div class="box2">Two</div> <div class="box3">Three</div> <div class="box4">Four</div> <div class="box5">Five</div> <div class="box6">Six</div> </div> ستكون النتيجة كالتالي: See the Pen css-layout-4 by Hsoub Academy (@HsoubAcademy) on CodePen. وضع العناصر ضمن الشبكة بمجرد أن تبني الشبكة، ستتمكن من وضع عناصر أخرى ضمنها بشكل صريح بدلًا من الاعتماد على سلوك التوضع التلقائي. نعرّف في المثال التالي الشبكة نفسها التي عرفناها سابقًا، لكن بوجود ثلاث عناصر أبناء فقط. وضبطنا سطري البداية و النهاية باستخدام الخاصيتين grid-column و grid-row مما يجعل العنصر يمتد على عدة مسارات. .wrapper { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: 100px 100px; gap: 10px; } .box1 { grid-column: 2 / 4; grid-row: 1; } .box2 { grid-column: 1; grid-row: 1 / 3; } .box3 { grid-row: 2; grid-column: 3; } <div class="wrapper"> <div class="box1">One</div> <div class="box2">Two</div> <div class="box3">Three</div> </div> ستظهر النتيجة على هذا النحو: See the Pen css-layout-4 by Hsoub Academy (@HsoubAcademy) on CodePen. ملاحظة: يعرض المثالان السابقان فكرة بسيطة عن قوة تخطيط الشبكة، وسنفصل أكثر في مقال قادم. لنتابع في بقية هذا المقال بعض التخطيطات الأخرى الأقل أهمية كتخطيطات رئيسية لصفحة الويب، لكنها مفيدة في مهام أخرى. وستجد عند فهم طبيعة المهام التي يؤديها كل تخطيط أن التخطيط الملائم لمكوّن معين من صفحتك سيكون واضحًا أغلب الأحيان. تعويم العنصر: الخاصية float يغير تعويم العنصر سلوكه وعناصر الكتلة الأخرى التي تأتي بعده في الانسياب الاعتيادي. تتوضع العناصر المعومة إلى اليمين أو اليسار وتُنقل من مكانها ثم يعوم حولها بقية المحتوى. للخاصية القيم التالية: left: تعويم العنصر إلى اليسار. right: تعويم العنصر إلى اليمين. none: لا تسمح بتعويم العنصر وهي القيمة الافتراضية. inherit: قيمة الخاصية float للعنصر هي نفسها قيم هذه الخاصية في العنصر الأب. نعوّم في المثال التالي عنصر <div> إلى اليسار ونحدد له هامشًا margin نحو اليمين لدفع المحتوى المحيط به قليلًا. يعطينا هذا التنسيق تأثير التفاف النص حول صندوق العنصر المعوّم، وهذا أهم ما تريد معرفته عن التعويم كما يُستخدم في تصميم الويب المعاصر. <h1>Simple float example</h1> <div class="box">Float</div> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci vel, viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare ex malesuada et. In vitae convallis lacus. Aliquam erat volutpat. Suspendisse ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis ornare egestas augue ut luctus. Proin blandit quam nec lacus varius commodo et a urna. Ut id ornare felis, eget fermentum sapien. </p> .box { float: left; width: 150px; height: 150px; margin-right: 30px; } ستظهر النتيجة على هذا النحو: See the Pen css-layout-5 by Hsoub Academy (@HsoubAcademy) on CodePen. ملاحظة: سنشرح التعويم بشكل كامل في مقال لاحق عن خاصيات التعويم. فقد استخدم تلك الخاصيات قبل ظهور تقنيات الصندوق المرن والشبكة لإنشاء تخطيطات متعددة الأعمدة. وقد تصادف هذه التخطيطات في بعض مواقع الويب لهذا سنغطيها أيضًا في مقال مستقل. تقنيات ضبط موقع العنصر تساعدك هذه التقنيات في نقل عنصر من المكان الذي ينبغي أن يحتله ضمن الانسياب الاعتيادي للعناصر إلى مكان آخر. ولا يُعد تموضع العنصر أسلوبًا في إنشاء تخطيطات رئيسية للصفحة، بل هو أقرب إلى ترتيب وضبط الموقع المخصص لكل عنصر في الصفحة بدقة. لكنك ستجد تقنيات مفيدة للحصول على أنماط تخطيط مخصصة تعتمد على استخدام الخاصية position. إن فهم فكرة التموضع ستساعدك على فهم الانسياب الاعتيادي للعناصر، وما الذي يعنيه نقل العنصر خارج هذا الانسياب. يوجد عمومًا خمسة أنواع تجدر معرفتها لتموضع العناصر: التوضع الساكن Static positioning: وهو الوضع الافتراضي لجميع العناصر، ويعني ببساطة وضع العنصر في مكانه الاعتيادي ضمن تخطيط الصفحة. التوضع النسبي Relative positioning: يساعدك على تعديل موقع عنصر في الصفحة وذلك بنقله بالنسبة إلى مكانه الاعتيادي، إضافة إلى جعله فوق عناصر أخرى في الصفحة Overlapping. التوضع المطلق Absolute positioning: يُخرج العنصر تمامًا من الانسياب العتيادي وكأنه يقع ضمن طبقة خاصة به. وبهذه الطريقة ستتمكن من تثبيت العنصر بالنسبة إلى حواف أقرب عنصر أب ثابت الموقع (وإن لم يكن هناك واحد سيكون هذا العنصر بالطبع <html>). لهذا الوضع أهميته في إنشاء تخطيطات معقدة مثل الصناديق متعددة النوافذ التي تتراكب فيها نوافذ المحتوى فوق بعضها لتُعرض وتختفي عند الطلب، أو لوحات المعلومات التي تضبط لتكون خارج الشاشة ثم تظهر إلى جانب الصفحة بالنقر على زر تحكم مخصص. التوضع الثابت Fixed positioning: يشابه الوضع المطلق إلا أنه يُثبِّت موضع العنصر بالنسبة إلى نافذة عرض المتصفح وليس لموقع عنصر آخر. لهذا الوضع فائدته في إنشاء تأثيرات هامة مثل قوائم التنقل التي تبقى دائمًا في نفس المكان على الشاشة بينما يكون المحتوى متحركًا عند تمرير الصفحة. التوضع اللاصق Sticky positioning: طريقة جديدة لتوضيع العناصر تجعلها تتصرف وكأنها في الوضع النسبي position: relative حتى تصل إلى حد معين بالنسبة لنافذة العرض عنها تتصرف وكأنها في الوضع الثابت position: fixed. مثال بسيط عن تموضع العناصر كي نألف العمل مع تقنيات التخطيط السابقة، سنعرض مثالين سريعين لكل منهما بنية HTML نفسها (ترويسة تليها ثلاثة فقرات نصية) كالتالي: <h1>Positioning</h1> <p>I am a basic block level element.</p> <p class="positioned">I am a basic block level element.</p> <p>I am a basic block level element.</p> تُنسق شيفرة HTML افتراضيًا باستخدام شيفرة CSS التالية: body { width: 500px; margin: 0 auto; } p { background-color: rgb(207, 232, 220); border: 2px solid rgb(79, 185, 227); padding: 10px; margin: 10px; border-radius: 5px; } إليك خرج الشيفرة السابقة على المتصفح: See the Pen css-layout-6 by Hsoub Academy (@HsoubAcademy) on CodePen. التموضع النسبي: يتيح لنا التوضع النسبي إزاحة العنصر خارج نطاق الانسياب الاعتيادي، بمعنى إمكانية إنجاز مهام مثل تحريك أيقونة قليلًا لتحاذي نص أو عنوان. لفعل ذلك، بالإمكان تطبيق قواعد التنسيق التالية: .positioned { position: relative; top: 30px; left: 30px; } أعطينا في شيفرة التنسيق السابقة القيمة relative للخاصية position العائدة إلى الفقرة الموجودة في الوسط. بالطبع لن يظهر تأثير ذلك قبل أن نضبط أيضًا قيمًا للخاصيتين top و left، إذ تجعلان العنصر ينزاح إلى الأسفل واليمين. قد ترى أن ما حدث هو عكس ما تتوقعه، لكن فكر بالموضوع على أنك دفعت العنصر من جانبيه العلوي واليساري وبالتالي ستكون النتيجة انزياحه نحو الأسفل واليمين. إليك نتيجة الشيفرة السابقة: See the Pen css-layout-7 by Hsoub Academy (@HsoubAcademy) on CodePen. التموضع المطلق ويستخدم لإخراج العنصر كليًا من مجرى الانسياب الاعتيادي، وإعادة توضيعه بإزاحته مقدارًا محددًا عن حواف الكتلة التي تحتويه. بالعودة إلى مثالنا السابق (دون تطبيق التوضع)، سنضيف قواعد التنسيق التالية لإنجاز التوضع المطلق: .positioned { position: absolute; top: 30px; left: 30px; } أعطينا في شيفرة التنسيق السابقة القيمة absolute للخاصية position العائدة إلى الفقرة الموجودة في الوسط، واستخدمنا الخاصيتين top و left كما سبق. إليك النتيجة: See the Pen css-layout-8 by Hsoub Academy (@HsoubAcademy) on CodePen. كما ترى، الأمر مختلف تمامًا هذه المرة! لقد انفصل العنصر بالكامل عن تخطيط الصفحة وبقي أعلاها، بينما بقيت الفقرتين النصيتين الأخريين في مكانهما دون أن تتأثرا بموقع الفقرة التي غيرنا أسلوب توضعها. وكذلك نجد اختلاف تأثير الخاصيتين top و left على الموقع في حالتي التوضع النسبي والمطلق. إذ تُحسب الإزاحة في حالة التوضع المطلق بالنسبة لأعلى ويسار الصفحة. التموضع الثابت يزيل التموضع الساكن العنصر من مجرى الانسياب الاعتيادي كما يفعل التوضع المطلق، لكن الإزاحة ستُطبق في هذه الحالة بالنسبة غلى نافذة العرض وليس بالنسبة إلى العنصر الأب (الكتلة الحاوية). وطالما أن العنصر يبقى ثابتًا بالنسبة إلى نافذة العرض، يمكن استخدام هذا التموضع لإحداث تأثيرات مميزة كالقوائم التي تبقى في مكانها عند تمرير محتوى الصفحة. وكمثال عن هذا التوضع، نجد شيفرة HTML تضم ثلاث فقرات نصية يسبقها صندوق <div> نضبط خاصية position له على القيمة fixed. <h1>Fixed positioning</h1> <div class="positioned">Fixed</div> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. </p> <p> Cras porttitor imperdiet nunc, at ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci vel, viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare ex malesuada et. </p> <p> In vitae convallis lacus. Aliquam erat volutpat. Suspendisse ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis ornare egestas augue ut luctus. Proin blandit quam nec lacus varius commodo et a urna. Ut id ornare felis, eget fermentum sapien. </p> .positioned { position: fixed; top: 30px; left: 30px; } وهذه النتيجة: See the Pen css-layout-9 by Hsoub Academy (@HsoubAcademy) on CodePen. التموضع اللاصق وهي الأسلوب الأخير الذي نناقشه فيما يخص التوضّع. تمزج هذه القيمة بين التوضع النسبي والتوضع الثابت، فعندما نُطبق القاعدة position: sticky على عنصر سيتحرك مع المحتوى عند تمريره حتى يصل إلى إزاحة محددة سلفًا بالنسبة لنافذة العرض وعندها يبقى في هذا الموقع كما لو طبقنا القاعدة position: fixed. .positioned { position: sticky; top: 30px; left: 30px; } النتيجة: See the Pen css-layout-10 by Hsoub Academy (@HsoubAcademy) on CodePen. تخطيط الجدول تُعد جداول HTML طريقة جيدة في عرض البيانات القابلة للجدولة، لكنها استُخدمت قبل سنوات عدة -حين لم تكن CSS مدعومة جيدًا من قبل المتصفحات- من قبل المطورين لتخطيط صفحة ويب بأكملها. إذ استخدمت أسطر وأعمدة الجدول لاحتواء ترويسة الصفحة وتذييلها وأعمدتها، ونفع الأمر حينها مع وجود مشاكل جدية تتعلق بمرونة الجداول وكم الشيفرة الكبير اللازم لصياغتها وصعوبة تنقيحها، ناهيك عن الأخطاء الدلالية في استخدامها، فهي دلاليًا غير مخصصة لاحتواء عناصر أخرى بل لعرض البيانات وبالتالي ستجد قارئات الشاشة صعوبة في تتبع تخطيطات الجداول. تُعرض جداول HTML ضمن صفحة الويب وفقًا لمجموعة من خاصيات CSS تُعرّف تخطيط الجدول، ويمكن استخدام نفس تلك الخاصيات لترتيب عناصر أخرى غير الجداول بطريقة تُوصف أحيانًا بجداول CSS. يعرض المثال القادم هذا النمط من الاستخدام، وتجدر الملاحظة هنا أن استخدام تخطيط جداول CSS يُعد طريقة قديمة حاليًا، ولا يجب استخدامه إلا لدعم المتصفحات الأقدم التي لا تدعم تخطيط الشبكة أو الصندوق المرن. لنلق نظرة على مثالنا المكون من توصيف بسيط لنموذج HTML لكل عنصر إدخال فيه عنوان، كما وضعنا عنوانًا ضمن فقرة نصية، وغلفنا كل زوج (عنصر إدخال/ عنوان) ضمن عنصر <div> لتنسيق التخطيط. <form> <p>First of all, tell us your name and age.</p> <div> <label for="fname">First name:</label> <input type="text" id="fname" /> </div> <div> <label for="lname">Last name:</label> <input type="text" id="lname" /> </div> <div> <label for="age">Age:</label> <input type="text" id="age" /> </div> </form> بالنسبة لشيفرة CSS فمعظمها معروفة ماعدا استخدام الخاصية display. إذ ضبطت طريقة عرض العناصر <form> و <div> و <label> و <input> لتظهر على شكل جدول وصفوف في جدول وخلايا على الترتيب. ستظهر كل العناصر مبدئيًا كما لو أنها ضمن جدول معياري مما يجعل العناوين وعناصر الدخل على نفس السوية تلقائيًا. كل ما علينا فعله بعد ذلك تغيير الأبعاد قليلًا وضبط الهوامش وغير ذلك ليبدو مظهر العناصر أفضل. لاحظ كيف طبقنا قاعدة التنسيق ;display: table-caption على الفقرة النصية التي تمثل العنوان لتبدو وكأنها عنوان جدول، وكذلك القاعدة ;caption-side: bottom كي يظهر عنوان الجدول في الأسفل لأجل التنسيق فقط حتى لو كانت الفقرة قبل عناصر الإدخال <input> في الشيفرة المصدرية. html { font-family: sans-serif; } form { display: table; margin: 0 auto; } form div { display: table-row; } form label, form input { display: table-cell; margin-bottom: 10px; } form label { width: 200px; padding-right: 5%; text-align: right; } form input { width: 300px; } form p { display: table-caption; caption-side: bottom; width: 300px; color: #999; font-style: italic; } إليك نتيجة الشيفرة السابقة: See the Pen css-layout-11 by Hsoub Academy (@HsoubAcademy) on CodePen. ملاحظة: لن يُغطي موضوع تخطيط الجدول أكثر كونه تقنية تخطيط قديمة. التخطيط متعدد الجداول تزودنا وحدة التخطيط متعدد الجداول في CSS بآلية لترتيب المحتوى ضمن أعمدة كما تُكتب الأعمدة في صحيفة. وعلى الرغم من أن قراءة الأعمدة أقل فائدة في صفحات ويب لأن الزائر يُضطر إلى تمرير المحتوى إلى الأعلى والأسفل باستمرار، لكن تقنية ترتيب المحتوى ضمن أعمدة تبقى مهمة بحد ذاتها. ولكي نحول كتلة إلى حاوية متعددة الأعمدة، نستخدم الخاصية column-count التي تخبر المتصفح كم عدد الأعمدة التي نحتاجها أو الخاصية column-width التي تخبر المتصفح أن يملأ الحاوية بأكبر عدد ممكن من الأعمدة ذات الاتساع المحدد. نبدأ في مثالنا التالي بشيفرة HTML ضمن عنصر الحاوية <div> الذي يمتلك الصنف container. <div class="container"> <h1>Multi-column Layout</h1> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta. </p> <p> Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada ultrices. Phasellus turpis est, posuere sit amet dapibus ut, facilisis sed est. Nam id risus quis ante semper consectetur eget aliquam lorem. </p> <p> Vivamus tristique elit dolor, sed pretium metus suscipit vel. Mauris ultricies lectus sed lobortis finibus. Vivamus eu urna eget velit cursus viverra quis vestibulum sem. Aliquam tincidunt eget purus in interdum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. </p> </div> أسندنا القيمة 200px للخاصية column-width كي ندفع المتصفح إلى إنشاء أكبر عدد ممكن من الأعمدة ذات الاتساع 200 بكسل ضمن الحاوية، وسيجري تقاسم أية مساحات فارغة زائدة بين الأعمدة. .container { column-width: 200px; } وإليك نتيجة الكود السابق: See the Pen css-layout-12 by Hsoub Academy (@HsoubAcademy) on CodePen. الخلاصة ناقشنا في هذا المقال جميع تقنيات تخطيط صفحات الويب التي يجدر معرفتها بصورة موجزة، وسنتابع الحديث عن هذه التقنيات بالتفصيل وحالات استخدامها المختلفة مقالات أخرى. ترجمة -وبتصرف- للمقال: Introduction to CSS layout اقرأ أيضًا استخدام خطوط الكتابة في الويب مع CSS تعرف على أساسيات لغة CSS التحكم في تخطيط الصفحة وضبط محاذاة العناصر في CSS وحدات القياس والقيم في CSS
-
أظهرت الاستقالات الفردية الضخمة التي بدأت في 2021، وخاصةً في الولايات المتحدة أنّ عددًا لا بأس به من الموظفين قد تركوا أعمالهم لأنها غير مناسبة، فما الذي قاد هذا التغير في السلوك؟ لقد تركوا عملهم بحثًا عن فرص أخرى تحمل تحديًا وقيمةً وحماسًا أكبر. سنلقي نظرةً في هذا المقال على أهمية رغبة الموظف وحماسه لعمله، وكيف يؤثر ذلك على بقاء الموظف في منصبه، والخطوات التي قد تتبعها الشركات لتحسين انخراط الموظفين بفعالية في أعمالهم. أهمية المشاركة الفعالة للموظف في عمله وعلاقتها باستمرارية عمله يترابط مفهوما المشاركة في العمل والمحافظة على الموظفين، فالموظفون المتحمسون لأعمالهم أكثر التزامًا بالعمل وبالفريق وبالشركة مقارنةً بغيرهم؛ إذ يشعر هؤلاء بالرضا والسعادة في عملهم ويستمتعون بما يقدمونه مع شعور بالتقدير، لهذا فمن غير المحتمل أن يتخلوا عن شركتهم. تعرف الشركات التي موظفوها راضون بأعمالهم أنّ تحسين انخراط الموظفين في العمل لا يتم بمبادرة واحدة، فالأعمال التي تستقطب أفضل المواهب وينخفض فيها معدل ترك الموظفين لأعمالهم تتفهم جيدًا أنّ سعادة فريق العمل ورضاه ومشاركته بفعالية بما يُسند إليهم من مهام لا بدّ وأن تكون في أولوياتها وجزءًا من ثقافتها. لنلق الآن نظرةً أعمق إلى العلاقة بين انخراط الموظفين الفعّال بأعمالهم والمحافظة على المتحمسين منهم ضمن قوام الشركة باستكشاف الطرق المضمونة لتنفيذ الأمر. هل يقل احتمال ترك الموظف لعمله إن كان متحمسا له؟ استنادًا إلى بعض الدراسات التي أجراها موقع Gallup، فإنّ الشركات التي ينخرط فيها أكثر من 75% من موظفيها في أعمالهم بحماس، تنخفض فيها نسبة ترك العمل بمقدار 43% مقارنةً بالشركات التي تقل نسبة الموظفين المتحمسين لعملهم عن 25%. وبكلمات أخرى، سيقل احتمال استقالة الموظفين كثيرًا في الشركات التي تعي أهمية حماسة موظفيها لأعمالهم وترسخ ذلك في ثقافتها مقارنةً بتلك التي لا تولي أهميةً لحماسة موظفيها. هل تزداد إنتاجية الموظفين المتحمسين لوظائفهم؟ نعم، سينجز الموظف المتحمس لعمله أكثر مما ينجزه غيره. واستنادًا إلى تقرير نفس الموقع عن حالة مواقع العمل عالميًا لعام 2021، يكلّف الموظفون الأقل حماسًا للمشاركة في العمل شركاتهم 18% من الكتلة المخصصة سنويًا للمرتبات على إنتاجية ضائعة. وبطبيعة الحال، تزيد الإنتاجية المرتفعة من نجاح الأعمال. هل تزداد سعادة الموظفين الأكثر حماسا لعملهم؟ يختلف مفهومي الموظف السعيد والموظف المتحمس للعمل لكنهما يتبادلان التأثير، فالموظف المتحمس لعمله تعريفًا هو الموظف الذي يتابع عمله يوميًا ويعتقد بأنّ عمله يتطلب التحدي ويشعر بقيمة ما يفعله؛ فهم يحبون ما يفعلونه ويشعرون بأنّ هذا العمل يلائم مهاراتهم جيدًا وأنّ لهم مكانتهم في الفريق والشركة. تترجم هذه الميزات إلى مستوىً أعلى من الرضا ويمنح الموظف تجربةً أغنى وهدفًا من وراء ما يفعله، وهذه المشاعر هي دافع حقيقي نحو السعادة. كيف تقيس مدى حماسة الموظف وانخراطه في عمله؟ لا بدّ من تكامل الجهود لتحسين انخراط الموظفين في أعمالهم على مستوى المديرين وفريق العمل والشركة ككل إن أرادت الحفاظ على أفضل الموظفين لديها، لكن الأمر صعب خاصةً إن لم تعِ بوضوح من أين تبدأ وأين ستصل. قياس مدى حماسة موظفيك للعمل ضرورة ملحة: يمكن أن يساعد ذلك المديرين على تجميع بيانات ومعلومات وأفكار قد يحتاجونها لفهم ما ينفع وما لا ينفع، وما الذي ينبغي فعله للتطوير. هنالك العديد من المؤشرات التي يمكن تحديدها منها: استطلاعات جس النبض قد يصعب فهم التجربة التي يعيشها موظفوك، لهذا تُعدّ استطلاعات جس النبض المنتظمة مهمةً في متابعة نبض الأحداث التي تدور في شركتك. ستساعدك هذه الاستطلاعات على تحديد ما يدفع الموظفين إلى الحماسة في العمل، وما يبعدهم عن الانخراط بفعالية؛ ومن ثم اتخاذ التدابير اللازمة لتحسين ذلك (وبالتالي المحافظة على موظفيك في المحصلة). وهذا الاستطلاع شديد الفائدة للمديرين الذي يقودون فرقًا موزّعة. اللقاء وجها إلى وجه تنحصر المسؤولية في معرفة مدى حماس الموظف أو إهماله لعمله على المدير وحده، ومن هنا تظهر أهمية اللقاءات الفردية وجهًا لوجه وبانتظام، إذ تصنع هذه اللقاءات مساحةً للموظف كي يتحدث عن تجربته مع مديريه ويتشارك معهم الرؤى حول ما يحفزه خصوصًا وما يحبطه، ليستفيد منها المديرون في تحسين خبراتهم ويقود إلى مستوى أعلى من الانخراط في العمل. لقاءات ترك الخدمة إن قرر موظفك ترك العمل وتقديم استقالته، فمن الجيد عندها أن تستغل الفرصة لتعرف السبب الكامن وراء قراره، وما الذي يمكن للشركة فعله لزيادة حماس موظفيها لعملهم. حاول أن تركز في هذه اللقاءات على حماسة الموظف وانخراطه في العمل؛ وخاصةً على السبب الذي يبعد الموظف عن واجباته أو يشعره بذلك. لقاءات العمل المستمرة وهي وسيلة لمواجهة انسحاب الموظفين من شركتك. تساعدك هذه اللقاءات مع موظفيك الحاليين على فهم الأسباب التي قد تدفع الموظف للبقاء أو الرحيل (لتفادي لقاءات ترك الخدمة لاحقًا). ومن أبرز منافع هذه اللقاءات هي المعلومات التي تقدمها لك كي تنجز استراتيجية ناجحة ترفع معدل الاحتفاظ بالموظفين وتلبي حاجاتهم. إن حماسة الموظفين للعمل الذي يُسند إليهم أمر أساسي، خاصةً في مسألة بقائهم أو رحيلهم. وقياس الانخراط في العمل هو الاستراتيجية الأنسب في جمع المعلومات التي تحتاجها لبناء موقع عمل يجذب الموظفين للاستمرار في العمل. أربع استراتيجيات قيادية لزيادة انخراط الموظفين في أعمالهم باختصار، إن أردت المحافظة على المواهب ضمن شركتك، اجعل اندفاع الموظفين إلى العمل في أعلى قائمة أولوياتك وامنحه معناه الحقيقي، فاتخاذ خطوات فعالة في تحسين انخراط الموظفين في العمل سيؤثر جدًا على احتمال استمرارهم في العمل لديك. وفقًا لموقع Gallup مثلًا، سنجد أن: إذًا، كيف ستفعل ذلك بالضبط؟ لنلق نظرةً على أربع استراتيجيات يمكن للقادة اتباعها لزيادة انخراط الموظفين في نشاط الشركة وزيادة رضاهم وتقليل عدد حالات ترك العمل. افسح المجال للمناقشة حول الانخراط في العمل قد تعتقد بأنك تعرف ما عليك فعله لزيادة حماس موظفيك، وذلك من وجهة نظرك بصفتك قائد؛ لكن إن أردت أن تعرف تمامًا ما يلزم لبناء موقع عمل أكثر تحفيزًا، فعليك أن تسأل موظفيك. إن حل أي مسألة بانفتاح وإفساح المجال للحوار الصريح مع الفريق بما في ذلك جلسات العصف الذهني لخلق مبادرات أكثر إبداعًا، والحوارات الشخصية وجهًا لوجه مع أعضاء الفريق حول ما يعزز الانخراط في العمل، هو الأسلوب الأنجع في دعم الموظفين. كما أنّ خلق همساحات للنقاش الجماعي مع الفريق أو الفردي أمر أساسي، فقد تدير مثلًا جلسة عصف ذهني تطلب فيها رأي الفريق عما يمكن للإدارة فعله لتحسين اندفاعهم نحو إنجاز العمل، ثم ترتب بعد ذلك جلسات نقاش فردية لتقف على تفاصيل أعمق من كل فرد من أفراد الفريق على حدة. موظفوك في النهاية هم من سيندفع إلى العمل بنشاط أو يتخاذل، لهذا عليك أن تسألهم رأيهم في إنجاز الأمر إن أردت أن تميل الكفة إلى صالح شركتك. الإشادة بالموظفين سيكون للإشادة البسيطة بالموظف أثر طويل الأمد على مستوى انخراطه في أداء عمله. ووفقًا لموقع McKinsey، فقد ترفع الشركات نسبة الانخراط في العمل بواقع 55% إن لم تغفل حاجة الموظف لتلقي الثناء في الموقع الذي يعمل به. ابحث عن سبل تثني من خلالها على موظفيك إن أردت تعزيز انخراطهم في العمل، وإليك بعض الأمثلة: إن كنت تعقد اجتماعًا أو مراجعة لمشروع سيكون فريق العمل مكتملًا، فابدأ الاجتماع بالإشادة بالمساهمة الخاصة التي قدمها كل عضو من أعضاء الفريق لنجاح هذا المشروع. إذا أدى أحد أعضاء الفريق عملًا يفوق ما هو مطلوب منه، فتأكد من أن تشيد بجهوده وأن تعبر عن امتنانك لما أنجزه. وإن كنت ستفعل ذلك، فاحرص على أن يكون الأمر على مرأى أو مسمع أحد مديريه أو قادته. إن شعرت بأن أحد موظفيك قد أُرهق من العمل، فيمكنك أن تحدثه جانبًا مشيدًا بقدرته على الاطلاع بعدة مسؤوليات في الوقت ذاته واسأله إن كان بإمكانك فعل أي شيء للتخفيف من أعبائه. أظهر لهم أهمية ما ينجزون أن يلمس الموظف أهمية ما ينجزه هو أمر أساسي يدفعه نحو مزيد من الحماسة والانخراط في عمله. ووفقًا لاستطلاع رأي نفذه موقع "McKinsey"، فقد تشهد الشركات ارتفاعًا في نسبة انخراط العاملين يقارب 49% عندما تتماشى قيم الشركة مع الغايات الفردية للموظفين. أظهر لموظفيك كيف ولماذا يشكل ما ينجزون من أعمال جزءًا مفصليًا من مسيرة نجاح الشركة؛ فعندما تطلق مثلًا مشروعًا جديدًا، فلا تبدأه بتوزيع الأدوار والواجبات مباشرةً، بل تحدث عن أهمية المشروع وأثره على الشركة بكل من فيها، واشرح أهمية كل دور سيؤديه فريق العمل في تحقيق الأهداف طويلة الأجل للشركة. أو إن واجه بعض الموظفين الجدد صعوبةً في التعامل مع واجباتهم الجديدة، فخصص لهم وقتًا لتشرح لهم رؤية شركتك وأهدافها وقيمها وكيف سيساهم العمل من مواقعهم في دعم قيم وأهداف الشركة. استخدم برمجيات مناسبة للمساعدة في قياس مؤشرات حماسة الموظفين لأعمالهم إنّ الإبقاء على المواهب في الشركة أمر جوهري، والمحافظة على الموظفين المتميزين أساس سوق العمل وينبغي أن تضع الأعمال تعزيز انخراط الموظفين في أعمالهم في أعلى قائمة الأولويات؛ لهذا إن أردت الإبقاء على مستويات الانخراط مرتفعة، فلا بدّ من قياسها باستمرار وبفعالية، وهنا يُنصح باستخدام بعض البرمجيات المخصصة لذلك، مثل بعض البرمجيات التي تتيح لك إمكانية قياس العديد من مؤشرات انخراط موظفيك في العمل، واستطلاع رأي موظفيك وتحديد مستوى حماسهم، ويعطيك بيانات لاستخدامها في خلق قوة عاملة أكثر التزامًا بالعمل، وبالتالي شركةً أكثر نجاحًا. ترجمة -وبتصرف- للمقال The importance of employee engagement and retention for the future of work لصاحبته Rachel Steben. اقرأ أيضًا الفرق بين دوران الموظفين والاحتفاظ بهم مقابلة البقاء وسبب إجرائها أفكار فعالة لتحفيز الموظفين في الظروف الصعبة
-
سنعمل في هذا المقال على بناء كاميرا لشاشة لمس في محرك الألعاب جودو كي يتمكن اللاعب من تحريك الكاميرا حول محورها وتكبير وتصغير وتدوير الكاميرا عن طريق اللمس. تهيئة الكاميرا ثنائية البعد افتح محرك الألعاب جودو وأنشئ مشروعك الأول، وابدأ بعقدة من النوع CameraD2، ولجعلها حساسة للمس، سنضيف سكريبت يدير العملية، وذلك بالنقر عليها بالزر الأيمن للفأرة ثم اختيار "إلحاق نص برمجي attach script" ولنسمّه "TouchCameraController.gd". ملاحظة أضفنا أيقونة إلى المشهد لكي نرى الكائن الذي يتحرك. إعداد الكاميرا نحتاج بداية إلى مجموعة من المتغيرات للتحكم بالكاميرا التي تمثلها في جودو العقدة Camera2D. تمثل هذه المتغيرات سرعة الحركة المحورية وسرعة التكبير والتصغير، وسرعة الدوران، وأخرى للتحكم في إمكانية التحريك أو التكبير أو التدوير. وإضافة إلى ذلك، ننشئ متغيرات لتخزين حالة الكاميرا ومدخلات اللمس. إليك طريقة تعريف المتغيرات: extends Camera2D @export var zoom_speed: float = 0.1 @export var pan_speed: float = 1.0 @export var rotation_speed: float = 1.0 @export var can_pan: bool @export var can_zoom: bool @export var can_rotate: bool var start_zoom: Vector2 var start_dist: float var touch_points: Dictionary = {} var start_angle: float var current_angle: float قمنا في البداية بتوسيع الصنف Camera2D في Godot الذي يمثل كاميرا ثنائية الأبعاد 2D في جودو ثم حددنا مجموعة المتغيرات التي يمكن تعديلها وهي: zoom_speed: قيمة عددية تحدد سرعة عملية التكبير والتصغير للكاميرا. pan_speed: قيمة عددية تحدد سرعة عملية التحريك الجانبي للكاميرا. rotation_speed: قيمة عددية تحدد سرعة عملية تدوير الكاميرا. can_pan: قيمة بوليانية تحدد إمكانية التحريك الجانبي للكاميرا. can_zoom: قيمة بوليانية تحدد إمكانية التكبير أو التصغير للكاميرا. can_rotate: قيمة بوليانية تحدد إمكانية تدوير الكاميرا. ثم عرفنا المتغيرات التي ستخزن معلومات عن اللمس وهي: start_zoom لتخزين قيمة بداية عملية التكبير أو التصغير الحالي للكاميرا. start_dist لتخزين المسافة بين نقاط اللمس عند بداية التكبير أو التصغير. touch_points لتخزين مواقع نقاط اللمس على الشاشة لاستخدامها في حسابات التكبير والتدوير. start_angle لتخزين زاوية بداية التدوير لحساب الزاوية المطلوبة للتدوير. current_angle لتخزين الزاوية الحالية لعملية التدوير لتحديث تدوير العنصر المرئي بشكل مستمر. تحريك الكاميرا حول محورها لنبدأ اﻵن بتحريك الكاميرا حول محورها، وهي الحركة اﻷبسط التي تنفذها الكاميرا في المشهد. سنحتاج إلى وسيلة لترصّد بعض أحداث الدخل، لهذا سنتجاوز override الدالة (input(event_ للتحقق من أحداث اللمس touch والسحب drag على الشاشة والاستجابة لها بالشكل المناسب: func _input(event): if event is InputEventScreenTouch: _handle_touch(event) elif event is InputEventScreenDrag: _handle_drag(event) تخزّن الدالة (handle_touch(event_ موقع كل نقطة لُمست على الشاشة ضمن القاموس touch_points وتستخدم دليل اللمس touch index كمفتاح، وهذا أساسي لتتبع المواقع التي تُلمس على الشاشة. كما سنضبط قيمة المتغير start_dist على 0 إن كان عدد النقاط التي لُمست أقل من 2: func _handle_touch(event: InputEventScreenTouch): if event.pressed: touch_points[event.index] = event.position else: touch_points.erase(event.index) if touch_points.size() < 2: start_dist = 0 بإمكاننا تحريك الكاميرا حول محورها بالاستفادة من نقطة لمس واحدة، وذلك باستخدام الدالة (handle_drag(event_ المعرفة كالتالي: func _handle_drag(event: InputEventScreenDrag): touch_points[event.index] = event.position if touch_points.size() == 1 and can_pan: offset -= event.relative * pan_speed إن شغّلت اللعبة على محاكي أندرويد سترى كيف تتحرك الكاميرا: إضافة ميزة التكبير والتصغير سنضيف اﻵن إمكانية التكبير والتصغير (تقريب وإبعاد)، لهذا سنعدّل الدالة (handle_touch(event_ كي نعالج حالة وجود نقطتي لمس والتي سنحسب فيها المسافة اﻷولية بينهما ونخزّنها: func _handle_touch(event: InputEventScreenTouch): if event.pressed: touch_points[event.index] = event.position else: touch_points.erase(event.index) if touch_points.size() == 2: var touch_point_positions = touch_points.values() start_dist = touch_point_positions[0].distance_to(touch_point_positions[1]) start_zoom = zoom start_dist = 0 نضيف بعد ذلك إمكانية التحكم بالتكبير والتصغير إلى الدالة handle_drag(event)_، فعند وجود نقطتي لمس، نحسب المسافة الحالية بينهما وبناء عليها نضبط التكبير والتصغير: func _handle_drag(event: InputEventScreenDrag): touch_points[event.index] = event.position # Handle 1 touch point if touch_points.size() == 1 and can_pan: offset -= event.relative * pan_speed # Handle 2 touch points elif touch_points.size() == 2 and can_zoom: var touch_point_positions = touch_points.values() var current_dist = touch_point_positions[0].distance_to(touch_point_positions[1]) var zoom_factor = start_dist / current_dist zoom = start_zoom / zoom_factor limit_zoom(zoom) # This is about to be created! نستخدم الدالة (limit_zoom(zoom لمنع التكبير أو التصغير من تجاوز الحدود وسيقف التكبير أو التصغير عند حد معين: func limit_zoom(new_zoom: Vector2): if new_zoom.x < 0.1: zoom.x = 0.1 if new_zoom.y < 0.1: zoom.y = 0.1 if new_zoom.x > 10: zoom.x = 10 if new_zoom.y > 10: zoom.y = 10 انقر على زر التشغيل لترى النتيجة: إضافة الدوران لنضف أخيرًا إمكانية تدوير الكاميرا، لهذا سنقيس الزاوية الأولية بين نقطتي اللمس من خلال الدالة handle_touch(event)_: func _handle_touch(event: InputEventScreenTouch): if event.pressed: touch_points[event.index] = event.position else: touch_points.erase(event.index) if touch_points.size() == 2: if touch_points.size() == 2: var touch_point_positions = touch_points.values() start_dist = touch_point_positions[0].distance_to(touch_point_positions[1]) start_angle = get_angle(touch_point_positions[0], touch_point_positions[1]) start_zoom = zoom elif touch_points.size() < 2: start_dist = 0 نضيف بعد ذلك إمكانية التحكم بالدوران ضمن الدالة handle_drag(event)_: func _handle_drag(event: InputEventScreenDrag): touch_points[event.index] = event.position if touch_points.size() == 1: if can_pan: offset -= event.relative * pan_speed elif touch_points.size() == 2: var touch_point_positions = touch_points.values() var current_dist = touch_point_positions[0].distance_to(touch_point_positions[1]) var current_angle = get_angle(touch_point_positions[0], touch_point_positions[1]) #this will be created below var zoom_factor = start_dist / current_dist if can_zoom: zoom = start_zoom / zoom_factor if can_rotate: rotation -= (current_angle - start_angle) * rotation_speed start_angle = current_angle # حدث الزاوية اﻷولية إلى الزاوية الحالية limit_zoom(zoom) تٌستخدم الدالة (get_angle(p1, p2 لحساب الزاوية: func get_angle(p1: Vector2, p2: Vector2) -> float: var delta = p2 - p1 return fmod((atan2(delta.y, delta.x) + PI), (2 * PI)) جرّب تدوير اﻷيقونة اﻵن! السكريبت المكتمل إليك الشيفرة الكاملة: extends Camera2D @export var zoom_speed: float = 0.1 @export var pan_speed: float = 1.0 @export var rotation_speed: float = 1.0 @export var can_pan: bool @export var can_zoom: bool @export var can_rotate: bool var start_zoom: Vector2 var start_dist: float var touch_points: Dictionary = {} var start_angle: float var current_angle: float func _ready(): start_zoom = zoom func _input(event): if event is InputEventScreenTouch: _handle_touch(event) elif event is InputEventScreenDrag: _handle_drag(event) func _handle_touch(event: InputEventScreenTouch): if event.pressed: touch_points[event.index] = event.position else: touch_points.erase(event.index) if touch_points.size() == 2: var touch_point_positions = touch_points.values() start_dist = touch_point_positions[0].distance_to(touch_point_positions[1]) start_angle = get_angle(touch_point_positions[0], touch_point_positions[1]) start_zoom = zoom elif touch_points.size() < 2: start_dist = 0 func _handle_drag(event: InputEventScreenDrag): touch_points[event.index] = event.position if touch_points.size() == 1: if can_pan: offset -= event.relative * pan_speed elif touch_points.size() == 2: var touch_point_positions = touch_points.values() var current_dist = touch_point_positions[0].distance_to(touch_point_positions[1]) var current_angle = get_angle(touch_point_positions[0], touch_point_positions[1]) var zoom_factor = start_dist / current_dist if can_zoom: zoom = start_zoom / zoom_factor if can_rotate: rotation -= (current_angle - start_angle) * rotation_speed start_angle = current_angle # Update the start_angle to the current_angle for the next drag event limit_zoom(zoom) func limit_zoom(new_zoom: Vector2): if new_zoom.x < 0.1: zoom.x = 0.1 if new_zoom.y < 0.1: zoom.y = 0.1 if new_zoom.x > 10: zoom.x = 10 if new_zoom.y > 10: zoom.y = 10 func get_angle(p1: Vector2, p2: Vector2) -> float: var delta = p2 - p1 return fmod((atan2(delta.y, delta.x) + PI), (2 * PI)) الخلاصة صممنا في هذا المقال سكريبت كاميرا تتجاوب مع أفعال اللمس على الشاشة في محرك الألعاب جودو 4، ويمكنها التحرك حول محورها أو التكبير والتصغير أو الدوران. انتبه فقط إلى ضرورة ربط السكريبت بعقدة من النوع Camera2D واستمتع بعملك! ترجمة -وبتصرف- لمقال Building a touchscreen camera in Godot 4: A comprehensive guide اقرأ أيضًا تشغيل محرك الألعاب جودو على بعض أنواع العتاد غير المدعوم تعرف على أشهر محركات الألعاب تعرف على أشهر لغات برمجة الألعاب مدخل إلى محرك الألعاب جودو
-
نتحدث في مقالنا عن أمثل الطرق ﻹعداد وتصدير الأصول أو الموجودات assets من بليندر Blender إلى محرّك اﻷلعاب جودو Godot، ونغطي خلاله العمل مع الخامات texture والتعامل مع قنوات لونية مختلفة، وبعض الإعدادات الشائعة لملفات المشاهد ثلاثية اﻷلعاب gLTF، ثم نتحدث عن فعالية استخدام هذه التنسيق. إعداد الخامة Texture عليك بداية إعداد الخامة texture، لهذا يمكنك الانتقال فورًا إلى التحرير اللوني shading، وقد تلاحظ وجود كائنين. والسبب في ذلك أننا سنستعرض تقنيتين مختلفتين لهما فائدة كبيرة جدًا، وستلاحظ أن معاملات الكائن اﻷول جاهزة وفي مكانها. وفي الفقرات التالية نوفر لك دليلًا سريعَا يوضح الدمج مع بقية الأصول التصميمية في ملف gLTF الذي سنصدّره والذي يستخدم لنقل وتحميل النماذج ثلاثية الأبعاد. القناة Alpha وخريطة Albedo تمثّل Albedo الخريطة اللونية التي يمكن سحبها إلى القاعدة اللونية Base Color. وإن وجدت القناة Alpha، سيتوجب عليك سحبها إلى مكانها. أما خريطة Albedo فهي الخريطة اللونية التي تحتاجها وبإمكانك سحبها إلى القاعدة اللونية. وبالعودة إلى قناة Alpha، وإن كان لديك أية قناة قد هيأتها سابقًا، فعليك وضعها ضمن القسم Alpha. وإن أردتها أن تعمل ضمن محرك اﻷلعاب الذي تريده، انتقل إلى المواد material وبعدها إلى وضع المزج blend mode وغيّرها إلى اقتصاص ألفا Alpha clip. وتذكر أن الطريقة التي تُعد فيها القناة هنا هي نفسها التي ستظهر عندما يتطلب اﻷمر تغيير بعض اﻹعدادات. ستجد في لوحة المواد لديك نمطًا للمزج تصل إليه كالتالي viewport display ثم settings ثم Blend Mode، وسيؤثر ذلك على طريقة عرض محرك اﻷلعاب لخرائطك: واضح Opaque: وهو اﻹعداد الافتراضي، تُرى فيه المواد بشكل كامل ولا يسمح بأي وضع شفاف، أي يتجاهل هذا الخيار أية معلومات تقدمها القناة Alpha ويتعامل مع المواد على أنها ظاهرة تمامًا. اقتصاص ألفا Alpha clip: ويُعرف هذا النمط أيضًا باختبار ألفا Alpha Test أو الاقتصاص Cutout، ويستخدم معلومات قناة Alpha ﻹنشاء فصل ثنائي واضح بين المناطق كاملة الوضوح وكاملة الشفافية. وهذا أمر مثالي للكائنات التي تتمتع بشفافية محددة بدقة مثل الأسوار وأوراق اﻷشجار أو القصاصات الورقية، إذ لا تريد حينها مناطق نصف شفافة. تظليل ألفا Alpha Hashed: يسمح هذا النمط باﻷوضاع نصف الشفافة للمواد، ويعطي أفضل النتائج عند تجميع الكائنات الشفافة فوق بعضها على شكل طبقات. يستخدم نمط التشويش العشوائي dithered pattern لمحاكاة الشفافية، وينتج عنه خامة مشوشة لكنها تعطي توزيعًا أفضل عمومًا للسطوح الشفافة مقارنة بنمط مزج ألفا Alpha Blend. مزج ألفا Alpha Blend: يسمح هذا النمط بالوضع نصف الشفاف الكامل، وهو مثالي لمواد مثل الزجاج أو السوائل، إذ يمزج قناة Alpha مع القناة اللونية ليعطي تمثيلًا دقيقًا للشفافية. مع ذلك قد يواجه هذا النمط مشاكل مع توزيع العمق اللوني وخاصة عند تتداخل عدة كائنات شفافة. المظهر المعدني والخشونة يستخدم مخطط عمل يعتمد على التصيير الفيزيائي Physical Based Rendering ليحاكي المواد الحقيقة في محركات اﻷلعاب ثلاثية اﻷبعاد. الخرائط المعدنية تحدد الخرائط المعدنية Metallic Maps أية أقسام من نموذجك لها مظهر معدني وتلك التي ليس لها هذا المظهر. ففي الخامة ذات التدرجات الرمادية، تعبر القيمة (1.0) للون اﻷبيض أن السطح معدني، بينما تعبر القيمة (0.0) عن سطح غير معدني. وعليك الانتباه إلى أن هذه الخاصية قد تكون ثنائية وغير متدرجة في أغلب اﻷحيان، فإما أن يكون السطح معدنيًا أو غير معدني. لهذا سيكون لهذه الخريطة قيم سوداء تمامًا أو بيضاء تمامًا غالبًا، ونادرًا ما تستخدم قيم تدريجية (رمادية). خرائط الخشونة تتحكم خرائط الخشونة Roughness Maps بتفصيل نعومة أسطح المواد وتحدد مدى الخشونة أو النعومة التي تبديها. ففي هذه اﻷرضية ذات التدرج الرمادي، تشير قيم اللون اﻷبيض إلى سطح خشن، يعكس الضوء باتجاهات مختلفة، معطيًا مظهرًا ليس لامعًا. بينما تشير قيم اللون الأسود إلى سطح ناعم يعكس الضوء باتجاهات محددة أكثر، معطيًا مظهرًا لامعًا. لكن كيف يمكن تصدير كل ذلك؟ كيف تُنفّذ هذه الإعدادات لتصديرها لاحقًا من الجيد فصل اﻷرضيات التي تحجب محيط الكائن وخرائط الخشونة والمظهر المعدني (ORM اختصارًا) وإسنادها إلى القناتين اللونيتين الزرقاء والخضراء وهو طريقة جيدة في حزم اﻷرضيات لجعلها أكثر فعالية. وعندما يكون لديك عدة خرائط متصلة مع خرائط ORM ستُجمّع كلها ضمن خامة ORM واحدة. وتأكد من ضبط خرائط الخشونة والمظهر المعدني والخرائط النمطية normal map على قيم غير لونية كي يكون الفضاء اللوني صحيحًا وبالتالي ستنقل البيانات بشكل صحيح. وتذكر أيضًا أن أية تغييرات تجريها على اﻷرضيات ستُصدّر أيضًا. حجب محيط المادة إن حجب المحيط Ambient Occlusion عملية مزعجة للكثيرين، وخاصة عند تصديرها من بليندر. والحل اﻷبسط هو تحديد عقدة الخامة ومضاعفتها بالضغط على المفتاحين Shift + D، ثم تجميعها بالضغط على المفتاحين CTRL + G والذي يُنشئ مجموعة من اﻷرضيتين في الوسط. احذف الخريطة الموجودة في الوسط: ستجد على اليمين المدخلات inputs والمخرجات outputs ضمن النافذة الفرعية "Group": أزل المدخلات فلن نحتاجها، ثم غيّر اسم الشعاع Vector تحت المدخلات إلى Occlusion وغيّر نوعه إلى float اضغط على Tab وستظهر عقدة مجموعة جديدة: غيّر اسم العقدة إلى "glTF Settings" كما في الصورة التالية تمامًا، فأي خطأ سيمنعه من العمل: صل اﻵن خريطة الحجب إلى عقدة المجموعة "glTF Settings": تصدير الخريطة النمطية الخريطة النمطية normal map هو نمط من اﻷرضيات المستخدمة في النماذج ثلاثية اﻷبعاد لمحاكاة التفاصيل الصغيرة للسطح مثل النتوءات دون الحاجة ﻹضافة مضلعات جديدة في النموذج. تُعد الخريطة النمطية بسيطة، واحرص على عدم استخدام قيم لونية عند ضبطها ثم صلها مع عقدة الخرائط النمطية وبعدها إلى normal. هذه هي الطريقة اﻷبسط لتصديرها. إعدادات إضافية أخرى ستجد في نافذة اﻹعدادات settings الخيار "Backface Culling" (ويعني إخفاء الوجه عند النظر من الخلف)، فإن فعّلته هنا سيُفعّل في محرًك اﻷلعاب الذي تنقل ملف اﻹعدادات إليه. عند تفعيل هذا الخيار، يتحقق محرك الرسوميات من توجّه كل مضلّع، فغن كان مواجهًا للكاميرا فسيُصيّر بشكل اعتيادي، وإن كان معاكسًا لها، سيتجاوزه محرّك الألعاب ولن يصيّره. ولهذا الأمر إيجابيات على اﻷداء، فهو يقلل عدد المضلعات التي يجدر بالمحرّك معالجتها بشكل واضح. ولكي تعمل هذه التقنية جيدًا، ينبغي أن يكون النموذج مغلقًا بالشكل الصحيح، أي لا يحتوي أية ثقوب تسمح بالنظر من خلالها إلى الوجه الخلفي لمضلعات أخرى. فإن فّعلّ خيار إخفاء الوجه عند النظر من الخلف وكان هناك ثقوب، فستظهر بعض أجزاء النموذج وكأنها مفقودة عند النظر من زاوية معينة. ومن المهم الانتباه إلى أن تفعيل هذا الخيار ليس محبذًا النماذج المسطحة والرقيقة مثل اﻷوراق او غيرها من المواد الشفافة أو نصف الشفافة والتي يمكن أن يُرى منها وجهي المضلع، بعد ذلك يمكنك تصدر الكائن بالانتقال إلى File ثم Export GLTF. ما الذي يجب تذكره عند تصدير GLTF؟ ينبغي الانتباه إلى عدة أشياء عند تصدير GLTF، لهذا سنناقش إعدادات تصدير النموذج ثلاثي اﻷبعاد بصيغة GLTF: التنسيق Format: أكثر التنسيقات استخدامًا هو صيغة GLB الثنائية، لأنها تضم النموذج ثلاثي اﻷبعاد واﻷرضيات في ملف واحد. مع ذلك يعطيك تنسيقا (glTF(GLTF + BIN + textures و glTF Embedded تحكمًا أوسع لأنهما يفصلان بين المكونات. ويُعد تنسيق (glTF(GLTF + BIN + textures مفيدُا إن أردت مشاركة اﻷرضيات مع كائنات أخرى. التضمين include: تحدد في هذا القسم أية أجزاء من ملف بلندر ستصدره. فالخيار "خيارات منتقاة Selected Options" يُصدّر فقط النماذج التي اخترتها، وجميع الخيارات في المجموعة الفعّالة حاليًا في حال اخترت "المجموعة الفعالة Active Collection". التحويل transform: إن كنت تواجه مشاكل مع توجّه النموذج في محرّك اﻷلعاب، بإمكانك تغيير المحورين "أعلى Up" و "للأمام Forward". وتذكّر اختلاف التوجّهات في محركات الألعاب المختلفة. تصدير المواد Material Export: عليك التأكد من تفعيل هذا الخيار. الصور Images: بإمكانك اختيار صيغة الصور التي تريدها من هذا القسم. هندسة النموذج Geometry: يتضمن هذا القسم خيارات التصدير المتعلقة بهندسة النموذج، فإذا كان نموذجك يستخدم ألوان Vertex فعّل الخيار المتعلق به وإلا فقم بتعطيله، اما خيار Apply Modifiers فهو يطبق جميع المعدلات على النموذج الخاص بك قبل التصدير. التحريك Animation: يساعدك هذا القسم في تصدير الرسوم المتحركة، وبإمكانك تصدير الرسوم المتحركة النمطية normal animations ومفاتيح الشكل shape keys ورسوم اﻷغلفة skinning كي تتحكم بها في محرّك اﻷلعاب الذي تريد. إدراج ملف glTF في محرك اﻷلعاب جودو عند اكتمال تصدير الملف، افتح محرّك اﻷلعاب جودو واستورد هذا الملف. وتأكد أن الصور المضمّنة في تنسيق glTf Embedded قد ضُبطت على "استخراج اﻷرضيات". ومن المفترض أن يتلائم الملف المصدّر جيدًا. في حالتنا الموضحة بالصور التالية، اخترنا اقتصاص ألفا Alpha clip عند التصدير، لكنه ظهر في محرك ألعاب جودو على شكل مقص ألفا Alpha Scissor. لاحظ كيف ظهرت الخرائط بالشكل الصحيح في جودو! وقد تلاحظ كيف تبدو غريبة ومليئة بألوان زاهية، يُدعى هذا اﻷمر خامة ORM أي أن اﻷرضيات قد حُزّمت ضمن خرائط مختلفة وأقنية مختلفة للخامة مما يجعل هذه الخرائط أكثر فعالية. وقد تلاحظ أيضًا ظهور قسم الانبعاثات Emision والخريطة النمطية Normal Map أيضًا. الخلاصة باتباعك الخطوات التي شرحناها في هذا المقال، ستتمكن من تصدير عناصر أو أصول الألعاب الخاصة بك بفعالية من بليندر إلى جودو Godot. لا تتردد في ترك أية تساؤلات أو اقتراحات في قسم التعليقات أسفل الصفحة لتعم الفائدة لجميع المهتمين بتصميم الألعاب الإلكترونية. ترجمة -وبتصرف- لمقال: How to Efficiently export Assets from Blender to your game engine اقرأ أيضًا مطور الألعاب: من هو وما هي مهامه بلندر للمبتدئين: كيف تصمّم وتحرّك روبوت - نمذجة الجسم والرأس كيف تصمّم وتحرّك روبوت: خامات بلندر ومفاتيح الشكل إنشاء مجسم ثلاثي الأبعاد لشجرة باستخدام برنامج بلندر
-
يواجه المديرون في السنوات الأخيرة تحديات في تقييم رضا فريق العمل بالأعمال الموكلة إليهم، خاصةً بعد انتشار أسلوب العمل عن بعد. ولحسن الحظ، تساعد بعض الحلول في التخفيف من المشكلة مثل منصات استطلاع الرأي التي تقيس مقدار انخراط موظفيك في أعمالهم وتقرّب المسافة التي تفصلك عنهم وتمنحك فكرةً عميقةً عن مشاعرهم حيال عملهم. وعلى خلاف استطلاعات الرأي التقليدية على الإنترنت التي تبدو جافةً ومعممة، يمكن لاستطلاع رأي الموظفين أن يحوّل نقاط النقاش إلى عمل فعلي له نتائجه الملموسة. ما الغاية من استطلاع رأي الموظفين إنّ الغاية الأساسية من استطلاع آراء الموظفين قبل كل شيء هي تحديد سلوك العمل لديهم من حيث مستويات التحفيز والالتزام بعملهم معك وقناعتهم بشركتك وبيئة العمل التي تحيطهم بها. لقد أظهر استبيان لموقع "Officevibe" أنّ: 37% من الموظفين لا يشعرون بأنهم مقربون من مديريهم. 31% من الموظفين يرغبون بالتواصل أكثر مع مديريهم. قرابة %96 من الموظفين يعتقدون بضرورة تلقي تنبيهات وردود أفعال من مديريهم بانتظام. كما أشارت البيانات إلى رغبة الكثيرين في التواصل المفتوح مع قادة شركاتهم، لكن الأمر غير متاح غالبًا، وقد يكون السبب هو عدم انتباه مشرفيهم إلى حاجتهم للتواصل. قد تنبه التعليقات أو الآراء مخفية المصدر (التي تنتج عن استطلاعات رأي الموظفين) مديري الشركات إلى طريقة تأسيس تقنية تواصل جيدة بينهم وبين موظفيهم وبين الموظفين أنفسهم. سيساعدك استثمار وقتك وجهدك في هذه الاستطلاعات على التخلص من الخيارات غير المدروسة عند بناء الفريق، ويمنحك المعلومات اللازمة لتنمية بيئة عمل مكتبية مريحة؛ كما تمكنك استطلاعات الرأي من تقييم رضا الأشخاص وتساعدك في بناء مسار تواصل جديد في شركتك، فتأسيس حلقة تواصل ضمن الشركة ستعمق معرفتك بالأوضاع وتُشعر الموظفين بقيمتهم وتدفعهم للالتزام بالعمل لديك مستقبلًا. فوائد تجنيها من استطلاع آراء الموظفين ستكون استطلاعات الرأي التي تشجع موظفيك على التعبير عن رضاهم بالعمل لديك وترشدك إلى طرق تحسين ثقافة التعاون، بمثابة مفتاح للحفاظ على موظفيك وزيادة إنتاجيتهم. وعندما تستخدم هذه الاستطلاعات بطريقة منهجية وفعالية ستتمكن من: 1. تحسين الروح المعنوية للموظفين تشير الدراسات إلى تقدير الناس للتواصل المستمر والالتزام به. وعندما تتواصل مع موظفيك متبادلًا الآراء معهم، فسيشعرون بأنك مصغ ومهتم. يمكن للمديرين أن يقيّموا مدى مشاركة الموظفين الفعالة في نشاط الشركة والمخاطر المحتملة في كل قسم على حدى من خلال استطلاعات الرأي، فقد تشير المعلومات الناتجة عن تحليل استطلاعات آراء الموظفين إلى شعورهم حيال أسلوب إدارتك وغيرها من النقاط؛ كما قد تدلك على النجاحات والإنجازات التي تحققت دون أن يلحظها أحد. وحتى لو لم تستطع الاستجابة لكل ما يرد في تلك الاستطلاعات مباشرةً، إلا أنك قادر على معالجة النقاط التي يمكن إنجازها على المدى القريب وتعم فائدتها على المدى الأطول. عزز الروح المعنوية للموظفين من خلال استطلاع آرائهم، وناقش نتائج تقييم انخراطهم في العمل وكيفية إبداع طرق وأساليب جديدة في تنمية روح الفريق. يمكن لاستطلاع آراء الموظفين أن يلقي الضوء على النجاحات والإنجازات التي تحققت دون أن يلحظها أحد، وقد تعطي الفرصة لحل بعض الخلافات أو إطلاق نقاشات أساسية حول الأداء والإنتاجية. وعندما تكون على دراية تامة بما يحدث حولك وتستمر في تجميع ردود أفعال موظفيك والاطلاع على آخر المستجدات، ستكون قادرًا على إبراز فريق العمل عندما يقدم أداءً ملفتًا، وهي طريقة ممتازة لتعزيز الروح المعنوية، خاصةً إن استمريت في تنفيذها. عندما تتقن إدارة الحالة النفسية لموظفي شركتك، ستكون قادرًا على تعزيز بيئة عمل متعاونة تشجع الناس وتزيد في انخراطهم بشغف في أعمالهم. ستزوّدك المعلومات التي تحصل عليها من استطلاعات الرأي المخصصة في إيجاد جملة من المواضيع الجديدة التي لا بدّ من تتبعها لفهم فريقك أكثر. 2. استدراك الثغرات المعرفية يمكن أن تحدد نتائج استطلاعات الرأي الثغرات المعرفية المحتملة على المستوى الفردي أو مستوى الفريق. هل فهم الجميع مثلًا جميع الأهداف التي عرضت في آخر اجتماع؟ هل عرف كل شخص الدور الذي سيلعبه للمساهمة في تحقيق الأهداف؟ هل الجميع مهيأ لتنفيذ المهمة المطلوبة؟ يمكن للقادة تنفيذ استطلاع رأي للتعمق في تفاصيل مهمة أو عمل ما، وستقودهم النتائج بسرعة إلى النقاط التي قد تسبب أخطاءً مكلفة، سواءً كانت نقصًا في الاستيعاب الكامل، أو نقصًا في المهارة. وبالتالي ستتمكن من حل هذه النقاط باكرًا إن عرفتها باكرًا من خلال التمرين أو المتابعة أو إجراء مقابلات خاصة وجهًا لوجه. 3. تحسين الصحة النفسية للموظفين تشير الدراسات إلى أنّ ضعف التواصل بين المدير والموظف قد تزيد من التوتر والاكتئاب، بما في ذلك الشعور بالعزلة الاجتماعية. هل أخذت بالحسبان يومًا تأثير الصحة النفسية على أداء الموظفين؟ هل كانت أخطاؤهم مجرد أخطاء صرفة أم أنها نتيجةً لذهن شارد أو شعور بالوحدة أو عدم الرغبة في الانخراط بالعمل؟ إنّ أهم ما تقدمه لك استطلاعات الرأي هو مناخ النقاش المفتوح في الشركة، فقد يساعدك طرح بعض الأسئلة الخاصة التي يمكن للموظفين الإجابة عليها بحرية على منح الكثير من الموظفين طريقة آمنة للتعبير عن الأفكار التي تثقل كاهلهم. نشعر جميعنا بأنّ وجود الإدارة المتعاطفة سيصب في مصلحتنا. وعندما تُجري استطلاعات الرأي فأنت تفتح بذلك مساحة تدعو إليها موظفيك للتواصل المباشر معك، وقد يساعدك ذلك في تخفيف شعورهم بالعزلة وزيادة رضاهم عن عملهم وتحسين صحتهم النفسية. 4. موظفين أكثر سعادة عندما تتبنى شركتك ثقافةً تشجع على التواصل المفتوح، فأنت تشجع موظفيك على البوح بما يجول في خاطرهم وتبعد فكرة طردهم عند ارتكابهم الأخطاء، وبهذا ستنمو الثقة بين الموظفين عندما يتبادلون النصائح أو الانتقادات البناءة، لأنها ستُفهم في سياق التآزر والتعاطف. تشير الدراسات إلى أن %83 من الموظفين سيقدّرون رأي الآخرين بما يقدّمون، سواءً كانت آراؤهم إيجابيةً أو سلبية؛ لذلك ينبغي أن تحرص على إيجاد فرصة لتوجيه ملاحظاتك أيًا كانت إلى موظفيك، وذلك من خلال الأقنية الرسمية وغير الرسمية لتنمي المشاعر الجيدة اتجاه مكان العمل. تساعد التوجيهات المستمرة الموظف على أداء واجباته دون ضغوطات أو مشاعر سلبية ناتجة عن سوء الفهم؛ فعندما يتيح الموظف لمديره مادةً يفتتح من خلالها الاتصال، فستعم الفائدة الشركة بأكملها؛ كما أنّ التعبير عما يتوقعه كل طرف من الآخر سيزيد من الصراحة والوضوح اللازمين لأداءٍ أفضل. 5. تعزيز عامل السلامة عند الموظفين قد تتفاجأ بأنّ الانخراط الفعال لموظفيك في عملهم يؤثر في سلامتهم المهنية، فقد أظهرت الدراسات أنّ الاجتهاد في العمل يزيد من إدراك الموظف لمحيطه، مما يقلل عدد حوادث العمل التي قد تؤثر على سلامتهم. وكما يعزز التواصل مع موظفيك الروح المعنوية لديهم، فقد تمنحك البيانات التي تقدمها استطلاعات الرأي إضاءات لأسلوب العمل الذي يزيد من حماسهم إلى العمل، والذي سيقود بدوره إلى سلامة مهنية أعلى. وستكون النتيجة بيئة عمل أكثر سعادةً وصحة، وتوفيرًا للوقت والمال نظرًا لانخفاض المخاطر. تلعب الصحة النفسية أيضًا دورًا مفتاحيًا، فقد أظهرت الدراسات أنّ %20 من أعضاء الفريق يخشون طرح أفكار جديدة؛ فعندما تفتح للموظفين أقنية للتواصل، فأنت تمنحهم منصةً ليفصحوا عما يجول في خواطرهم وستفتح الطريق أمام إبداعات فكرية وابتكارات جديدة. 6. زيادة رضا الموظفين يتطلب إيجاد عمل مقنع عن بعد (من المنزل) انسجامًا مع العمل نفسه والأشخاص القائمين عليه مثل المديرين والزملاء والعملاء وغيرهم من أصحاب الأعمال، إذ يحدُّ التخاطب مع أشخاص ترى وجوههم فقط من خلال شاشة الحاسوب من التواصل البشري، وسيشعر الناس بأنهم غرباء وفاقدي الحافز أو الرغبة في إنجاز أعمالهم عندما يقل التواصل وجهًا لوجه، كما قد ينعكس ذلك سلبًا على مستوى الرضا عن العلاقة مع المشرفين. تساعدك أدوات استطلاعات الرأي الشاملة على قياس مؤشرات الانخراط في العمل، مثل الرضا عن العمل، بالإضافة إلى مؤشرات أخرى تتعلق بالعلاقة مع الزملاء وإرادة العمل والتوتر والانحياز إلى الشركة وغيرها. وبمراجعة نتائج استطلاع الرأي والإجابات المقدمة، ستتمكن من الإحاطة بعمل فريقك ومن ثم اتخاذ التدابير اللازمة لتعزيز رضا الموظفين عن الأعمال التي ينجزونها، كما ستتمكن من خلال تحديد مستويات رضا الموظفين من تتبع وتحليل نتائج جهودك التي تبذلها لتحسين واقع العمل مع الوقت. 7. المحافظة على موظفيك لا يمكن للمدراء دائمًا أن يعرفوا ما يجول في خاطر الموظفين، وليس من السهل الإحساس بالآخرين عندما يشعرون بقلة التقدير أو عدم الاستفادة من قدراتهم في إنجاز العمل؛ فإهمال تقدير الأشخاص يُعَد واحدًا من أهم الأسباب التي تؤدي إلى ترك الموظفين لعملهم. عندما لا يرى الموظف أنّ ما يقدمه من مساهمات للشركة محط اهتمام، فسيبحث عن بيئة عمل تقدر ما يفعل؛ لذلك لا بد من التأكد أنّ أصوات موظفيك مسموعة وأنّ مخاوفهم محط اهتمامك، وهنا قد تساعدك استطلاعات آراء الموظفين في استشعار الجو العام ومن ثم التصرف بسرعة قبل وقوع المشاكل أو التحديات المحتملة. 8. زيادة ولاء الموظفين لشركتك لن يترك الموظف العمل لديك إن كان متحمسًا للعمل وملتزمًا بإنجاز الأهداف الموكلة إليه ويشعر بتقديرك له، فكيف ستتمكن إذًا بصفتك مديرًا أن توفر كل المتطلبات السابقة لموظفيك؟ الجواب هو قياس المشاركة الفعالة للموظفين في الأعمال بانتظام. عندما تجد وسيلةً توصل بها إليك أصوات موظفيك، فهذه إشارة إلى اهتمامك بهم وبما يشعرون به حيال استطلاعات الرأي التي تطلقها. اسألهم عن التفاعل فيما بينهم، وعن ضغط العمل وعما يمكن أن تفعله كي يقدم لهم كل الدعم من خلال المبادرات القادمة، فالاستطلاعات هي بمثابة وسيلة لاتخاذ الإجراءات التالية. تُبنى العلاقات على الأخذ والعطاء، فإن أبدت الشركة اهتمامها بموظفيها، فسيرد الموظفون الاهتمام بالمثل. 9. تحسين خدمة العملاء هل جرّبت أن تقدّم المساعدة للعميل وأنت في مزاج سيّئ؟ من الصعب أن تُبقي على هيئتك الودودة لكسب رضا العميل وأنت محبط. ينطبق هذا الأمر تمامًا على موظفي الشركات، فإن استطاعت الإدارة خلق مساحة للتعبير عن الآراء والمشاعر، فستزيح بعض الإحباط الذي قد يشعر به الموظفون وستشهد الشركة تحسنًا شاملًا في مزاج موظفيها وأدائهم ورضاهم، وهذه خطوة جيدة في الاتجاه الصحيح. 10. تنشئ رافعة للتغيير تساعد استطلاعات الرأي على تجميع المعلومات التي تكشف المخاوف غير المعلنة. وحالما تحسّن الظروف المحيطة بالعاملين وتستمع إلى مخاوفهم، ستُحدث نقلة نوعية في ثقافة عمل الشركة ويستفيد الجميع، إذ يستمر الموظفون في العمل لديك إن كانوا سعداء، ويبذلون جهدًا أكبر وتتحسن بيئة العمل بأكملها. هل تحسن استطلاعات آراء الموظفين حماستهم في العمل؟ لاستطلاعات الرأي القدرة على إحياء روح الحماسة تجاه العمل، لكن بالطبع لن ينفع استطلاع واحد! لا بدّ في واقع الأمر من تبني ثقافة تبادل الرأي وتلقي ردود الأفعال وأساسها الاستطلاعات، ومن ثم العمل على نتائجها لتحفيز وتشجيع الموظفين. لا حدود للإمكانيات التي سيوفرها الانخراط الناجح والفعال لموظفيك في أعمالهم، لكنك سترى فقط التغيرات السلوكية إن حاولت العمل على نتائج استطلاعات الرأي؛ فقد تجد مثلًا أنّ ما يقلق فريقك هو نقص التواصل والتشجيع، وسيكون الحل عندها التعاون مع فريقك لتطوير منظومة تبادل آراء أفضل، كما يمكنك العمل مع فريق نشيط لتقديم دعم أفضل أو أسلوب لمكافأة العامل المتميز والاستفادة من الإمكانات الفردية أو زيادة ما ينفع الموظفين. ما الفائدة من استطلاع آراء الموظفين؟ تساعد استطلاعات الرأي المدراء على فهم النواحي التي يعاني فيها فريق العمل أو يشعر بالغبن فيها، أو يحتاج فيها إلى مساعدة أكبر؛ ففهم حاجات موظفيك هو إحدى مزايا القائد الجيد، واستطلاعات الرأي هي إحدى الأدوات التي قد تساعدك وتساعد فريقك على تحقيق النجاح. ترجمة -وبتصرف- للمقال 10 benefits of employee engagement surveys لصاحبته Rachel Steben. اقرأ أيضًا أهمية تبادل الآراء مع الموظفين ما يتوقعه الموظفون من المديرين وفقا لآراء الموظفين هل يشعر الموظفون بالراحة عند إعطاء آرائهم؟
-
نتحدث في هذا المقال عن استخدام محرر قواعد البيانات SQLite للعمل مع جودو، ونعرض بداية اﻷسباب التي تدفع مطوري اﻷلعاب للعمل مع محرر قواعد بيانات أصلًا، ونتعرف بعدها على محرر قواعد البيانات SQLite والذي يُعد قاعدة بيانات مضمّنة صغيرة تسمح للمستخدم تخزين البيانات والاستعلامات ضمنها. لكن لماذا على استخدام قاعدة بيانات هذه؟ إن الميزة المفيدة لهذه القاعدة هو قدرتها على استيعاب كل البيانات في منطقة واحدة، واﻷهم من كل ذلك هو القدرة على الحصول على البيانات بأبسط طريقة. حتى تبدأ العمل معنا في هذا المقال، افتح محرك الألعاب جودو وأنشئ مشروعًا جديدًا. إعداد قاعدة البيانات إذا كنت مطور ألعاب إلكترونية فقد تحتاج لاستخدام قواعد البيانات في لعبتك من أجل تخزين بيانات اللاعبين وحفظ المستوى أو النقاط التي حصلوا عليها، ولتجهيز قاعدة البيانات SQLite التي سنستخدمها في هذا المقال، حمّل متصفح قواعد البيانات DB Browser for SQLite الذي يساعدك في إدارة قاعدة البيانات من خلال واجهة رسومية يمكنك من خلالها إنشاء قاعدة البيانات وتحريرها بسهولة. سنبدأ بإنشاء قاعدة بيانات جديدة، لهذا افتح متصفح قاعدة البيانات وانقر على النافذة "قاعدة بيانات جديدة New Database". وانتقل بعد ذلك إلى المجلد الذي يضم مشروع جودو الذي أنشأته سابقًا وأنشئ ضمنه مجلدًا جديدًا يحمل الاسم "datastore"، فلنختر الاسم "data" لقاعدة بياناتنا الجديدة. تظهر بعد ذلك نافذة "تحرير تعريف الجدول Edit table definition"، اختر عندها الاسم "Scoreboard" لهذا الجدول وسنخزن في هذا الجدول نتيجة كل لاعب أو عدد النقاط التي حصل عليها في اللعبة. لنبدأ بإنشاء أول اﻷعمدة "id" بالنقر على الزر "Add"، وستكون عناصره من النوع الصحيح INTEGER وانقر على الخيارات "غير فارغ NN" و"تزايد تلقائي AI"، مما يسمح له بأن يكون مرجعًا لنا للحصول على البيانات من الجدول أو إلحاق بيانات أخرى. أنشئ تاليًا حقلًا field نصيًا TEXT وسمه "name" وذلك لتخزين اسم المستخدم الذي نريد معرفة نتيجته. ويستخدم النوع السابق لتخزين أكثر من ا تيرابايت من البيانات النصية، فانتبه إلى ذلك! ثم أنشئ أخيرًا حقل النتيجة "score" واجعله من النوع الصحيح INTEGER. انقر اﻵن على الزر "موافق OK" وانتقل إلى مشاهدة قاعدة البيانات من خلال النقر على "تصفح البيانات Browse Data"، وسترى جدولك وقد ظهر. بإمكانك اﻵن من هذه النافذة أن تدخل البيانات يدويًا إن أردت، وذلك بالنقر على أيقونة اﻹضافة ومن ثم إدخال ما تريد. إن انتقلنا إلى "تنفيذ استعلام execute SQL"سترى المكان الذي تنفذ فيه الاستعلامات التي نريد على قاعدة البيانات. سنجرّب الاستعلامات بإدخال بعض البيانات، لهذا اكتب الاستعلام التالي: insert into scoreboard (name,score) values ('nori',50),('finepointcgi',20) عند تنفيذ هذا الاستعلام على النحو التالي: سترى النتيجة التالية: وعند تنفيذ الاستعلام Select * from scoreboard، سترى نتيجة عملك. ولننتقل اﻵن إلى محرك الألعاب جودو من أجل استكمال عملية ربطه مع قاعدة البيانات SQLite. تنزيل اﻹضافة الخاصة بقاعدة البيانات SQlite لننتقل اﻵن إلى جودو ثم نفتح النافذة الفرعية "مكتبة الأصول أو مكتبة الموجودات Asset library" التي تمثل مستودعًا لأي أدوات أو موارد إضافية تريد تضمينها في اللعبة، ثم اكتب sqlite واختر الإضافة التي تملك الرقم 2shady4u فهي إضافة جيدة وذات أداء مستقر. جرّب بعد ذلك تثبيتها وانتظر لحين اكتمال التنزيل. سنضيف تاليًا عقدة، لهذا سننشئ سكريبت ونسمّيه "MainSystem.gd" وسيحتوي هذا الملف على كافة السكريبتات والتعليمات التي تتفاعل مع البيانات، لذا علينا تحميل أن نقوم بتحميل قاعدة البيانات في بدايته، وكي تتمكن من القيام بالتحميل المسبق للبيانات عليك استخدام الدالة preload مع تمرير العنوان التالي لوسيط لهذه الدالة: res://addons/godot-sqlite/bin/gdsqlite.gdns إدخال بيانات إلى قاعدة البيانات الآن انسخ الشيفرة التالية إلى ملف السكريبت الذي أنشأته في الخطوة السابقة: const SQLite = preload("res://addons/godot-sqlite/bin/gdsqlite.gdns") var db var db_name = "res://DataStore/database" func _ready(): db = SQLite.new() db.path = db_name func commitDataToDB(): db.open_db() var tableName = "PlayerInfo" var dict : Dictionary = Dictionary() dict["Name"] = "this is a test user" dict["Score"] = 5000 db.insert_row(tableName,dict) ننشئ في الكود أعلاه المتغيرين db و db_name بعد تحميل قاعدة البيانات، ونسند للثاني عنوان قاعدة البيانات "res://DataStore/database". ومن أجل تهيئة قاعدة البيانات، نستدعي التابع ()SQLite.new داخل الدالة ()ready ونسند قيمته إلى المتغير db، وسيُهيئ ذلك صنفًا لإعداد قاعدة البيانات. نحتاج بعد ذلك إلى ضبط مسار قاعدة البيانات كالتالي db.path= db_name ونضيف بعدها دالة جديدة تُدعى ()commiteDataToDB سنستخدمها ﻹيصال البيانات إلى قاعدة البيانات. ننشئ ضمن الدالة ()commiteDataToDB قناة اتصال مع قاعدة البيانات لهذا نستدعي التابع ()db.open_db الذي يهيئ قناة الاتصال مع قاعدة البيانات ويسمح لنا بتنفيذ استعلامات عليها. ولاختيار اسمٍ للجدول، نعرّف متغيرًا بالاسم tablename ونضبطه قيمته على "PlayerInfo". ثم ننشئ قاموسًا dict يحدد المعلومات التي نريد إدراجها في قاعدة البيانات، ويكون مفتاح القاموس بمثابة العمود والقيمة بمثابة الصف عند إضافة معلومات القاموس إلى قاعدة البيانات من خلال التعليمة INSERT. نستدعي أخيرًا الدالة (db.insert_row(tableName,dict ﻹضافة القاموس (الذي يمثل المُدخل الجديد) إلى قاعدة البيانات. قراءة البيانات من قاعدة البيانات كما هو الحال عند الكتابة إلى قاعدة البيانات، لا بد من فتح قناة اتصال مع قاعدة البيانات واختيار الجدول الذي نريد القراءة منه. ثم ننشئ بعد ذلك الاستعلام الذي نريد باستدعاء التابع ()db.query وكتابة تعليمات الاستعلام ضمنه كمعامل نصي. وبمجرد استدعاء هذا التابع سيتصل مع قاعدة البيانات وينفذ الاستعلام ويخزن النتيجة ضمن المصفوفة query_result. لا بد بعد ذلك من التنقل بين عناصر المصفوفة من العنصر 0 وصولًا إلى آخر عنصر الذي تمثله الخاصية size للمصفوفة query_result للحصول على الكائنات الموجودة في قاعدة البيانات، ومن ثم طباعة النتيجة. func readFromDB(): db.open_db() var tableName = "PlayerInfo" db.query("select * from " + tableName + ";") for i in range(0, db.query_result.size()): print("Qurey results ", db.query_result[i]["Name"], db.query_result[i]["Score"]) الخلاصة هذا هو اﻷمر برمّته! فقد تعلمنا في مقال اليوم طريقة إضافة البيانات إلى قاعدة بيانات ومن ثم تعاملنا معها. ولعللك لاحظت أن استخدام قواعد البيانات أسهل وأسرع من استخدام الملفات لتخزين البيانات في لعبتك الإلكترونية. وتسمح لك باسترجاع البيانات التي تحتاجها فقط بدلًا من قراءة الكثير من الملفات. وعندما ترى أن بياناتك أضخم من عدة ملفات، من الجيد عندها الانتقال إلى قاعدة بيانات. ترجمة وبتصرف للمقال: Setting up Godot to work with SQLite اقرأ أيضًا تعرف على أهمية صناعة الألعاب الإلكترونية مدخل إلى محرك الألعاب جودو تعرف على محرر محرك اﻷلعاب جودو Godot كيف ومتى نستخدم SQLite
-
تشير الإحصاءات إلى أنّ موظفًا من بين خمسة غير راضٍ عن عدد المرات التي يتبادل فيها الآراء مع مديره المباشر، وأن قرابة %30 من الموظفين يتمنون تجاوبًا أكبر من زملائهم! يُعَد التجاوب مع الموظفين وتبادل الآراء أمرًا شديد الأهمية لما له من أثر إيجابي على شعور الموظف بأنه جزء مهم من منظومة أكبر، فعندما يشعر الموظفون بأنهم جزء من الشركة، يزداد نشاطهم وحماسهم لتنفيذ رؤية الشركة وتمثّل قيمها. أيضًا، يُعَد تبادل الرأي جزءًا أساسيًا لتعزيز المشاركة في نشاط الشركة، فالتواصل المثمر هو ما يبني العلاقات الراسخة ويحافظ على المواهب والكفاءات ويوسع قاعدة العملاء ويحافظ عليها، ويرفع من قيمة العلامة التجارية للشركة. ما أهمية الاستماع لآراء الموظفين؟ لآراء الموظفين عندما تُقدّم بطريقة بنّاءة أهمية كبيرة لأنها: تمكّن التنمية المستدامة. تساعد في تحديد وإزالة العوائق في طريق الوصول إلى الأهداف. تقوي العلاقة بين الموظفين والمدير، وكذلك بين الموظفين أنفسهم. يشعر الموظفون بالدعم عند أداء واجباتهم. تساهم هذه الفوائد بمجملها في الانخراط الإيجابي للموظفين في نشاطات شركتهم، كما يُعدّ تبادل الآراء مع الموظفين مهمًا على مستوى الشركة ككل لما له من أثر على الموارد البشرية وعلى مؤشرات الأداء، مثل الاحتفاظ بالموظفين والروح المعنوية لهم، وثقافة الشركة، وبناء المهارات. لنلق نظرةً أقرب على هذه المؤشرات فيما يلي! زيادة قدرة الشركة على إبقاء الموظفين يزيد تبادل الآراء مع الموظفين من احتمال المحافظة عليهم ضمن قوام الشركة، إذ سيقدّر الموظف ذلك عندما تبدي رأيك بعمله إيجابًا أو سلبًا بطريقة صحّية، وقد يدفعهم ذلك إلى استثمار إمكاناتهم ووقتهم في تنمية أعمالك، كما قد يدفعهم حتى إلى رفض فرص عمل في شركات أخرى. يقدّر القادة في هذه الأيام الثمن المكلف لخسارة موظف واستبداله بآخر، وذلك في معركة استقطاب الكفاءات، فقد تخسر الشركة الآلاف عند كل عملية توظيف جديدة، وبالمقابل، تساهم المناصب الشاغرة أو المستبدلة في ضعف انخراط الموظفين في العمل بالشكل المطلوب. وعندما يضطر الموظف إلى تحمل أعباء أكبر في العمل، سيزيد الشعور بالإرهاق والسخط وترتفع مؤشرات ترك العمل وتدخل منظومة العمل في دائرة الخطر. ارتفاع الروح المعنوية للموظفين ترفع ردود الفعل الإيجابية التي يبديها المدير الروح المعنوية للموظف، فعندما يعرف أنّه أدى عملًا ممتازًا، فسيشعر غالبًا براحة نفسية وضغوطات أقل؛ كما سينعكس تعزيز الروح المعنوية للموظف إيجابًا على عائدات الاستثمار، فالموظفون السعداء أكثر إنتاجًا ومشاركةً في العمل. بناء ثقافة إيجابية للشركة ستساهم ثقافة العمل الإيجابية التي تسود الفريق في رفع مستويات أدائه وكفائته، وستجد موظفيك بلا شك مقتنعين بوظائفهم. يتطلب بناء جو العمل الإيجابي الكثير من الثقة والنزاهة، ويساعد إيجاد طريقة فعّالة لتبادل الآراء وتقييم العمل في بناء ثقافة عمل يزدهر فيها موظفوك. اطلع بمساعدة فريقك على آراء موظفيك حول ما يساعدهم في تمثّل القيم الجوهرية للشركة، لأنّ ردودهم قد تساعد في تطوير سير العمل وسياسات الشركة. بناء يد العمل الماهرة يساعد التعلم المستمر الموظفين على تطوير مسيرتهم المهنية (وهذا مؤشر مهم على الانخراط في العمل والمحافظة على اليد العاملة). كما تساعد البرامج التدريبية على تحسين الأداء الكلي للشركة، لأنّ رفع المهارات يدفع قدرات موظفيك وإبداعهم إلى الأمام، وستكون النتيجة خدمات أكثر وتطوير منتجات أكثر وكسب المزيد من الأرباح. ادعم مبادرات التعلم والتطوير بردود أفعال وآراء قابلة للتطبيق، فإن لم يتعلم موظفوك شيئًا جديدًا ولم يستفيدوا من البرامج التدريبية، فما الغاية منها أصلًا! ماهي فوائد تبادل الآراء مع الموظفين تظهر فائدة تبادل الآراء في توضيح ما هو متوقع ويساعد الموظفين على التعلم من أخطائهم، لكن طريقة إنجاز الأمر ليست سهلة، وفوق كل ذلك لا بدّ من الموضوعية واحترام آراء الآخرين لتعم فائدة النقاش. إبداء الرأي أو تقييم عمل موظف يدفع إبداء رأيك بموظفيك إلى زيادة ثقتهم في أدائهم والتزامهم بإظهار سلوك إيجابي، فعندما توجههم ليدركوا مهاراتهم ونقاط قوتهم، ستعزز مكانتهم في بيئة العمل، وهذا هو مفتاح النجاح. يساعد تقييم موظفيك وإبداء رأيك بما ينجزون على تطوير المسيرة المهنية لكل يد عاملة في الشركة. يشير مقال كتبه "Netsuite’s Barnyard" إلى أنّ معظم الذين ينتمون إلى الجيل الجديد (10-25 عامًا) تكيفوا مع إصدار أحكام سريعة، وبالتالي يمكن للمديرين تحاشي إصدار آراء متسرعة وغامضة مباشرة بعد انتهاء مشروع وتأجيلها حتى المراجعة التالية للأداء. باستخدام التقنيات والموارد المناسبة، يمكن التأسيس لثقافة تبادل آراء محورها الموظفون كي يستطيعوا تبادل الآراء بحرية مع زملائهم ومديرهم. الحصول على آراء الموظفين إنّ الاستماع إلى آراء وردود فعل الموظفين هي الطريقة الأسرع لتحسين قدراتك القيادية. فعندما تأخذ وقتك في سماع آراءٍ بناءة من موظفيك، ستلمّ أكثر بما يجري في شركتك على جميع المستويات وستكون قادرًا على اتخاذ قرارات واعية؛ كما أنها ستحل الخلافات التي قد تقع في بيئة العمل قبل وقوعها حتى. بصفتك مدير، عليك مدير أن تقود النقاش الصحيح في بيئة العمل. وعندما تقع النزاعات، استفد من الآراء التي جمعتها لدعم النقاش، ولا تجادل أو تتحيز إلى أي طرف؛ فعندما يفهم الموظف كيفية إبداء الرأي بشكل مؤثر، ستتعزز ثقافة عرض الاختلافات والتعامل معها مباشرةً مهما كانت حساسة، فالصراحة في التواصل هي المفتاح لعلاقات عمل هادئة. أنواع التقييمات أو الآراء الموجهة للموظفين هنالك ثلاثة أنواع رئيسية من التقييمات والآراء الموجهة للموظفين، تتمثل في الآتي. رد الفعل الإيجابي: تبرز هذه الردود نقاط القوة في موظفيك وتدل على إنجازاتهم. فالغاية منها هي تعزيز سلوك العمل الإيجابي لدى الموظفين كما قد تزيد من ثقتهم، مثل: رد فعل سلبي: تضيء هذه الردود على السلوك الذي يجب أن يتوقف كي لا يؤثر سلبًا على الأداء أو فريق العمل، مثل: ردود فعل بناءة: وتوجه إلى شخص محدد للإشارة إلى نقاط الضعف في أدائه تليها طريقة لتقويم الأمر. تفيد هذه الآراء في تقديم حالات أو أمثلة يمكن للموظف أن يتمثلها مع بعض النقد البناء، مثل: كيف تسأل الموظف عن رأيه؟ بعد أن عرضنا فوائد تبادل الآراء وتوجيه رسائل مختلفة للموظفين، علينا استيعاب موضوع لا يقل أهمية عن ذلك ويتعلق بطريقة جمع آراء وإفادات الموظفين بالشكل الصحيح. اطلب رأي فريقك عندما تطلب رأيًا، اجعل جوابه مفتوحًا؛ كأن تسأل فريقك "كيف يمكن أن أحسّن اللقاءات الأسبوعية للفريق؟"، أو حاول أن تسأل أسئلةً محددةً من قبيل "هل تريد أن أساعدك في إعداد تقرير المبيعات الشهري؟". اطلب الآراء بانتظام لا يجد الناس صعوبةً في تبادل الآراء نظرًا لافتقارهم إلى الخبرة، بل لعدم تكرار الأمر، لذا لا تنتظر الوقت المحدد لمناقشة الأداء حتى تستمتع إلى الآراء وتجمّع ردود الأفعال، بل كن سباقًا وتحقق من ردود أفعال من حولك، خاصةً عندما تصل إلى منعطف مهم أو في منتصف مشروع ضخم. يساعد التحقق المستمر على الإجابة بسرعة قبل أن يغدو الأمر أكثر تعقيدًا، كما يعزز الحصول المستمر على الآراء انفتاحًا أوسع ويوطد أكثر علاقات العمل. لا تنس عبارة الشكر بعد أن تتلقى التقييم قد يكون من الصعب في بعض الأحيان أن تتلقى تقييمًا لك، وخاصةً في ما يتعلق بالنقد البناء، مع ذلك فكرّ بالأمر دائمًا على أنه لصالحك؛ وكما تعلم، إبداء رأي صريح ليس أمرًا سهلًا، لذلك عليك أن تقدّر هذه الآراء عند وصولها. حلقة تبادل الآراء مع الموظفين فعّل منظومة تبادل الآراء من خلال حلقات العمل المتتالية، إذ عليك إدراج النقاط التي نوقشت في آخر تقييم لطاقمك واستدركها في اللقاء التالي. تذكر أن تبقى موضوعيًا إن أردت تأسيس حلقة تبادل آراء مع موظفيك، وتدرب على الاستماع الفعّال لتأخذ صورة كاملة عن الموضوع. قابل موظفيك شخصيًا ليكون تبادل الرأي ذا صبغة خاصة وشفافًا، إذ سيساعدك هذا -حتى لو كان افتراضيًا-، فسيساعدك في توضيح نقاط وملاحظات الاختلاف، والتي لا يمكن فعلها عن طريق البريد الإلكتروني أو المحادثة الكتابية. ما الفرق الذي يحدثه تبادل الآراء مع الموظفين؟ تنبع أهمية تبادل الآراء من منطلق تأثيرها المباشر على تقرير المديرين والعلاقات وعلى الشركة عمومًا. ولا بد من معرفة فوائد تبادل الآراء وأنواع ردود الفعل على سلوكهم المهني ومتى ينبغي إبداء الرأي أو ردة الفعل إن قررت أن تنشئ منظومةً ناجحةً لتبادل الآراء في شركتك. إسأل أخيرًا موظفيك عن آرائهم، وكوّن حلقات لتبادل الآراء في مكانها الصحيح لأنها أمور حاسمة لتأسيس علاقات عمل جيدة مع طاقمك وحيويّة لنجاح شركتك. ترجمة -وبتصرف- للمقال Importance of employee feedback لصاحبته Rachel Steben. اقرأ أيضًا الدليل الشامل للمديرين حول كيفية إعطاء الملاحظات للموظفين كيف تمنح الموظفين التقييم السلبي دون أن تثبط اندفاعهم مجموعة أفكار فعالة لتحسين مشاركة الموظفين والتواصل معهم ما يتوقعه الموظفون من المديرين وفقا لآراء الموظفين
-
نتحدث في هذا المقال عن بعض المشاكل التي يتعرض لها مستخدمو محرك الألعاب جودو Godot 4 عند محاولة العمل على عتاد لا يدعمه محرّك اﻷلعاب. فإن كنت تعمل على أجهزة حواسيب مصنّعة قبل عام 2013، فقد لا تملك برامج تشغيل العتاد Vulkan حيث تدعم هذه الأجهزة OpenGL 3.0 فقط من أجل عرض الرسومات ثلاثية الأبعاد على حاسوبك. وبالتالي إذا حاولت تشغيل محرك الألعاب جودو 4 ضمن بيئة عمل وهمية VirtualBox، ففي هذه الحالة قد تصادفك بعض العقبات. وسنوضح لك في هذا المقال طريقة للالتفاف على تلك المشاكل والعقبات وسبل حلها، فإذا كانت لديك أي مشكلات في التعامل مع إقلاع محرك ألعاب جودو 4 على جهازك تابع معنا قراءة هذا المقال. أين تكمن المشكلة في جودو 4؟ لنفترض أن ثبّت محرك ألعاب جودو 4 وأنت متحمس بالفعل لبدء العمل على صناعة لعبتك الإلكترونية، ثم نقرت نقرة مزدوجة على أيقونة البرنامج، وفوجئت بطهور رسالة خطأ تخبرك بفشل تهيئة برنامج تشغيل بطاقة الفيديو لديك لأنها لا تدعم Vulkan أو OpenGL كما هو موضح في الصورة التالية: لحل هذه المشكلة أمامك خيارات سنشرحهمها في الفقرات التالية. تحديث برامج تشغيل العتاد أو الالتفاف على الموضوع لديك اﻵن خياران، الأول هو أن تحدّث برنامج تشغيل بطاقة الفيديو لديك من خلال التوجه إلى موقع الويب الخاص بمصنع بطاقة العرض لديك، ومن ثم تنزيل وتثبيت آخر إصدار لهذه البطاقة. وفي حال لم يكن الخيار الأول متاحًا لديك، يمكن في هذه الحالة فتح محرر سطر اﻷوامر Command prompt أو الطرفية على جهازك ثم تكتب الأمر Godot، بعدها ابحث عن الملف التنفيذي للمحرك جودو، ثم شغله بعد إضافة الوسيط التالي لأمر التشغيل كما يلي: >Godot_v4.2.1-beta3_mono_win64.exe --rendering-drive opengl3 كما هو هو مبين في الشاشة التالية: ستعمل هذه الحيلة في أغلب اﻷحيان وسيُحمّل برنامج جودو ويعمل بشكل صحيح على جهازك. حل مشكلة النقر على زر التشغيل Play قد يبدو كل شيء على ما يرام حتى الآن، لكن قد تفاجئ بعد أن تنقر على زر التشغيل، بظهور رسالة الخطأ نفسها من جديد. لا تقلق يمكنك أيضًا إصلاح هذا الأمر من خلال الانتقال إلى القائمة مشروع Project ثم اختيار إعدادات المشروع Project Settings وبعدها ثم بتفعيل الخيار إعدادات متقدمة Advanced Settings كما في الصورة التالية. بعد أن تظهر لك النافذة أعلاه انتقل ذلك إلى قسم المحرر Editor ثم اختر الخيار تشغيل Run ثم اجعل قيمة المتغير Main Run Arguments كما يلي: rendering-drive opengl3-- وانقر بعد ذلك على زر إغلاق Close ومن المفترض أن يعمل زر التشغيل بشكل صحيح ودون أي مشكلات. خطوات إضافية للعمل على VitrualBox أو على جهاز محدد إن كنت تعمل على الجهاز الافتراضي VirtualBox، أو لم تنجح الخطوات السابقة لحل المشكلة، عليك في هذه الحالة اتباع بعض الخطوات الإضافية. انتقل إلى المتصفح وحمّل برامج تشغيل العتاد Mesa dist Windows في حال كان نظام تشغيل حاسوبك هو ويندوز Windows، أما إن كنت تعمل على إحدى توزيعات نظام التشغيل لينكس Linux فلن تحتاج إلى ذلك. حمّل اﻹصدار MingW من برنامج تشغيل العتاد Mesa وبرنامج ضغط الملفات 7-Zip الذي سوف تحتاجه لاستخراج ملفات برنامج تشغيل العتاد. عند اكتمال عملية التنزيل انتقل إلى مجلّد تنزيلات downloads، ثم استخرج الملفات باستخدام البرنامج 7-zip ثم افتح المجلد الناتج وشغّل الملف System Wide Deploy الذي سيخبرك بأنه سيثبّت برامج تشغيل العتاد OpenGL الخاص بالحواسب المكتبية. اختبار برامج تشغيل العتاد عليك تاليًا اختبار كلا برنامجي تشغيل العتاد OpenGL الخاص بسطح المكتب، ومايكروسوفت OpenGL على DirectX 3D12. سيعمل برامج تشغيل العتاد الأول على المعالج المركزي CPU وسيحاول الثاني العمل على المعالج الرسومي GPU. تشغيل جودو 4 عد مجددًا إلى محرر سطر اﻷوامر واكتب الأمر التالي: Godot –rendering-driver opengl3 ويجب أن يعمل جودو كما هو مطلوب، وتذكر أن ما فعلناه هنا هو الالتفاف حول المشكلة، فلا تتوقع أداءً استثنائيًا! لكن على اﻷقل ستشغّل محرك ألعاب جودو 4 بصورة صحيحة. أما إن كنت تعمل على توزيعة لينكس منت Mint، فلن تحتاج لعملية الالتفاف تلك، وسيعمل جودو حتى على العتاد غير المدعوم لأن برنامج تشغيل العتاد Mesa مضمّن معه. الخلاصة قد يكون تشغيل محرك الألعاب جودو 4 على عتاد لا يدعمه أمرًا صعبًا على مطور الألعاب الإلكترونية، لكن حل هذه المشكلة ليس مستحيلًا! كل ما عليك هو تجربة الخطوات التي شرحناها في المقال وتستأنف العمل على جودو، وإن واجهتك أي مشكلة في التعامل مع محرك الألعاب جودو لا تتردد في طرحها في قسم التعليقات أسفل المقال لنساعدك على حلها. ترجمة -وبتصرف- للمقال Making Godot 4 work on (some)unsupported hardware اقرأ أيضّا مدخل إلى محرك الألعاب جودو Godot تعرف على محرر محرك اﻷلعاب جودو Godot تعرف على أشهر محركات الألعاب Game Engines
-
يبدي مجال التجارة الإلكترونية تنافسيةً واضحةً في هذه الفترة، لهذا لابد من تطوير استراتيجية عصرية لتسويق علامتك التجارية كي تبرز عن بقية منافسيك. إذ في حال لم تُعِر انتباهًا كافيًا لأهمية علامتك التجارية، فسيغدو متجرك الإلكتروني نسخةً عن بقية المتاجر الأخرى؛ بينما سيمنح التسويق الجيد لعلامتك الخاصة متجرك هويةً فريدةً ويساعدك على بناء حلقة مستقرة من المتابعين مقارنةً ببقية منافسيك. وبالطبع ستكمن صعوبة الأمر في التطبيق. يُعَد الترويج لعلامة تجارية من أصعب نواحي إدارة الأعمال والتسويق. ونظرًا لتوجّه العملاء افتراضيًا إلى التسوق الإلكتروني مقارنةً بالتقليدي في أيامنا هذه، فلا بد أن تُعزز المتاجر الإلكترونية وجودها من خلال إرساء علامات تجارية قوية وفريدة وإيصال الرسائل المناسبة. سيقودك هذا الدليل عبر عملية ربط متجرك بعلامة تجارية إلكترونية خطوةً بخطوة، وسيمنحك الأساس اللازم لتكوين علامة ناجحة. 1. سوّق للمنتجات التي تثق بها لن يكون من السهل تطوير رؤية واثقة وفعّالة لعلامة تجارية ما لم تكن مقتنعًا ومتحمّسًا للمنتجات التي تبيعها. لهذا من الضروري عندما تخطط لإطلاق علامتك التجارية الإلكترونية أن تفكّر مليًا بما ستبيعه وكيف. وتأكد أن زوار وعملاء متجرك سيشعرون بك عندما لا تكون متحمسًا للمنتجات التي تسوقها، وعندما ينتابهم هذا الشعور، سيحجمون غالبًا عن الشراء. إنّ أهمية تقييم إمكانية تصريف المنتجات توازي في الأهمية فكرة ثقتك بما تسوّق؛ فلا يمكنك حرفيًا أن تطلق متجرًا إلكترونيًا لتبيع ما لا يريده أحد. لن يؤثر ذلك سلبًا على قدراتك المالية، بل سيجعل تجربتك مكلفةً وبلا جدوى، ولهذا السبب لا بد أن تكون منتجاتك مناسبةً لك وللسوق الذي تخطط للتوجه إليه، سواءً بعت منتجات من تصميمك أو اختراعك، أم سوّقت لمنتجات مزوّد آخر، وهنا عليك أن تتأكد من قدرتك على الوثوق بجميع الأطراف التي تعتمد عليها. مغزى الكلام، أنه لا بد من تفحّص سلسلة التوريد التي تزوّدك بالمنتجات بعناية، بغية التأكد من جودتها ابتداءً بمرحلة التصنيع وصولًا إلى يد المستهلك. 2. حدد السوق الذي تستهدفه إنّ أهمية تحديد الفئة التي تستهدفها لعرض منتجاتك لا تقل أهميةً عن فهمك لطبيعة المنتجات التي تبيعها، فالأسواق المختلفة تتطلب مقاربات تسويقية مختلفة، وستخفق في تحقيق الأثر المطلوب إن لم تدرك تمامًا في مقاربتك الخصائص المميزة للسوق المستهدف وسماته؛ فكلما جمعت معلومات أكثر عن الفئة المستهدفة، ستركّز بفعالية أكبر على طريقة التسويق التي تتبناها. لبعض المنتجات سوق واضح خاص بها، فهناك مثلًا منتجات قد تكون خاصة بالرجال وأخرى بالنساء، لكن الأمر ليس بهذا الوضوح دائمًا. إن كانت منتجاتك متاحةً في سوق واسع التنوع، فمن الأفضل أن توجّه نشاطك التسويقي وعلامتك التجارية لتختص بفئة محددة من العملاء، وستكون هذه المقاربة شديدة الأثر لأنها تضعك في مركز السوق الذي تلبي متطلباته. يسعى بعض المسوقين الإلكترونيين في البداية إلى بيع منتجاتهم إلى أوسع شريحة ممكنة من العملاء، ثم يجرون بعد ذلك بعض الأبحاث ليحددوا الفئة التي يبيعونها. وبصرف النظر عن الطريقة التي تحدد بها الشريحة التي تستهدفها من العملاء، عليك أن تركز على الميزات الخاصة لهذه الشريحة بمجرد أن تكوّن فكرة كاملة عن تكوينها. ونقولها مجددًا: كلما عرفت أكثر، سهل عليك عملك. من أهم المعايير التي ينبغي الانتباه لها في الفئة المستهدفة ستجد العمر والجنس ومعدّل الدخل. ستحدد هذه المعايير الثلاثة أكثر من غيرها أشكال التسويق التي يستجيب لها العملاء، ونوع المنتجات التي يُرجَّح أن يشتروها. وحالما تتفهم هذه المعايير، ستتمكن من البحث بعمق عن ميزات أخرى لهذه الفئة، مثل القيم التي يؤمنون بها واهتماماتهم والأمور التي تُعَد مصدر إلهام لهم. ستساعدك هذه السمات على توجيه علامتك التجارية التي تختارها لمتجرك الإلكتروني بدقة أكبر. 3. أبدع الأفكار الجديدة عندما تقرر طبيعة المنتجات التي تسوق لها وكيف ستبيعها، يمكن أن تبدأ عملك بثقة. يجد الكثير من المهتمين في هذا المجال أنّ تحديد الفئة المستهدفة والتحقق من سلامة السلسلة التي تسلكها المنتجات أمرًا مرهقًا، لكنه ضروري. عندما تنهي الخطوات السابقة، ستكون مستعدًا لما يُدعى بالتفكير الإبداعي والترويج بالطريقة الأكثر فاعلية لبيع منتجاتك إلى السوق المستهدف. وتُعَد لوحة تجميع الأفكار mood board بمثابة الخطوة المنهجية الأولى للانطلاق في عملية الترويج. وهذه اللوحة هي بشكلها الأساسي مجموعة من الملصقات التي تعرض طبيعة الأفكار والعناصر التي تريد دمجها في علامتك التجارية، علمًا أنّ التصميمات الرقمية للّوحة كثيرة الاستخدام هذه الأيام. تساعد لوحة تجميع الأفكار على البحث عن مصادر إلهام دون أن تضطر لاعتماد أي منها في خلق علامتك الفريدة، بعدها عليك أن تستقي من اللوحة عند اكتمالها شيئًا فريدًا وخاصًا بمتجرك الإلكتروني، لكن ما عليك فعله الآن هو تجميع الأفكار لكي تستخدمها لاحقًا. قد تجد فائدةً في تصميم عدة لوحات لتجميع الأفكار، فالأولى مثلًا تضم جميع العناصر التي تحتاجها لعلامتك التجارية بشكلها النهائي، والثانية لتجميع العناصر التي تحتاجها لتحديد السوق المستهدف، وهكذا. تضم لوحة تجميع الأفكار الخاصة بالسوق المستهدف ما قد يناسب الفئة المستهدفة وليس ما يناسبك شخصيًا من أفكار وتصورات. 4. صمم شعار علامتك التجارية حالما تنتهي من لوحة تجميع الأفكار واثقًا من إدراكك لما ستفعله، سيكون تصميم شعار هو الخطوة التالية. قد يكون التصميم صورةً صغيرةً وبسيطةً ومعبّرةً دون الخوض في التعقيدات، ولا بد أن تضع في بالك كل الأشياء التي تعلمتها من المراحل السابقة. قد لا يتسع شعار واحد لكل الأفكار والمفاهيم التي تراها مهمةً في تعريف طبيعة عملك وتأسيس علامتك التجارية الفريدة، لكنك تستطيع بشيء من التفكير المتأني أن تدمج الكثير منها. إنّ اختيار الشعار هو الخطوة الأكثر تأثيرًا من خطوات الترويج لعلامة تجارية، ومن الضروري أن تنجزها بالشكل الصحيح. لا تخشَ وضع تصاميم مختلفة ومن ثم تختار من كل تصميم ما تراه مميزًا ليكون جزءًا من التصميم النهائي. وإن رأيت بأنك لن تستطيع أن تصمم بنفسك شعارًا مؤثرًا، فلا تتردد باستشارة مختصين في هذا المجال. وإذا لاحظت، حتى الشركات الضخمة مستعدة لإنفاق ملايين الدولارات في تصميم شعارات قد لا تبدو للعين غير الخبيرة معقدة أبدًا. بالرغم من أنه حتى أبسط الشعارات في واقع الأمر هي نتيجة لعدد هائل من المداولات والتقييمات. 5. صمم موقع ويب متميز سيكون لموقع الويب الذي تصممه وقع خاص على الطريقة التي يتقبل بها الناس العلامة التجارية لموقعك، إذ ينبغي أن يكون شعار المتجر دائمًا في مقدمة موقعك ويشغل مركز الصفحة وأن يكون مرئيًا دائمًا دون أن يزعج الزوّار. تذكر أن الغاية الرئيسية من تأسيس علامة تجارية هو التميز عن منافسيك، فإن كان موقعك نسخةً عن متجر إلكتروني آخر أو كان له مظهرًا نمطيًا شائعًا، فسيقل الاهتمام بعلامتك التجارية أو ستخسرها إلى الأبد. إن لم تكن واثقًا من قدرتك على بناء موقع ويب بنفسك، يمكنك البحث في العديد من المنصات التجارية الإلكترونية التي تتيح لك إمكانية إنشاء متجر دون أي معرفة مسبقة بكتابة الشيفرات وتصميم المواقع. وسواءً اخترت تصميم موقعك بنفسك أو من خلال منصات التجارة الإلكترونية، لا بد من تصميمه بما يتلاءم مع خصائص العلامة التجارية لمتجرك، وتذكر أنّ العلامة التجارية أكثر من مجرد مفهوم بصري وأنّ الشعار جزء هام جدًا منها، لكنه يبقى جزءًا فقط. لا بد أيضًا من تنسيق الكلمات التي تتقدم بها إلى جمهورك وطريقة عرض منتجاتك بما يتلائم مع علامتك التجارية، فلا تقلل أبدًا من التأثير الكبير الذي قد تحدثه العلامة التجارية على نجاح متجرك الإلكتروني. تذكر دائمًا أن المتاجر التي لا يستغرق التخطيط لإطلاقها وتحديد مزاياها وعلامتها التجارية الوقت الكافي ستختفي بسرعة. لهذا ميّز نفسك عن منافسيك بإبداعك علامة تجارية قوية ومستقلة. ترجمة -وبتصرف- للمقال E-Commerce Store Branding- A step-by-step Guide. اقرأ أيضًا الخطوات الابتدائية لإنشاء متجرك الإلكتروني: عنوان المتجر وحجز النطاق (Domain) العلامة التجارية وأهميتها في قرار الشراء - مكونات العلامة التجارية كيفية تأسيس علامة تجارية وأساسيات تسويقها
-
تحدثنا في مقال سابق عن التنسيقات الأساسية للنصوص وخطوط الكتابة في CSS، وسنتعمق في مقالنا هذا في استكشاف خطوط الكتابة المستخدمة في الويب وتفاصيلها، وكيفية استخدام خطوط مخصصة في صفحاتك لتجعلها أكثر تنوعًا وخصوصية. ننصحك قبل إكمال قراءة المقال أن تطلع على أساسيات لغة HTML ومقال التنسيقات الأساسية للنصوص وخطوط الكتابة في CSS. مراجعة سريعة لعائلات خطوط الكتابة يمكن التحكم بالخط المستخدم في كتابة محتوى HTML باستخدام الخاصية font-family التي تأخذ اسم عائلة خط واحد أو أكثر كقيم لها. وبهذا يبحث المتصفح عند عرض صفحة الويب ضمن قائمة الخطوط المتوفرة في نظام التشغيل حتى يجد العائلة المطلوبة: p { font-family: Helvetica, "Trebuchet MS", Verdana, sans-serif; } تعمل هذه الطريقة دون مشاكل، لكن خيارات المطورين محدودة عادةً؛ فهنالك عدد محدود جدًا من الخطوط التي يمكن أن تضمن وجودها في جميع أنظمة التشغيل والتي تُعرف بخطوط الويب الآمنة. لهذا بإمكانك وضع قائمة من الخطوط التي تشاء تتبعها بالبدائل الآمنة ومن ثم الخط الافتراضي لنظام التشغيل، لكن سيزيد ذلك طبعًا حمل العمل نظرًا للاختبارات المطلوبة للتأكد من عمل تصميمك وفقًا لكل خط تضعه. خطوط الويب هناك بديلٌ يعمل جيدًا ويعتمد على CSS التي تسمح بتخصيص ملفات لخطوط كتابة تجدها على الويب، بحيث يمكنك تنزيلها واستخدامها مع موقعك، ويعني ذلك أن جميع المتصفحات التي تدعم ميزة CSS هذه ستعرض المحتوى بالخط الذي اخترته تمامًا. نستخدم أولًا الخاصية @font-face في بداية ملف CSS، وتحدد ملف أو ملفات الخطوط التي ينبغي تنزيلها: @font-face { font-family: "myFont"; src: url("myFont.woff2"); } ثم نستخدم بعد ذلك اسم عائلة الخط التي خصصناها ضمن font-face@ كي نطبق الخط المخصص أينما نشاء وبالطريقة التقليدية: html { font-family: "myFont", "Bitstream Vera Serif", serif; } قد تغدو هذه الطريقة أعقد قليلًا، وهذا ما سنناقشه تاليًا. إليك بعض النقاط المهمة التي ينبغي تذكرها جيدًا: لا تكون ملفات الخطوط مجانية غالبًا، وعليك أن تدفع ثمنها أو أن تخضع لشروط رخصة الاستخدام كأن تشير إلى صاحب الخط في شيفرتك أو موقعك، لهذا لا تحاول سرقة الخطوط واستخدامها دون الإشارة الواضحة إلى مصدرها. تدعم كل المتصفحات الرئيسية ملفات الخطوط من نوع WOFF/WOFF2 (خطوط ويب مفتوحة التنسيق بنسختيها الأولى والثانية)، وتدعم كذلك المتصفحات الأقدم مثل IE9 (المنتشر منذ عام 20111) ملفات الخطوط WOFF. تدعم خطوط WOFF2 مواصفات TrueType و OpenType كاملةً بما في ذلك الخطوط المتغيرة variable fonts والخطوط الملونة chromatic fonts ومجموعات الخطوط font collections. طريقة ترتيب ملفات الخطوط مهمة، فلو زوّدت المتصفح بعدة ملفات للخطوط كي ينزّلها، سيختار المتصفح أول ملف قادر على تفسيره، لهذا لا بُد من وضع الخطوط التنسيقات المفضّلة في البداية -أي WOFF2- تليها التنسيقات الأقدم. فعندما لا يفهم المتصفح تنسيقًا، سينتقل إلى التنسيق الذي يليه في القائمة. إذا أردت العمل مع المتصفحات القديمة، عليك تضمين التنسيق EOT (النمط المفتوح المضمّن Embedded Opentype) أو التنسيق TrueType Font -أو اختصارًا TTF- أو تنسيق SVG. وسنتعلم في هذا المقال استخدام Fontsquirrel Webfont Generator للحصول على الملفات المطلوبة. ملاحظة يمكنك استخدام محرّر خطوط فايرفوكس Firefox Font Editor لفحص وتغيير الخطوط المستخدمة في صفحتك فيما ومعرفة إن كانت خطوط ويب صالحة أم لا. تطبيق عملي: مثال عن استخدام خطوط ويب سنحاول بناء مثال توضيحي عن استخدام خطوط ويب. من الصعب طبعًا توضيح ذلك من خلال مثال تفاعلي مدمج، لهذا نطلب منك اتباع الخطوات التي نوردها تاليًا كي تفهم فكرة العملية. حمّل الملفين web-font-start.html و web-font-start.css واستخدمهما بمثابة نقطة انطلاق، ثم ضِف شيفرتك ضمنها (اطلع على المثال المباشر). انسخ الملفين السابقين إلى مجلد جديد على حاسوبك. ستجد في الملف بعض قواعد CSS التي تنسّق التخطيط الأساسي وتنسيق الكتابة في المثال. إيجاد خطوط للكتابة نستخدم في مثالنا خطين من خطوط الويب، أولهما للعناوين والآخر لمتن الصفحة، وعلينا بدايةً إيجاد الملفات التي تضم هذه الخطوط. تُصنع الخطوط من قبل مختصين وتُخزّن ضمن ملفات بتنسيقات مختلفة، وستجد الخطوط ضمن المواقع التالية عمومًا: موزعي الخطوط المجانية: وهي مواقع تتيح للمستخدمين تنزيل خطوط مجانية (مع وجود بعض شروط لترخيص الاستخدام أحيانًا، كأن تشير إلى مصمم الخط). من هذه المواقع نجد: Font Squirrel, [dafont و Everything Fonts. موزعي الخطوط المدفوعة: وهي مواقع تقدم خطوطًا مدفوعة الثمن مثل fonts.com أو myfonts.com ، ويمكنك أيضًا شراء الخطوط من منتجيها مباشرةً، مثل Linotype، أو Monotype، أو Exljbris. خدمات خطوط الكتابة عبر الإنترنت: وهي مواقع تخزّن الخطوط وتسمح لك باستخدامها، مما يسهل العملية برمتها. ابحث الآن عن بعض الخطوط في موقع Font Squirrel وانتقي خطين الأول للعناوين (لا بأس بالخطين nice display أو slab serif font) والآخر أقل لمعانًا وأوضح قراءةً للفقرات. انقر على زر التنزيل عندما تجد الخطوط المناسبة وخزّن الملفات ضمن المجلد نفسه الذي وضعت فيه ملفات الشيفرة. لا تكترث إذا كانت الملفات بتنسيق TTF أو تنسيق Open Type Fonts -أو اختصارًا OTF. فُكَّ ضغط الملفات من حزمتي الخطوط، إذ توزّع ملفات الخطوط عادةً مثل ملفات مضغوطة ZIP تضم ملفات الخطوط ومعلومات الترخيص. وقد تجد ضمن الحزمة أكثر من خط، إذ توزّع بعض الخطوط مثل عائلة واحدة مع عدة توزيعات، مثل الخط الرفيع أو النحيف thin والمتوسط medium والغامق bold والمائل italic والمائل النحيف thin italic وهكذا. ولا نريد منك في هذا التطبيق سوى اختيار خطين مناسبين. ملاحظة: يمكنك في موقع Font Squirrel أن تختار الخطوط من خلال الفئات المتوفرة تحت قسم "إيجاد الخطوط Find fonts" كي تقلل عدد الخيارات المتاحة. توليد الشيفرة المطلوبة نحتاج الآن إلى توليد الشيفرة اللازمة وتنسيقات الخط، لهذا اتبع التعليمات التالية لكل خط: تأكد من أنك حققت متطلبات الترخيص، إذا كنت ستستخدم الخط في مشروع تجاري أو مشروع ويب. انتقل إلى موّلد خطوط الويب Webfont Generator من Fontsquirrel. ارفع ملفات الخطوط باستخدام زر "Upload Fonts". فعّل زر التحقق الذي يحمل العنوان "Yes, the fonts I'm uploading are legally eligible for web embedding". انقر زر "Download your kit" لتنزّل مجموعتك. بعد إكمال المولّد معالجة الملفات، ينبغي أن تكون الملفات جاهزة للتنزيل بتنسيق ZIP، نزّلها في نفس مجلد CSS و HTML، وإذا أردت دعم المتصفحات القديمة، اختر النمط "خبير Expert" في موّلد خطوط ويب، ثم اختر التنسيقات SVG و EOT و TTF قبل تنزيل المجموعة. تحدد خدمات ويب التي تولّد الخطوط حجمًا محددًا للملفات، لهذا فكّر باستخدام أحد الأدوات التالية: sfnt2woff-zopfli للتحويل من ttf إلى woff. fontforge للتحويل من ttf إلى svg. batik ttf2svf للتحويل من ttf إلى svg. woff2 للتحويل من ttf إلى woff2. استخدام الشيفرة في مثالنا استخرج الملفات من الملف المضغوط الذي نزّلته، وستجد ضمن المجلد الناتج العناصر المفيدة التالية: نسختين من كل خط على شكل ملفين يحملان اللاحقتين woff. و woff2. ملف HTML تجريبي لكل خط. حمّل هذه الملفات في متصفحك لترى كيف سيبدو الخط في السياقات المختلفة. ملف تنسيق stylesheet.css يضم شيفرة font-face@ الموّلدة والتي تحتاجها. لاستخدام الخطوط في مثالك، اتبع الخطوات التالية: أعد تسمية المجلد المستخرج من الملف المضغوط باسم بسيط سهل التذكر مثل "fonts". افتح الملف "stylesheet.css" وانسخ القاعدة font-face@ إلى ملف التنسيق "web-font-start.css" الذي أنشأته، وتذكر أن تكون في أعلى الملف وقبل أي قاعدة CSS أخرى، إذ لا بد من إدراج الخطوط قبل أن تتمكن من استخدامها في موقعك. تشير كل دالة من الدوال ()url إلى ملف خط نريد إدراجه ضمن ملف CSS، ولا بد من التأكد من صحة المسار إلى ملف الخط المطلوب، لهذا أضِف العبارة /fonts قبل بداية كل مسار (عدّل ما تراه مناسبًا). يمكنك الآن استخدام هذه الخطوط مثل أي خط ويب آمن أو خط من خطوط نظام التشغيل. إليك مثالًا: @font-face { font-family: "zantrokeregular"; src: url("fonts/zantroke-webfont.woff2") format("woff2"), url("fonts/zantroke-webfont.woff") format("woff"); font-weight: normal; font-style: normal; } font-family: "zantrokeregular", serif; ينبغي أن ينتهي بك المطاف إلى صفحة تجريبية تعرض بعض الخطوط الجميلة، ولأن الخطوط المختلفة قد صُممت بقياسات مختلفة، قد يكون عليك تعديل حجمها والفراغات فيما بين الأحرف والكلمات. ملاحظة: إذا واجهتك أية مشاكل في تنفيذ الأمر بالشكل الصحيح، قارن بين نسختك مع ملفاتنا المكتملة web-font-finished.html و web-font-finished.css. كما يمكنك تحميل الشيفرة من غيت هب GitHub أو تشغيل المثال المنتهي مباشرةً. استخدام خدمات خطوط الكتابة عبر الإنترنت تخزّن خطوط الكتابة عبر الإنترنت خطوط الكتابة وتقدمها لك دون الحاجة إلى استخدام شيفرة font-face@ فكل ما يتطلبه الأمر عادةً هو إدراج سطر بسيط أو اثنين من الشيفرة ضمن موقعك حتى يعمل كل شيء على ما يرام. من الأمثلة على هذه الخدمات نجد Adobe Fonts و Cloud.typography. تعتمد معظم هذه الخدمات على مبدأ الاشتراك ما عدا Google Fonts فهو استثناء عنها كونه خدمة مجانية وخاصة لأعمال الاختبارات السريعة وكتابة الأمثلة التوضيحية Demos. من السهل استخدام معظم هذه الخدمات، لهذا لن نتحدث عنها مطوّلًا، بل سنلقي نظرة على خدمة Google Fonts كي تفهم الفكرة. استخدم لهذا الغرض الملفين "web-font-start.html" و "web-font-start.css" أيضًا بمثابة نقطة انطلاق. انتقل موقع Google Fonts. ابحث عن خط الكتابة الذي تفضله، أو استخدم المرشحات filters أعلى الصفحة لعرض أنواع الخطوط التي ترغب في انتقاء بعضها، ثم اختر خطين منها. لاختيار عائلة خط، انقر على زر العرض ثم انقر على الزر ⊕ إلى جانب الخط. عندما تختار عائلات الخطوط، انقر على زر عرض عائلات الخطوط المختارة "View your selected families" في أعلى يمين الصفحة. انسخ سطر HTML الذي يظهر على الشاشة ثم الصقه في ترويسة ملف HTML. ضعه فوق العنصر <link> الموجود أصلًا كي يجري إدراج الخط قبل أن تستخدمه بواسطة CSS. عليك الآن نسخ تصريحات CSS الموجودة ضمن ملف CSS كما تراه ملائمًا حتى تُطبّق الخط على عناصر HTML. ملاحظة: ستجد نسخةً مكتملةً على google-font.html و google-font.css إذا أردت التحقق من نسختك بالمقارنة مع نسختنا (ألق نظرةً على عملها). تفاصيل أكثر عن قاعدة font-face@ لنستكشف صياغة font-face@ التى ولّدها موقع Fontsquirrel، ستبدو إحدى مجموعات القواعد على النحو التالي: @font-face { font-family: "zantrokeregular"; src: url("zantroke-webfont.woff2") format("woff2"), url("zantroke-webfont.woff") format("woff"); font-weight: normal; font-style: normal; } لنرى ما هو دور كل تصريح: font-family: يُخصّص هذا التصريح لاختيار اسم مناسب يشير إلى الخط، وقد يكون أي شيء تريده طالما أنك تستخدمه بنفس الطريقة ضمن ملف CSS. src: يُخصص هذا التصريح لتحديد المسار إلى موقع ملف الخط الذي تريد إدراجه ضمن شيفرة CSS (الجزء url منه)، ولتحديد تنسيق ملف الخط (الجزء format منه)، أما الجزء الأخر في كل حالة فهو اختياري لكنه تصريح مفيد لأنه يسمح للمتصفحات أن تحدد بسرعة أي خط يمكنها استخدامه. يمكن أن نبني أيضًا قائمةً من التصريحات تفصل بينها الفاصلة ,، ومن المفيد ترتيب هذه التصريحات ابتداءً من التنسيق الأكثر تفضيلًا مثل WOFF2، لأن المتصفح سيحاول تطبيق التصريحات على نحوٍ متسلسل ابتداءً من التصريح الأول. font-weight/font-style: يخصص هذان التصريحان سماكة الخط إضافةً إلى كونه مائلًا أو لا؛ فإذا أدرجت عدة سماكات للخط نفسه، يمكنك حينها تخصيص سماكة ونمط محددين ثم استخدام الخاصيتين font-weight/font-style للتبديل بين السماكات والأنماط المختلفة الأخرى. ملاحظة: يمكنك تخصيص قيم محددة للخاصيتين font-variant و font-stretch من أجل خطوط الويب، كما يمكنك -في المتصفحات الحديثة- تخصيص قيمة للخاصية unicode-range وهي مجال محدد من المحارف التي ترغب في استخدامها خارج مجموعة محارف خط الويب وذلك في المتصفحات التي تدعم ذلك، وستُنزّل حينها هذه المحارف فقط تحاشيًا لتنزيل ما لا حاجة له. الخطوط المتغيرة توجد تقنية جديدة للخطوط تدعمها المتصفحات وتُدعى الخطوط المتغيرة variable fonts، وهي خطوط تسمح بتشارك عدة توزيعات لواجهة خط الكتابة في ملف واحد بدلًا من وجود ملف مستقل لكل اتساع أو سماكة أو نمط. هذا الموضوع متقدم ولن نناقشه في مقالنا. الخلاصة بهذا المقال نكون قد أنهينا سلسلة المقالات التي تتعلق بأساسيات تنسيق النصوص باستخدام CSS. لا تتردد في المشاركة وطرح الأسئلة حول النقاط التي تعتقد أنها غامضة في قسم التعليقات أسفل كل مقال من مقالات السلسلة. ترجمة -وبتصرف- لمقال Web fonts. اقرأ المزيد المقال السابق تنسيق الروابط باستخدام CSS. تنسيق نصوص صفحات الويب باستخدام CSS. التنسيقات الأساسية للعناصر في CSS. أساسيات لغة CSS.
-
نناقش في هذا المقال طريقة تنسيق الروابط في لغة CSS ونعرفك على طرق مختلفة لتحسين مظهرها على موقع الويب الخاص بك، ونعرفك على الحالات المختلفة للروابط وطريقة تنسيقها بفعالية أكبر بالاستفادة من آلية استخدام الأصناف الزائفة pseudo classes في CSS، ونناقش تنسيق الروابط في المواضع المألوفة المختلفة مثل روابط قوائم التنقل، والتبويبات الفرعية tabs. ننصحك قبل إكمال قراءة المقال أن تطلع على أساسيات لغة HTML ومقال التنسيقات الأساسية للنصوص وخطوط الكتابة في CSS. لنلق نظرة على بعض الروابط التشعبية اطلعنا في مقال سابق على أفضل الطرق المتبعة في إنشاء وإضافة الروابط التشعبية إلى صفحات HTML، وسنتابع في هذا المقال استعراض أفضل الممارسات المتبعة في تنسيق هذه الروابط. حالة الرابط لا بد قبل كل شيء من فهم مصطلح "حالة الرابط link state" والذي يدل على الحالات المختلفة التي يكون عليها الرابط. إذ يجري تنسيق الرابط وفقًا لحالته باستخدام الأصناف الزائفة: حالة الرابط Link: وهي الحالة التي يكون فيها للرابط وجهة (وليس مجرد مربط anchor باسم محدد). تُنسّق هذه الحالة من خلال الصنف الزائف link:. حالة رابط جرت زيارته Visited: وهي الحالة التي نُقر فيها على الرابط وخزّن ذلك في ذاكرة المتصفح. تُنسّق هذه الحالة باستخدام الصنف الزائف visited:. حالة رابط عند مرور مؤشر الفأرة Hover: تُنسّق هذه الحالة باستخدام الصنف الزائف hover:. إضافة أيقونات إلى الروابط حالة تركيز الدخول إلى الرابط Focus: وذلك من خلال الانتقال إليه عبر الضغط المتكرر على زر Tab في لوحة المفاتيح أو برمجيًا باستخدام ()HTMLElement.focus وتُنسّق هذه الحالة باستخدام الصنف الزائف focus:. حالة الرابط الفعّال Active: وهي الحالة التي يُنقر فيها على الرابط وتُنسّق باستخدام الصنف الزائف :active. التنسيقات الافتراضية يعرض المثال التالي الطريقة التي يبدو عليها الرابط وطريقة سلوكه الافتراضي، إذ تقوم لغة CSS بتكبير حجم النص وتجعله في المنتصف كي يبرز ويصبح أكثر وضوحًا. ستتمكن في هذا المثال من مقارنة السلوك أو المظهر الافتراضي لروابطك مع سلوك ومظهر الروابط الأخرى المنسّقة باستخدام خاصيات CSS إضافية، إذ يكون للروابط ذات التنسيق الافتراضي الخصائص التالية: تحتوي خطوطًا أسفلها. تكون الروابط التي لم تُزر بعد زرقاء اللون. تكون الروابط التي جرت زيارتها بنفسجية اللون. يغيّر تحريك مؤشر الفأرة فوق الرابط أيقونة الفأرة إلى أيقونة على شكل يد. يحيط إطار بالروابط التي اكتسبت تركيز الدخل. يمكنك نقل التركيز على رابط في الصفحة بالضغط المتكرر على زر Tab (في نظام ماك لا بد من الضغط على زري Option و Tab معًا). تكون الروابط الفعالّة حمراء اللون. حاول أن تنقر وتستمر بالضغط على الرابط. تكون شيفرة HTML للرابط كما يلي: <p><a href="#">A simple link</a></p> أما شيفرة CSS فهي كالتالي: p { font-size: 2rem; text-align: center; } لتعطي النتيجة التالية: ملاحظة: تنقلك جميع روابط الأمثلة إلى أعلى الصفحات التي تضمها، وتُستخدم الأجزاء الفارغة "#"=href لإنشاء أمثلة بسيطة والتأكد أن الأمثلة المعروضة والمحتواة ضمن إطار <iframe> تعمل جيدًا. بقيت هذه التنسيقات كما هي منذ الأيام الأولى للمتصفحات خلال تسعينات القرن الماضي، إذ يتوقع المستخدمون سلوك هذه الروابط بناءً على تلك الألوان وسيؤدي تغييرها إلى إرباك الكثيرين. ولا يعني هذا طبعًا التخلي عن تنسيق الروابط نهائيًا، بل عدم المغالاة في تنسيقها إلى درجة بعيدة عما هو متوقع، فعليك على الأقل أن: تستخدم خط أسفل الرابط فقط للرابط وليس لأية أغراض أخرى، وإن لم تشأ وضع هذا الخط حاول تظليل الرابط بطريقة أخرى. تمنح الرابط طريقةً يتفاعل فيها مع تمرير مؤشر الفأرة فوقه أو عندما ينتقل تركيز الدخل إليه، وأن تجد طريقةً مشابهةً ليتفاعل الرابط عند تفعيله. يمكنك تغيير أو إلغاء هذه التنسيقات باستخدام خاصيات CSS التالية: color: لتلوين نص الرابط. cursor: لتنسيق مؤشر الفأرة، ولا تحاول إلغاء هذا التنسيق ما لم يكن السبب وجيهًا. outline: لتنسيق الإطار المحيط بالكتابة. والإطار أمر مشابهة للحواف borders، إلا أن الحواف ستشغل مساحة من صندوق العنصر على عكس الإطار الذي يتوضّع فوق الخلفية فقط، وللإطار فائدة في تحسين شمولية الوصول، ولا ينبغي إلغاؤه ما لم تجد طريقة أخرى لتدل على رابط تركيز focused link. ملاحظة: لست مضطرًا إلى التقيد بالخاصيات السابقة فقط، بل يمكنك استخدام أية خاصيات تجدها مناسبة لتنسيق الروابط. تنسيق بعض الروابط بعد أن اطلعنا على التنسيقات الافتراضية بشيء من التفصيل، سنلقي نظرةً على مجموعة من التنسيقات النمطية التي نتخذها بمثابة قاعدة انطلاق ثم نملؤها بالقواعد التي نريد: a { } a:link { } a:visited { } a:focus { } a:hover { } a:active { } لترتيب القواعد في الشيفرة السابقة أهميته لأن تنسيقات الروابط تُبنى فوق بعضها بعضًا؛ إذ ستُطبّق مثلًا التنسيقات ضمن القاعدة الأولى على كل القواعد التي تليها، وعندما يُفعّل الرابط، يستجيب غالبًا إلى تمرير مؤشر الفأرة. لهذا، لو وضعت القواعد بترتيب خاطئ وحاولت تغيير نفس الخاصيات في كل قاعدة، فلن يعمل التنسيق كما تتوقع. إليك هذه العبارة لتتذكر الترتيب الصحيح لكتابة القواعد "LoVe Fears HAte" حيث يشير حرف L إلى حالة الرابط Link وحرف V إلى الحالة Visited …إلخ. لنضع الآن بعض التنسيقات ضمن القواعد التي رتبناها قبل قليل: body { width: 300px; margin: 0 auto; font-size: 1.2rem; font-family: sans-serif; } p { line-height: 1.4; } a { outline: none; } a:link { color: #6900ff; } a:visited { color: #a5c300; } a:focus { text-decoration: none; background: #bae498; } a:hover { text-decoration: none; background: #cdfeaa; } a:active { background: #6900ff; color: #cdfeaa; } إليك شيفرة HTML البسيطة التالية كي نطبّق عليها التنسيقات: <p> There are several browsers available, such as <a href="#">Mozilla Firefox</a>, <a href="#">Google Chrome</a>, and <a href="#">Microsoft Edge</a>. </p> ستكون النتيجة على النحو التالي: ما الذي فعلناه إذًا؟ يبدو مظهر الروابط مختلفًا عن التنسيق النمطي، لكنه يقدّم تجربةً مماثلة يفهم من خلالها الزائر ما الذي يحدث: لن نناقش أول قاعدتين فهما واضحتان تمامًا. تستخدم القاعدة الثالثة المحدد a للتخلص من إطار الرابط، والذي يختلف التعامل معه من متصفح لآخر. استخدمنا بعد ذلك المحددين a:link و a:visited لضبط بعض التغييرات اللونية للروابط التي زارها المستخدم والتي لم يزرها بعد ليستطيع التمييز بينهما. استخدمنا في القاعدتين التاليتين المحددين a:focus و a:hover كي لا يظهر خط أسفل الروابط التي يتحرك مؤشر الفأرة فوقها أو تكتسب تركيز الدخل مع تغيير لون الخلفية. استخدمنا أخيرًا المحدد a:active لمنح الرابط لونًا معاكسًا عند تفعيله كي يظهر أن أمرًا مهمًا قد حدث. تطبيق عملي: نسق روابطك الخاصة نطلب إليك في هذا التطبيق العملي أن تستفيد من مجموعة القواعد الفارغة التي تعاملنا معها سابقًا كي تضيف التنسيقات الخاصة بك كي تعرض الروابط بطريقة جميلة. استخدم مخيلتك وابتكر تنسيقات جديدة، فقد تصل إلى شيء جديد جميل ومفيد بقدر ما فعلناه. إذا ارتكبت خطأً يمكنك النقر على الزر "Reset"، وإذا لم تتمكن من فعل شيء، ألق نظرةً على الحل بالنقر على زر "Show solution". إضافة أيقونات إلى الروابط من الممارسات الشائعة عند إنشاء الروابط تزويدها بأيقونة تشير إلى طبيعة المحتوى الذي يقود إليه كل رابط، لهذا سنلقي نظرةً على مثال بسيط يضيف أيقونة إلى رابط خارجي (يقود إلى موقع آخر). يبدو شكل هذه الأيقونة عادةً مثل سهم يشير إلى خارج الصندوق، وسنستخدم أيقونة من موقع icon8.com. إليك شيفرة HTML و CSS التي ستساعدنا على عرض الفكرة: شيفرة HTML: <p> For more information on the weather, visit our <a href="#">weather page</a>, look at <a href="https://en.wikipedia.org/">weather on Wikipedia</a>, or check out <a href="https://www.nationalgeographic.org/topics/resource-library-weather/"> weather on National Geographic</a>. </p> شيفرة CSS: body { width: 300px; margin: 0 auto; font-family: sans-serif; } p { line-height: 1.4; } a { outline: none; text-decoration: none; padding: 2px 1px 0; } a:link { color: blue; } a:visited { color: purple; } a:focus, a:hover { border-bottom: 1px solid; } a:active { color: red; } a[href^="http"] { background: url("external-link-52.png") no-repeat 100% 0; background-size: 16px 16px; padding-right: 19px; } النتيجة: ما الذي حدث إذًا؟ سنتجاوز توضيح أغلب شيفرة التنسيقات لأننا تحدثنا عنها قبل قليل وننتقل إلى القاعدة الأخيرة المهمة. لقد وضعنا صورة خلفية مخصصة للرابط وهي أيقونة الموقع الخارجي، وبنفس الطريقة التي اتبعناها في إضافة نقاط مخصصة إلى القوائم في المقال السابق. لكننا استخدمنا هنا الخاصية المختصرة background بدلًا من ضبط كل خاصية على حدى، كما ضبطنا مسار الصورة واستخدمنا القيمة no-repeat كي لا تظهر سوى نسخة واحدة من الصورة. ضبطنا كذلك موقع الصورة كي يكون 100% إلى يمين النص دون أن يكون لها هامش علوي 0px. استخدمنا أيضًا الخاصية background-size لتحديد أبعاد الصورة. ومن الأفضل عمليًا أن نختار صورة أكبر ثم نعيد ضبط أبعادها كما يتطلبه صفحات ويب المتجاوبة. لن تعمل هذه الطريقة طبعًا على المتصفحات الأقدم من IE9، لهذا عليك أن تغير أبعاد الصورة بنفسك ثم تستخدمها، إذا أردت دعم تلك المتصفحات. ضبطنا أخيرًا قيمة الحاشية من جهة اليمين باستخدام الخاصية padding-right كي نعطي صورة الخلفية مساحة كافية لتظهر دون أن تتداخل مع النص. كلمة أخيرة: كيف لنا أن تختار فقط الروابط الخارجية لتنسيقها بهذا الشكل مع وجود روابط داخلية؟ إذا كتبت عناوين روابط HTML بالشكل الصحيح، عليك في هذه الحالة استخدام عناوين URL المطلقة للروابط الخارجية، وسيكون من المفيد استخدام العناوين النسبية للروابط الداخلية (كما في الرابط الأول في المثال السابق). لهذا السبب ستظهر العبارة "http" في العناوين الخارجية فقط (كما في العنوانين الثاني والثالث في المثال السابق)، وعندها يمكننا استخدام محدد الخواص التالي ["a[href^="http الذي يحدّد عن عناصر <a> ولكن فقط التي تمتلك الخاصية href مع قيمة تبدأ بالكلمة http، وهذا كل مافي الأمر. حاول أن تعود إلى التطبيق العملي السابق وأن تطبق هذه التقنية. ملاحظة: قد تبدو قيمة الخاصية href في مثالنا غريبة فقد استخدمنا روابط وهمية لا تنقلك إلى أي مكان، والسبب في ذلك أنك ستتمكن من تحميل هذه الروابط ضمن المحرر التفاعلي لو كانت حقيقية وبالتالي ستفقد الشيفرة الموجودة. ملاحظة: لا تقلق إن لم تكن لديك معرفة بالخلفيات أو بتصميم الويب المتجاوب فقد شرحناها في مقالات أخرى يمكنك الاطلاع عليها. تنسيق الروابط على هيئة أزرار يمكنك استخدام الأساليب التي خبرتها حتى الآن في مقالنا بطرق أخرى، حيث يمكنك استخدام حالة تمرير مؤشر الفأرة مع عناصر أخرى مثلًا وليس بالضرورة مع الروابط، وقد ترغب أن تتفاعل الفقرات وعناصر القوائم وغيرها مع مرور مؤشر الفأرة فوقها. ومن الشائع أيضًا تنسيق الروابط لتبدو مثل الأزرار في بعض الحالات، كما في قائمة التنقل ضمن الموقع، إذ تُوصّف عناصر القائمة على هيئة روابط وتُنسّق بعدها لتبدو مثل مجموعة من أزرار التحكم التي تنقل المستخدم من صفحة إلى أخرى في الموقع نفسه. لنرى كيف نفعل ذلك. إليك شيفرة HTML: <nav class="container"> <a href="#">Home</a> <a href="#">Pizza</a> <a href="#">Music</a> <a href="#">Wombats</a> <a href="#">Finland</a> </nav> وشيفرة CSS: body, html { margin: 0; font-family: sans-serif; } .container { display: flex; gap: 0.625%; } a { flex: 1; text-decoration: none; outline: none; text-align: center; line-height: 3; color: black; } a:link, a:visited, a:focus { background: palegoldenrod; color: black; } a:hover { background: orange; } a:active { background: darkred; color: white; } ستكون النتيجة على النحو التالي: نُعرّف في شيفرة HTML عنصر قائمة التنقل <nav> التي تمتلك صنف التنسيق "container". تضم هذه القائمة الروابط المطلوبة، بينما تُنسق شيفرة CSS القائمة والروابط معًا. تنص القاعدة الثانية على ما يلي: الحاوية هي Flexbox: أي أن العناصر ضمنها مرنة، وتتوضع على نحوٍ متجاور حتى تملأ المساحة المخصصة لها. ستكون المسافة بين العناصر 0.625% من اتساع القائمة. تُنسِّق القاعدة الثالثة الروابط: يعني التصريح flex: 1 أن اتساع العناصر سيكون مضبوطًا كي تشغل جميعها المساحة المخصصة للحاوية. ألغينا الخط أسفل الرابط text-decoration والإطار الذي يحيط به outline عند انتقال التركيز إليه، كي لا يفسدا مظهر الأزرار. تُستخدم التصريحات الثلاثة الأخيرة لتوسيط النص ضمن الرابط، وضبط ارتفاع العنصر على القيمة 3 عبر الخاصية line-height لمنح الرابط بعض الارتفاع والمساعدة على توسيط النص عموديًا، وأخيرًا ضبط لون النص ليكون أسودًا. الخلاصة نأمل أن تكون المعلومات التي قدمناها في مقالنا قد لامست فعلًا ما تحتاجه في تنسيق الروابط، وسننتقل في المقال التالي إلى تفصيل طريقة استخدام خطوط الكتابة المخصصة (أو خطوط الويب كما هو شائع) ضمن موقعك. ترجمة -وبتصرف- للمقال- Styling Links اقرأ المزيد المقال السابق تنسيق القوائم في CSS. HTML و CSS للمبتدئين: مقدمة إلى تنسيقات CSS. أساسيات لغة CSS. تأثيرات حركية على عناصر قوائم HTML باستخدام CSS
-
لا تختلف القوائم lists في سلوكها عن النصوص في المجمل، لكنك ستجد بعض خاصيات CSS مخصصة للقوائم لا بد من الإطلاع عليها، والاطلاع على أفضل الممارسات في تنسيقها وهذا ما سيعرضه هذا المقال. ننصحك قبل إكمال قراءة المقال أن تطلع على أساسيات لغة HTML ومقال التنسيقات الأساسية للنصوص وخطوط الكتابة في CSS. مثال عن قائمة بسيطة حتى نبدأ العمل سنعرض مثالًا عن قائمة بسيطة، وخلال تقدم المقال سنلقي نظرةً على القوائم المرتبة وغير المرتبة وقوائم الوصف التي تتمتع بميزات تنسيقية متشابهة إضافةً إلى ميزات مخصصة لكل منها. يمكنك الوصول إلى المثال بشكله الأصلي غير المنسّق عبر غيت هب GitHub والحصول على الشيفرة المصدرية. <h2>Shopping (unordered) list</h2> <p> Paragraph for reference, paragraph for reference, paragraph for reference, paragraph for reference, paragraph for reference, paragraph for reference. </p> <ul> <li>Hummus</li> <li>Pita</li> <li>Green salad</li> <li>Halloumi</li> </ul> <h2>Recipe (ordered) list</h2> <p> Paragraph for reference, paragraph for reference, paragraph for reference, paragraph for reference, paragraph for reference, paragraph for reference. </p> <ol> <li>Toast pita, leave to cool, then slice down the edge.</li> <li> Fry the halloumi in a shallow, non-stick pan, until browned on both sides. </li> <li>Wash and chop the salad.</li> <li>Fill pita with salad, hummus, and fried halloumi.</li> </ol> <h2>Ingredient description list</h2> <p> Paragraph for reference, paragraph for reference, paragraph for reference, paragraph for reference, paragraph for reference, paragraph for reference. </p> <dl> <dt>Hummus</dt> <dd> A thick dip/sauce generally made from chick peas blended with tahini, lemon juice, salt, garlic, and other ingredients. </dd> <dt>Pita</dt> <dd>A soft, slightly leavened flatbread.</dd> <dt>Halloumi</dt> <dd> A semi-hard, unripened, brined cheese with a higher-than-usual melting point, usually made from goat/sheep milk. </dd> <dt>Green salad</dt> <dd>That green healthy stuff that many of us just use to garnish kebabs.</dd> </dl> إذا عرضت الشيفرة ضمن متصفح، ثم تصفّحت قائمة العناصر باستخدام أدوات مطوري ويب ستلاحظ بعض التنسيقات الافتراضية المطبّقة: للقائمة غير المرتبة <ul> والمرتبة <ol> هوامش علوية وسفلية بحجم 16px (أو 1em)، وحاشية يسارية padding-left بحجم 40px (أو 2.5em). في حال ضُبطت الخاصية dir من اليمين إلى اليسار right-to-left أو rtl للعناصر ul و ol، سيظهر تأثير الحاشية اليمنية padding-right والتي لها القيمة الافتراضية 40px (أو 2.5em). لا تملك عناصر القائمة <li> مجموعة تنسيقات افتراضية. للعنصر <dl> هوامش علوية وسفلية بحجم 16px (أو 1em) لكن دون حواشي. للعنصر <dd> هامش يساري margin-left حجمه 40px (أو 2.5em). للعنصر <p> الذي أضفناه على سبيل الموازنة هوامش علوية وسفلية بحجم 16px كما هو حال الأنواع المختلفة للقوائم. التعامل مع التباعد في القوائم لا بد من ضبط تنسيق القوائم بطريقة تحافظ على نفس التباعد مع العناصر المحيطة بها مثل الفقرات والصور، وهو ما يُعرف بالتناسق العمودي vertical rhythm، وتحافظ على نفس التباعد الأفقي مع بعضها. يمكنك الاطلاع على المثال الجاهز على غيت هب وتنزيل الشيفرة المصدرية. إليك شيفرة CSS المستخدمة في تنسيق النص وتنسيق التباعد: /* General styles */ html { font-family: Helvetica, Arial, sans-serif; font-size: 10px; } h2 { font-size: 2rem; } ul, ol, dl, p { font-size: 1.5rem; } li, p { line-height: 1.5; } /* Description list styles */ dd, dt { line-height: 1.5; } dt { font-weight: bold; } تعرِّف القاعدة الأولى خط كتابة لكامل الموقع حجمه الأساسي 10px، وترث هذه القاعدة جميع عناصر الصفحة. تعرّف القاعدتين الثانية والثالثة حجم خط نسبي (مقاس بواحدة em) مخصص للعناوين <h> ولأنواع القوائم المختلفة (يرثها أبناء عناصر القائمة) والفقرات. أي سيكون لكل قائمة وفقرة حجم الخط نفسه ونفس التباعد من الأعلى والأسفل مما يحافظ على التناسق العمودي. تخصص القاعدة الرابعة نفس ارتفاع السطر line-height في الفقرات وعناصر القوائم أي سيكون التباعد نفسه بين أسطر الفقرات وعناصر القوائم، ويساعد ذلك في الحفاظ على التناسق العمودي. تُطبَّق القاعدتان الخامسة والسادسة على قوائم الوصف وتعطي نفس ارتفاع السطر بين عناصر القائمة والوصف كما هو الحال بين عناصر القوائم السابقة والفقرات. كما جعلنا الخط سميكًا في الوصف ليتميز عن عناصر القائمة. خاصيات التنسيق المخصصة للقوائم بعد أن ألقينا نظرة على التقنيات المتبعة في تحديد التباعد في القوائم، ننتقل إلى استكشاف بعض الخاصيات التي خصصت لتنسيق القوائم. هناك ثلاث خاصيات لا بد من الاطلاع عليها بدايةً ويمكن أن تُطبّق على القوائم المرتبة <ol> أو غير المرتبة <ul>: list-style-type: تضبط نوع النقاط المستخدمة في القائمة كأن تكون دائرية أو مربعة مثلًا في القوائم غير المرتبة، أو أن تكون أرقامًا أو أحرفًا في القوائم المرتبة. list-style-position: تضبط موضع النقاط في عناصر القائمة إن كانت ستظهر داخل القائمة أو خارجها. list-style-image: تسمح باستخدام صورة مخصصة في قوائم التعداد النقطي بدلًا من المربع أو الدائرة النمطية. تنسيق قوائم التعداد النقطي تُستخدم الخاصية list-style-type كما أشرنا سابقًا لضبط نمط النقاط المستخدمة في القوائم النقطية. وفي مثالنا، سنضبط القائمة المرتبة لتعرض ترقيمًا رومانيًا بأحرف كبيرة: ol { list-style-type: upper-roman; } ستكون النتيجة على النحو التالي: بإمكانك إيجاد خيارات أكثر من خلال الاطلاع على صفحة الخاصية list-style-type على موسوعة حسوب. موضع النقاط تحدد الخاصية list-style-position إن كانت النقاط ستظهر داخل عناصر القائمة أو خارجها قبل بداية كل عنصر. تأخذ الخاصية القيمة الافتراضية outside التي تجعل النقاط خارج عناصر القائمة كما في الصورة السابقة، لكن إن ضبطنا قيمة الخاصية على inside على النحو التالي: ol { list-style-type: upper-roman; list-style-position: inside; } ستكون النتيجة مشابهة للشكل التالي: استخدام صور مخصصة للنقاط تسمح الخاصية list-style-image باستخدام صور مخصصة لنقاط القائمة، وبطريقة بسيطة جدًا: ul { list-style-image: url(star.svg); } لكن هناك محدودية في استخدام هذه الخاصية من ناحية التحكم بموقع النقاط وحجمها وغيرها، لهذا ننصحك باستخدام مجموعة الخاصيات المتعلقة بالخلفية background والتي تعرفنا عليها في مقال سابق، وإليك كيفية استخدامها: ul { padding-left: 2rem; list-style-type: none; } ul li { padding-left: 2rem; background-image: url(star.svg); background-position: 0 0; background-size: 1.6rem 1.6rem; background-repeat: no-repeat; } ما فعلناه في الشيفرة السابقة هو كالتالي: ضبطنا قيمة الحاشية اليسارية padding-left للعنصر <ul> على 20px بدلًا من القيمة الافتراضية 40px، وطبقنا نفس الحاشية على عناصر القائمة غير المرتبة كي تبقى بمحاذاة عناصر القائمة المرتبة وقائمة الوصف على الرغم من وجود حاشية لصور الخلفية ضمن كل عنصر، ولو لم نفعل ذلك، ستتداخل صور الخلفية مع نص العنصر ويبدو الأمر فوضويًا. ضبطنا الخاصية list-style-type على القيمة none كي لا تظهر النقاط بشكلها الافتراضي لأننا سنستخدم خاصيات الخلفية background للتعامل معها. وضعنا نقطة مخصصة قبل كل عنصر في القائمة غير المرتبة، وإليك الخاصيات التي استخدمناها لتخصيص هذه النقطة: background-image: تعطي مرجعًا إلى مسار ملف الصورة التي نستخدمها بصفتها نقطة. background-position: تضبط مكان ظهور الخلفية ضمن العنصر وقد جعلناها في حالتنا 0 0 مما يعني أن النقطة ستظهر أعلى يسار العنصر. background-size: تضبط حجم صورة الخلفية، ومن الناحية العملية لا بد أن يكون حجم صورة الخلفية بحجم عنصر القائمة (أو أكبر أو أصغر بشيء بسيط)؛ وطالما أننا نستخدم الحجم 1.6rem (أو 16px) والذي يتناسب تمامًا مع حجم حاشية مقدارها 20px يمكن أن نضع النقاط ضمن عنصر القائمة دون مشاكل، سيجعل مجموع 16 بكسل مع 4 بكسل من الفراغ الذي يحيط بالنقطة الأمر مناسبًا. background-repeat: تتكرر الصورة افتراضيًا حتى يمتلئ الفراغ المتاح لها، وطالما أننا نحتاج إلى نسخة واحدة من الصورة التي تمثل النقطة، ضبطنا قيمة الخاصية على no-repeat. ستكون نتائج عملنا كما في الصورة التالية: الخاصة المختصرة list-style يمكنك ضبط الخاصيات الثلاث السابقة باستخدام الخاصية المختصرة list-style، إذ تستطيع مثلًا أن تستبدل الشيفرة التالية: ul { list-style-type: square; list-style-image: url(example.png); list-style-position: inside; } بالشيفرة المختصرة التالية: ul { list-style: square url(example.png) inside; } يمكن أن ترتب القيم الثلاث بأية طريقة، كما يمكنك استخدام إحداها أو اثنتين منها أو ثلاثتها. توضع القيم الافتراضية التالية: disc و none و outside في حال لم تُحدد قيمتها صراحة. إذا استُخدمت الخاصية type مع الخاصية image، سيُستخدم النوع type إن لم ينجح تحميل الصورة المحددة. التحكم بطريقة ترقيم القوائم قد تحتاج أحيانًا إلى تطبيق طريقة تعداد مختلفة للقوائم المرتبة المختلفة، كأن تبدأ الترقيم بالرقم 3 مثلًا أو أن تعد مثنى مثنى، لهذا تتيح لك HTML و CSS بعض الطرق لتنفيذ ذلك. الخاصية start تتيح لك الخاصية start الخاصة بعنصر القائمة المرتبة <ol> أن تحدد الرقم الذي تبدأ منه التعداد. إليك مثالًا: <ol start="4"> <li>Toast pita, leave to cool, then slice down the edge.</li> <li> Fry the halloumi in a shallow, non-stick pan, until browned on both sides. </li> <li>Wash and chop the salad.</li> <li>Fill pita with salad, hummus, and fried halloumi.</li> </ol> ستكون النتيجة على النحو التالي: الخاصية reversed تجعل الخاصية reversed التعداد عكسيًا ابتداءً من قيمة محددة. إليك مثالًا: <ol start="4" reversed> <li>Toast pita, leave to cool, then slice down the edge.</li> <li> Fry the halloumi in a shallow, non-stick pan, until browned on both sides. </li> <li>Wash and chop the salad.</li> <li>Fill pita with salad, hummus, and fried halloumi.</li> </ol> ستكون النتيجة على النحو التالي: ملاحظة: إن كان عدد عناصر القائمة أكبر من القيمة التي تحددها الخاصية start عند استخدام التعداد العكسي، فسيستمر التعداد نحو الصفر ومنه إلى القيم السالبة. الخاصية value تسمح لك الخاصيةvalue بتخصيص رقم لكل عنصر من عناصر القائمة. إليك مثالًا: <ol> <li value="2">Toast pita, leave to cool, then slice down the edge.</li> <li value="4"> Fry the halloumi in a shallow, non-stick pan, until browned on both sides. </li> <li value="6">Wash and chop the salad.</li> <li value="8">Fill pita with salad, hummus, and fried halloumi.</li> </ol> ستكون النتيجة على النحو التالي: ملاحظة: حتى لو استخدمت تعدادًا ليس رقميًا للخاصية list-style-type، ستحتاج إلى استخدام القيم الرقمية المكافئة ضمن الخاصية value. تطبيق عملي نطلب منك في هذا التطبيق العملي الاستفادة من الأفكار التي طرحناها في المقال لتنسيق قائمة متداخلة. ستجد ضمن المحرر التفاعلي التالي شيفرة HTML الخاصة بالقائمة ونريد منك أن: تعطي القائمة غير المرتبة تعدادًا نقطيًا. تعطي عناصر القائمة غير المرتبة والمرتبة ارتفاع سطر يعادل 1.5 من حجم خطها. تعطي عناصر القائمة المرتبة نقاط تعداد على شكل أحرف لاتينية صغيرة. تحاول تعديل تنسيق القوائم كما يحلو لك. إن ارتكبت خطأً انقر على زر "reset" ليعود كل شيء كما كان، وإن أردت إظهار الحل الصحيح انقر على الزر "show solution". الخلاصة من السهل تنسيق القوائم إن اعتدت التعامل مع أساسياتها وخاصياتها المميزة، وسننتقل في المقال التالي إلى شرح طريقة تنسيق الروابط التشعبية. ترجمة -وبتصرف- للمقال Styling lists. اقرأ المزيد المقال السابق التنسيقات الأساسية للنصوص وخطوط الكتابة في CSS تنسيق القوائم (Lists) في CSS تعرف على أساسيات لغة CSS هيكلية لغة CSS
-
نحاول في هذا المقال أن نضعك على الطريق الصحيح لإتقان تنسيق النصوص باستخدام CSS. لهذا سنطلعك تدريجيًا وبالتفصيل على أساسيات التنسيق بما في ذلك ضبط حجم الخط وعائلته وتنسيقاته، إضافةً إلى الخاصيات المختصرة، ومحاذاة النصوص وغيرها من التأثيرات، كما سنتعلم ضبط التباعد بين الأسطر والحروف. ننصحك قبل إكمال قراءة المقال أن تطلع على أساسيات لغة HTML وأساسيات لغة CSS. ما الذي يتضمنه تنسيق النصوص من خلال CSS؟ إذا عملت على ملفات HTML أوCSS مسبقًا، فأنت تعرف حتمًا أن النص الموجود داخل العنصر يُوضع ضمن صندوق المحتوى الخاص بالعنصر، إذ يبدأ النص من الزاوية اليسارية العليا لمنطقة المحتوى (أو من اليمينية العليا في اللغات التي تُكتب من اليمين إلى اليسار) وينساب نحو نهاية السطر. حالما يصل النص إلى نهاية السطر ينتقل تلقائيًا إلى سطر جديد وينساب نحو نهاية السطر من جديد وهكذا حتى يُكتب كامل النص ضمن صندوق المحتوى المخصص. إذًا، يسلك المحتوى النصي سلوك سلسلة من العناصر السطرية المتجاورة المرتبة في سطور، ولا تُطبق عملية الانتقال إلى سطر جديد حتى بلوغ نهاية السطر، أو أن تجبرها يدويًا على الانتقال إلى سطر جديد باستخدام العنصر <br>. ملاحظة: إذا لم تكن على دراية عن الأفكار التي طرحتها في الفقرة السابقة، عد إلى مقال نموذج الصندوق Box Model كي تتزود ببعض المعلومات المفيدة عن نظرية النموذج الصندوقي قبل المتابعة في هذا المقال. يمكن تقسيم خاصيات CSS المستخدمة في تنسيق النصوص ضمن فئتين أساسيتين، سنلقي نظرةً عليهما تباعًا في هذا المقال: تنسيقات خطوط الكتابة Font styles: وهي الخاصيات التي تؤثر مباشرةً على خط الكتابة، مثل نوع الخط المطبّق وحجمه وسماكته وغير ذلك. تنسيقات تخطيط النص Text layout styles: وهي الخاصيات التي تؤثر على مقدار المساحات الفارغة وغيرها من ميزات تخطيط النص، التي تسمح مثلًا بتغيير المسافة الفارغة بين الأسطر والحروف، ومحاذاة النص ضمن الحيز المحدد للمحتوى. ملاحظة: تذكّر أن النص الموجود ضمن عنصر سيتأثر بالخاصيات وكأنه كيان واحد، وبالتالي لن تتمكن من اختيار جزء من النص ثم تنسيقه على نحوٍ مختلف إذا لم تغلف هذا الجزء ضمن عنصر مناسب مثل <span>، أو أن تستخدم عنصر زائف مخصص لاستهداف النصوص مثل first-letter::، الذي يختار الحرف الأول من النص الذي يحتويه عنصر ما، أو first-line::، الذي يختار السطر الأول من نص ضمن عنصر، أو selection::، الذي يستهدف النص الذي جرى تحديده من خلال مؤشر الفأرة. خطوط الكتابة سننتقل مباشرةً الآن إلى خاصيات تنسيق خطوط الكتابة من خلال المثال التالي الذي نطبق خلاله بعض خاصيات CSS على شيفرة HTML التالية: <h1>Tommy the cat</h1> <p>Well I remember it as though it were a meal ago…</p> <p> Said Tommy the Cat as he reeled back to clear whatever foreign matter may have nestled its way into his mighty throat. Many a fat alley rat had met its demise while staring point blank down the cavernous barrel of this awesome prowling machine. Truly a wonder of nature this urban predator — Tommy the cat had many a story to tell. But it was a rare occasion such as this that he did. </p> بإمكانك إيجاد المثال في حالته النهائية على غيت هب GitHub، كما يمكنك تنزيل الشيفرة المصدرية أيضًا. الألوان تضبط الخاصية color لون الخلفية لمحتوى العنصر الذي تختاره، وهو عادةً نص، كما تتضمن أشياء أخرى، مثل لون الخط الذي يمر من وسط النص، أو أسفله والذي تضبطه الخاصية text-decoration. تقبل الخاصية color قيمًا بأية وحدات لونية تعرّفها CSS: p { color: red; } تجعل الشيفرة السابقة النص في الفقرة باللون الأحمر بدلًا من اللون الأسود الذي يستخدمه المتصفح افتراضيًا لعرض الفقرات لتظهر بالشكل التالي: عائلات الخطوط يمكنك استخدام الخاصية font-family التي تسمح لك بتخصيص خط أو مجموعة خطوط كي يطبقها المتصفح على عنصر تختاره، ويجب الانتباه إلى أن المتصفح لن يطبق أي خط كتابة ما لم يكن موجودًا على الجهاز الذي يستضيف موقع الويب، وإلا سيستخدم خط الكتابة الافتراضي. إليك هذا المثال البسيط: p { font-family: arial; } تطبق الشيفرة السابقة نوع الخط "arial" على جميع الفقرات النصية في الصفحة، وهو خط كتابة موجود على أي حاسوب. خطوط الكتابة الآمنة على الويب هناك عدد محدد من أنواع الخطوط التي تتوفر عادةً في جمع الأنظمة، وبالتالي يمكن استخدامها دون أن نقلق من تجاهل المتصفح لها. لهذا، دُعيت هذه الخطوط بخطوط الويب الآمنة safe web fonts. يرغب مطورو الويب غالبًا بتخصيص الخطوط التي يستخدمونها لعرض المحتوى النصي في الصفحات، وتكمن المشكلة في إيجاد طريقة معرفة أن خطًا معينًا سيكون متوفرًا على الجهاز الذي يستضيف الصفحة. لن نتمكن من معرفة هذه المعلومة تحديدًا في كل الحالات، لكن تُعرف خطوط الكتابة الآمنة في الويب بأنها متاحة في جميع نسخ أنظمة التشغيل تقريبًا بما في ذلك ويندوز وماك أو إس ومعظم توزيعات لينكس المعروفة وأندرويد وأي أو إس iOS. تتغير قائمة خطوط الكتابة الآمنة مع تغيير أنظمة التشغيل، لكن من المنطقي أن تفكر باستخدام خطوط ويب الآمنة التالية وعلى الأقل حاليًا، إذ زادت شعبية الكثير منها بفضل مبادرة مايكروسوفت التي دُعيت Core fonts for the Web في أواخر التسعينات وبداية الألفية الجديدة: الاسم النمط الأساسي ملاحظات Arial sans-serif يُعدّ أيضًا اختيار نوع الخط "Helvetica" بدلًا من "Arial" من الممارسات الأفضل على الرغم من أن وجهي الخطين متطابقين تمامًا، لكن "Helvetica" يعطي خطًا أكثر وضوحًا رغم كونه أقل توفرًا. Courier New monospace لبعض أنظمة التشغيل نسخة بديلة (ربما أقدم) من الخط "Courier New" يُدعى "Courier". لهذا من الممارسات الأفضل أن تستخدم كليهما مع تفضيل للنوع "Courier New". Georgia serif Times New Roman serif لبعض أنظمة التشغيل نسخة بديلة (ربما أقدم) من الخط "Times New Roman" يُدعى "Times". لهذا من الممارسات الأفضل أن تستخدم كليهما مع تفضيل للنوع "Times New Roman". Trebuchet MS sans-serif لا بد من الانتباه عن استخدام هذا الخط، فهو منتشر بصورةٍ واسعة ضمن أنظمة تشغيل الهواتف المحمولة. Verdana sans-serif ملاحظة: ستجد في كثير من المصادر ومنها cssfontstack.com قوائم لخطوط الويب الآمنة المتاحة على ويندوز وماك أو إس وبالتالي تساعدك في اتخاذ قرار بنوع الخط الذي تستخدمه في صفحاتك. ملاحظة: هناك طريقة لتنزيل خطوط مخصصة لصفحة ويب تسمح لك بتخصيص الخطوط في صفحتك بالطريقة التي تراها مناسبة. هذا الأمر معقد قليلًا وسنناقشه لاحقًا. الخطوط الافتراضية تعرّف CSS خمسة أسماء معممة لأنواع الخطوط هي: serif و sans-serif و monospace و cursive و fantasy. هذه الأسماء معممة جدًا ويمكن أن تختلف واجهات خطوط الكتابة المُستخدمة من هذه الأسماء من متصفح لآخر، ومن نظام تشغيل لآخر. يمثّل هذا الوضع ما يُسمى "سيناريو الحالة الأسوأ worst case scenario"، إذ سيحاول المتصفح جاهدًا في انتخاب خط الكتابة الأكثر قربًا من الخطوط الموجودة، وفعلًا من السهل التعامل مع الخطوط serif و sans-serif و monospace فهي متوقّعة وستكون النتيجة التي يعرضها المتصفح معقولة، بينما يصعب توقع سلوك المتصفح مع الخطين cursive و fantasy لهذا يجدر الحذر عند استخدامها، واختبار العمل باستمرار. تُعرّف الأسماء الخمسة للخطوط على النحو التالي: المصطلح التعريف serif وهي خطوط تنتهي فيها حواف الحروف بنتوءات (وهي تفاصيل صغيرة تظهر في نهاية خطوط الحروف) sans-serif وهي الخطوط التي لا تنتهي حواف الحروف بنتوءات. monospace وهي خطوط يكون لكل المحارف فيها الاتساع ذاته، وتُستخدم عادةً في كتابة وتنظيم الشيفرة، أي لضبط المحاذاة. cursive وهي الخطوط التي يُنوى استخدامها لمحاكاة خط اليد، من ناحية الإنسياب وترابط الأحرف. fantasy وهي الخطوط المُستخدمة لأغراض التزيين. قوائم الخطوط طالما أننا لن نضمن توفر جميع الخطوط التي ننوي استخدامها عن تصميم الصفحات (فحتى خطوط ويب الآمنة قد تخفق أحيانًا)، يمكنك اختيار قائمة من الخطوط font stack ليختار المتصفح منها خطًا. يتضمن ذلك اختيار مجموعة من القيم للخاصية font-family تفصل بينها فواصل ,. p { font-family: "Trebuchet MS", Verdana, sans-serif; } في هذه الحالة، يبدأ المتصفح باختيار الخط الأول من القائمة ليرى إن كان متاحًا على الجهاز فيطبّقه، فإن لم يكن كذلك ينتقل إلى التالي وهكذا. من الجيد تزويد المتصفح بأسماء خطوط معممة مناسبة في نهاية القائمة، فإن لم يكن أي خط من الخطوط التي تريدها متاحًا، يمكن للمتصفح أن يختار حينها على الأقل ما يشابهها. لتوضيح هذه الفكرة، تأخذ الفقرات النصية خط المتصفح الافتراضي "serif" إن لم تكن بقية الخيارات في قائمة الخطوط متوفرة، وهذا الخط غالبًا "Times New Roman"، وهذا لن يخدمك إن كنت تريد خطًا من النوع "sans-serif". ملاحظة: لا بد من إحاطة أسماء خطوط الكتابة المكونة من أكثر من كلمة (أي تحتوي على مسافات بيضاء) بإشارات تنصيص مزدوجتين "" مثل "Trebuchet MS". تحذير: ينبغي اقتباس أي اسم عائلة خطوط يمكن تفسيره عن طريق الخطأ على أنه اسم عائلة معمّم أو كلمة مفتاحية على مستوى CSS. يمكن تضمين أسماء عائلات الخطوط مثل <custom-ident> أو <string>، لكن لا بُد من تضمين أسماء عائلات الخطوط التي من الممكن أن يكون لها نفس قيمة خاصية CSS، مثل خاصية initial أو inherit، أو CSS التي لها نفس أسماء الخطوط المعممة، مثل sans-serif أو fantasy، على أنها سلاسل نصية، وإلا سيُفسّر اسم عائلة الخط على أنه كلمة CSS مفتاحية أساسية مكافئة أو اسم عائلة معمّم. لدى استخدام أسماء العائلات على أنها كلمات مفتاحية، يجب عدم اقتباس أسماء العائلات المعمّمة مثل serif و sans-serif و monospace و cursive وكذلك الأمر بالنسبة لكلمات CSS المفتاحية العامة، إذ لا تُفسّر السلاسل النصية على أنها كلمات CSS مفتاحية. مثال عن قائمة خطوط لنضف إلى مثالنا السابق الخطوط من النوع المعمم "sans-serif": p { color: red; font-family: Helvetica, Arial, sans-serif; } وستكون النتيجة على النحو التالي: حجم الخط اطلعنا في مقال قيم ووحدات CSS على وحدات الطول والحجم التي نستخدمها، ورأينا أن الخاصية font-size التي تضبط حجم الخط قد تأخذ قيمًا من معظم وحدات القياس المستخدمة (بما في ذلك النسب المئوية). لكن أكثر ما ستصادفه من وحدات القياس في تقدير حجم النصوص هي: البكسل px: وهو عدد البكسلات التي تقيس ارتفاع النص، وهي وحدة مطلقة تنتج دائمًا القيمة نفسها لارتفاع الخط في جميع الحالات تقريبًا. em: عندما نضبط حجم الخط على1 em، فهذا يعني أننا نختار للعنصر الذي ننسقه نفس حجم الخط للعنصر الأب (وبدقة أكبر، اتساع الحرف M في الخط المستخدم في تنسيق العنصر الأب). سيكون الأمر مربكًا إذا كانت هناك الكثير من العناصر المتداخلة والمنسقة بخطوط كتابة مختلفة، ومع ذلك فالأمر قابل للتنفيذ كما سنرى تاليًا. لماذا عليّ ذلك؟ سيكون الأمر عاديًا بمجرد أن تعتاد عليه، وستتمكن من استخدام في تحديد أبعاد أي شيء وليس النصوص فقط، ويمكن استخدام واحدة القياس em لتقدير أبعاد جميع العناصر في الصفحة مما يُسهّل الصيانة. rem: وهي واحدة مشابهة لواحدة em، إلا أن 1 rem ستعادل في هذه الحالة حجم الخط المستخدم لتنسيق العنصر الجذري root element وليس العنصر الأب. يسهّل هذا الأمر الحسابات المستخدمة في تقدير الأبعاد المختلفة، لكن قد تعاني إن أردت دعم المتصفحات الأقدم، فلا يقبل المتصفح إنترنت إكسبلور 8 وما دون هذه الواحدة مثلًا. يرث العنصر حجم الخط من العنصر الأب، وتبدأ الوراثة انطلاقًا من العنصر الجذري للصفحة ككل <html>. ويُعد 16px القياس الافتراضي لحجم خط العنصر الجذري في جميع المتصفحات، إذ ستأخذ جميع الفقرات النصية، أو أية عناصر أخرى لا يعطيها المتصفح قيمةً افتراضيةً مخصصة ضمن العنصر الجذري قياسًا نهائيًا قيمته 16px، وتأخذ عناصر أخرى قيمًا افتراضية مختلفة مثل العنصر <h1> الذي يأخذ القياس 2em افتراضيًا وسيكون قياسه النهائي 32px. ستأخذ الأمور منحًى مربكًا أكثر عندما تبدأ تغيير حجم الخط لعناصر متداخلة؛ فلو كان لديك العنصر <article> في صفحتك وضبط حجم الخط فيه على 1.5em (يقابل 24px)، وأردت أن تجعل حجم خط الفقرات ضمن هذا العنصر 20px فما هو الحجم المناسب مقاسًا بواحدة em؟ <!-- 16px القياس الأساسي للعنصر الجذري--> <article> <!-- 1.5em إن كان القياس في هذا العنصر--> <p>My paragraph</p> <!-- 20px كيف أحسب القياس --> </article> لا بد أن تجعل القيمة على النحو 20/24em أي 0.8333 em. فإجراء العمليات الحسابية قد يكون مربكًا بعض الشيء، لهذا عليك الإنتباه عند تنسيق الأشياء. من الأفضل إذًا استخدام rem حيثما أمكن لتبقي الأمور بسيطة وتفادى ضبط حجم الخط font-size للعناصر الحاوية ما أمكن. تنسيق الخطوط وثخانتها وتحويل حالة حروف النصوص وتزيينها تزودنا CSS بمجموعة من الخاصيات التي تغيّر ثخانة النص وتبرزه نذكر منها: font-style: تُستخدم لتحويل النص إلى الشكل المائل أو العكس، وتأخذ القيم التالية (نادرًا ما تستخدمها، إلا إن أردت فعلًا جعل الخط مائلًا لسبب وجيه): normal: يجعل الخط نمطيًا (يلغي الإمالة). italic: يجعل الخط مائلًا إن كان الخط يدعم ذلك، بينما يجعله منحرفًا قليلًا oblique إن لم يدعم الخط ذلك. oblique: يقلّد الإمالة نوعًا ما بجعل الأحرف منحرفة قليلًا عن الوضع النمطي. font-weight: تحدد هذه الخاصية مقدار سماكة أو ثخانة الخط، ولها عدة قيم: "light-" و "normal-" و "bold-" و "extrabold-" و "black-" في حال احتجت إلى ذلك، لكنك لن تستخدم عمليًا سوى "normal" و "bold": normal و bold: تجعل الخط سميكًا أو طبيعيًا. lighter و bolder: تجعل الخط أسمك أو أخف بدرجة واحدة من سماكة العنصر الأب. 100 – 900: قيم عددية لمقدار سماكة خط الكتابة وتقدم طريقة لتحكم أفضل بالسماكة بدلًا من الكلمات المفتاحية. text-transform: تساعدك على تحويل حالة الحروف في النص: none: تمنع أية تحويلات. uppercase: تحوّل جميع الحروف إلى حروف كبيرة. lowercase: تحوّل جميع الحروف إلى حروف صغيرة. capitalize: تحوّل الأحرف الأولى من الكلمات إلى حروف كبيرة. full-width: تكتب أي حرف ضمن مربع ثابت الاتساع (أي يشغل كل حرف نفس المساحة) مما يسمح بمحاذاة المحارف المختلفة مثل اللاتينية والآسيوية مثلًا. text-decoration: تمكّن أو تلغي تزيين النص (تُستخدم غالبًا في إزالة الخط الموجود تحت الروابط التشعبية عند تنسيقها): none: إزالة أي تزيين في النص. underline: يضع خطًا تحت النص. overline: يضع خطًا فوق النص. line-through: يضع خطًا وسط النص. تقبل الخاصية text-decoration قيمًا متعددة إذا أردت إضافة عدة تزيينات في الوقت عينه. إليك مثالًا: text-decoration: underline overline ولا بد من الإشارة إلى أن text-decoration هي خاصية مختصرة للخاصيات text-decoration-line و text-decoration-style و text-decoration-color، لهذا يمكنك استخدام توليفة من هذه التنسيقات لإظهار الأثر المطلوب. إليك مثالًا: text-decoration: line-through red wavy لنلق نظرةً على المثال التالي الذي يضيف خاصيتين من الخاصيات السابقة معًا: html { font-size: 10px; } h1 { font-size: 5rem; text-transform: capitalize; } h1 + p { font-weight: bold; } p { font-size: 1.5rem; color: red; font-family: Helvetica, Arial, sans-serif; } إليك النتيجة: إلقاء الظلال على النصوص يمكن إلقاء الظل على النص باستخدام الخاصية text-shadow التي تأخذ حتى أربعة قيم كما يظهر في المثال التالي: text-shadow: 4px 4px 5px red; أما القيم الأربعة فهي: الإزاحة الأفقية للظل عن النص الأصلي: وتأخذ معظم وحدات قياس الطول والأبعاد المتاحة في CSS، لكن ما ستستخدمه عادةً هو px. تزيح القيم الموجبة الظل نحو اليمين والسالبة إلى اليسار، ولا بد من استخدام هذه القيمة. الإزاحة العمودية للظل عن النص الأصلي: تشابه من ناحية الوظيفة الإزاحة الأفقية إلا أنها للأعلى والأسفل وليست لليمين واليسار، ولا بُد من استخدام هذه القيمة. نصف قطر التمويه blur: وتشير القيم الأعلى إلى أن الظل أوسع انتشارًا، وتأخذ القيمة 0 إن لم تُستخدم (لا يوجد إماهة). يمكن أن تأخذ هذه القيمة أية وحدات لقياس الطول أو الأبعاد في CSS. اللون الأساسي للظل: ويأخذ جميع القيم اللونية في CSS. وإن لم تُستخدم، فسيكون لون الظل افتراضيًا هو اللون الحالي المأخوذ من الخاصية color للعنصر. الظلال المتعددة يُمكن تطبيق عدة ظلال على النص باستخدام عدة قيم منفصلة عن بعضها بفواصل: h1 { text-shadow: 1px 1px 1px red, 2px 2px 1px red; } إذا طبقنا هذا التنسيق على العنصر <h1> على مثالنا السابق ستكون النتيجة على النحو التالي: تخطيط النص لنلقِ نظرةً الآن على الخاصيات التي تؤثر على تخطيط layout النص: محاذاة النصوص تُستخدم الخاصية text-align في محاذاة النصوص ضمن صندوق الحاوية. تأخذ الخاصية القيم التالية التي تعمل بنفس الطريقة التي تستخدمها المحررات النصية النمطية: left: تُحاذي النص إلى اليسار. right: تُحاذي النص إلى اليمين. center: تجعل النص في وسط الحاوية. justify: تجعل النص ممتدًا ذو فراغات مختلفة الأحجام ليجعل اتساع جميع الأسطر في النص متساويًا. قد يبدو مظهر النص سيئًا وخاصةً إذا احتوى فقرات تضم الكثير من الكلمات الطويلة؛ فإذا كنت ستستخدم هذه الخاصية، لا بد من استخدام خاصية أخرى هي hyphens لتوزيع بعض الكلمات الطويلة على سطرين. إذا طبقنا الخاصية text-align: center على العنصر <h1> في مثالنا السابق: html { font-size: 10px; } h1 { font-size: 5rem; text-transform: capitalize; text-shadow: 1px 1px 1px red, 2px 2px 1px red; text-align: center; } h1 + p { font-weight: bold; } p { font-size: 1.5rem; color: red; font-family: Helvetica, Arial, sans-serif; } ستكون النتيجة على النحو التالي ارتفاع السطر تضبط الخاصية line-height ارتفاع كل سطر من أسطر النص، وتأخذ جميع وحدات القياس في CSS إضافةً إلى قيم بدون وحدات unit-less تعمل مثل مضاعفات وهي عمليًا أفضل الخيارات. عند استخدام قيم بلا وحدات سيُحسب جداء حجم الخط font-size في هذه القيمة وتكون النتيجة هي ارتفاع الخط. سيبدو النص أفضل وأسهل قراءة عندما تتباعد الأسطر عن بعضها، ويكون عادةً الفراغ المزدوج (1.5-2) هو التباعد المناسب بين الأسطر، وكي نجعل التباعد بين الأسطر في مثالنا بقيمة 1.6 ما علينا سوى كتابة الشيفرة التالية: p { line-height: 1.6; } وعند تطبيقها على عنصر الفقرة <p> في مثالنا السابق: html { font-size: 10px; } h1 { font-size: 5rem; text-transform: capitalize; text-shadow: 1px 1px 1px red, 2px 2px 1px red; text-align: center; } h1 + p { font-weight: bold; } p { font-size: 1.5rem; color: red; font-family: Helvetica, Arial, sans-serif; line-height: 1.6; } ستكون النتيجة على النحو التالي: الفراغات بين الحروف والكلمات تسمح الخاصيتان letter-spacing و word-spacing بضبط الفراغات بين الحروف والكلمات في النص. لن تستخدمهما كثيرًا، لكنك قد تحتاجهما لإعطاء النص مظهرًا مخصصًا، أو لتحسين مظهر خطوط معينة ذات طبيعة متراصة. تأخذ هذه الخاصية معظم وحدات قياس الأبعاد والأطوال. لإظهار طريقة عمل هاتين الخاصيتين سنطبق تباعدًا بين كلمات وأحرف أول سطر من العنصر <p> في مثالنا السابق: p::first-line { letter-spacing: 4px; word-spacing: 4px; } ثم نصيّر شيفرة HTML التالية: html { font-size: 10px; } h1 { font-size: 5rem; text-transform: capitalize; text-shadow: 1px 1px 1px red, 2px 2px 1px red; text-align: center; letter-spacing: 2px; } h1 + p { font-weight: bold; } p { font-size: 1.5rem; color: red; font-family: Helvetica, Arial, sans-serif; line-height: 1.6; letter-spacing: 1px; } ستكون النتيجة على النحو التالي: خاصيات أخرى تستحق الملاحظة تعطيك الخاصيات التالية فكرةً عن طريقة تنسيق النصوص في صفحات الويب، لكن هناك الكثير غيرها. سنغطي هنا أكثر الخاصيات أهمية، لهذا لا بد من استكشاف طريقة عملها بمجرد أن تتقن الخاصيات التي شرحناها سابقًا: خاصيات تنسيق الخط: font-variant: تبدّل بين الأحرف الصغيرة والنص العادي. font-kerning: تبدل بين وضع التداخل kerning والوضع الطبيعي. font-feature-settings: تبدّل بين ميزات الخطوط من النوع OpenType. font-variant-alternates: تتحكم باستخدام المحارف البديلة لواجهة خط كتابة معين. font-variant-caps: يتحكم باستخدام بدائل المحارف الكبيرة. font-variant-east-asian: تتحكم باستخدام المحارف البديلة لخطوط كتابة اللغات الشرق آسيوية مثل اليابانية والصينية. font-variant-ligatures: تُستخدم للتحكم بكيفية استخدام المحارف المترابطة (محرفين مرتبطين على شكل محرف واحد) والمحارف ذات الحركات. font-variant-numeric: تتحكم باستخدام بدائل محارف الأرقام والأعداد الكسرية وعلامات الترتيب. font-variant-position: تتحكم باستخدام بدائل المحارف التي تشغل مواقع أصغر مثل المحارف التي تُكتب منخفضة أو مرتفعة. font-size-adjust: تعديل الحجم المرئي للخط بمعزل عن حجمه الحقيقي. font-stretch: تُستخدم للتبديل بين النسخ الممتدة stretched الممكنة لخط معين. text-underline-position: يحدد موقع الخط الذي يُرسم أسفل النص عند استخدام القيمة underline للخاصية text-decoration-line. text-rendering: تحاول أن تحسّن في النص عند تصييره. خاصيات تخطيط النص: text-indent: تحدد مقدار الفراغ الأفقي الواجب تركه قبل بداية السطر الأول من النص. text-overflow: تعرّف طريقة تنبيه المستخدم عندما لا يُعرض المحتوى في حالة الطفحان overflow. white-space: تعرّف كيفية التعامل مع المسافات الفارغة وعناصر الانتقال إلى سطر جديد ضمن العناصر. word-break: تحدّد إذا ما كان مسموحًا تجزئة الكلمة عند الانتقال إلى سطر جديد. direction: تعرّف اتجاه خط الكتابة. يتعلق الأمر عادةً بلغة الكتابة ومن الأفضل ترك الأمر للغة HTML كي تتعامل مع هذا الجزء لارتباطه بسياق النص. hyphens: تفعّل أو تعطّل تجزئة الكلمات على سطرين في اللغات التي تدعم ذلك. line-break: تشدد أو تتسامح بالانتقال إلى سطر جديد في اللغات الآسيوية. text-align-last: تحدد محاذاة آخر سطر من كتلة أو أي سطر قبل أن يُجبر النص على الانتقال إلى سطر جديد. text-orientation: تحدد جهة انسياب الكلمات ضمن السطر. overflow-wrap: تحدد إن كان يُسمح للمتصفح أن ينتقل بالنص إلى سطر جديد لتفادي طفحان المحتوى أو لا. writing-mode: تحدد إن كان اتجاه الأسطر أفقي أو عمودي واتجاه انسياب الأسطر اللاحقة. الخاصيات المختصرة لتنسيق خط الكتابة يمكن ضبط الكثير من قيم خاصيات تنسيق النصوص من خلال الخاصية المختصرة font، وتكتب قيمها وفق التسلسل التالي: font-style و font-variant و font-weight و font-stretch و font-size و line-height و font-family. وتُعد الخاصيتين font-size و font-family ضروريتان فقط (يجب تحديد قيمهما). لا بد من الإشارة إلى ضرورة وضع شرطة أمامية مائلة "/" بين الخاصيتين font-size و line-height كما في المثال التالي: font: italic normal bold normal 3em/1.5 Helvetica, Arial, sans-serif; تطبيق عملي: حاول أن تتدرب على تنسيق النصوص نريد منك في هذا التطبيق أن تستخدم محرر الشيفرة التفاعلي التالي لتتدرب على استخدام خاصيات تنسيق النصوص وتكتشف طريقة عملها وما يمكن أن تقدمه من فائدة. بإمكانك أن تستخدم ملفات HTML/CSS التي نزّلتها أو العمل على شيفرتك الخاصة. إن ارتكبت خطأً، انقر على زر "مسح Reset" لإلغاء كل ما فعلته والعمل من جديد. الخلاصة نأمل أن تكون قد استمتعت واستفدت مما قدمناه في مقالنا عن تنسيق النصوص في CSS، وسنتابع العمل في المقال القادم على تنسيق قوائم HTML. ترجمة -وبتصرف- للمقال Fundamentals text and font styling اقرأ المزيد المقال السابق تنظيم الشيفرة في CSS. تعرف على أساسيات لغة CSS توثيق لغة CSS العربي. تنسيق نصوص صفحات الويب باستخدام CSS. التنسيقات الأساسية للعناصر في CSS.
-
تنظيم شيفرة CSS حالما تبدأ العمل على ملفات تنسيق ضخمة ومشاريع كبيرة ستكتشف أن صيانة ومتابعة ملفات التنسيق الضخمة ليس أمرًا سهلًا، لهذا سنلقي نظرةً في هذا المقال على بعض أفضل الممارسات التي ينبغي اتباعها في كتابة تنسيقات CSS لتسهيل الصيانة والتعديل وبعض الحلول التي يستخدمها الآخرون وتحسّن القدرة على متابعة وصيانة شيفرات التنسيق. ننصحك قبل المتابعة في قراءة هذه المقال أن: تطلع على أساسيات استخدام الحاسوب وتصفح الويب. تحضّر بيئة عمل بسيطة كما تحدثنا مسبقًا في المقال تثبيت البرمجيات الأساسية، وتتفهم طريقة إنشاء وإدارة الملفات كما شرحناها في مقال التعامل مع الملفات. تطلع على أساسيات HTML كما شرحناها في سلسلة المقالات مدخل إلى HTML. تتفهم أساسيات CSS كما شرحناها في سلسلة المقالات خطواتك الأولى في CSS. نصائح لترتيب شيفرات CSS إليك بعض الاقتراحات العامة لطرق تنظيم وترتيب ملفات شيفرة CSS: هل هناك نموذج محدد في تنسيق شيفرة المشروع؟ إذا كنت تعمل ضمن فريق على مشروع موجود مسبقًا، عليك أن تتحقق أولًا من وجود دليل خاص بتنسيق شيفرة CSS ضمن المشروع، إذ لا بد أن تلتزم بالإرشادات الموجودة في الدليل بدلًا من تطبيق ما تفضّله أنت من القواعد. لا توجد غالبًا معايير لتحديد ما هي الطريقة الصحيحة أو الخاطئة لتنفيذ المطلوب، لكن ما يهم فعلًا هو التناسق consistency. الحفاظ على التناسق إذا كنت تعمل وفق قواعد خاصة بمشروع أو كنت تعمل وحيدًا، لا بد من المحافظة على تناسق أسلوب العمل. يمكنك أن تضمن التناسق بطرق عدة، كأن تستخدم نفس أسلوب تسمية الأصناف، أو اتباع طريقة ثابتة في وصف الألوان، أو المحافظة على الأسلوب ذاته في كتابة الشيفرة، كأن تستخدم مفتاح الجدولة Tab دائمًا لإزاحة الشيفرة ضمن الملف، أو تستخدام مفتاح المساحة الفارغة Space بدلًا عنه وفي حال استخدمت المساحة الفارغة ما هو مقدار المساحة الفارغة الذي تعتمده. يساعدك وجود قواعد ثابتة وموحدة تتبعها باستمرار على تقليل العبء الفكري عند كتابة CSS نظرًا لوجود قراراتٍ قد اتخذتها مسبقًا. تنسيق قواعد CSS لتكون سهلة القراءة يستخدم المطورون طريقتين أساسيتين في كتابة شيفرات CSS أحدها كتابة جميع القواعد على نفس السطر على النحو التالي: .box {background-color: #567895; } h2 {background-color: black; color: white; } بينما يفضل آخرون كتابة كل قاعدة على سطر جديد كما يلي: .box { background-color: #567895; } h2 { background-color: black; color: white; } لن يؤثر ذلك على تنفيذ تلك القواعد، لكن من الواضح أن كتابة كل خاصية وإلى جوارها قيمتها ضمن سطر جديد أسهل قراءةً. التعليقات على الشيفرة تساعد التعليقات التي تضيفها إلى الشيفرة أي مطوّر سيعمل مستقبلًا على شيفرتك، كما تساعدك أيضًا في تذكر ما كتبته عند عودتك إلى العمل على ملف التنسيق بعد انقطاع. /*CSS هذا مثال عن التعليقات في يمكن كتابة التعليق على أكثر من سطر */ من النصائح المفيدة في هذا الصدد هي كتابة كتلة من التعليقات بين الأقسام المنطقية في ملف التنسيق أيضًا كي يتسنى لك الوصول إلى أي منها بسهولة عند قراءة ملفك أو استخدامها مثل عبارات للبحث عن القسم المطلوب من شيفرة CSS. إذا استخدمت نصًا لا يظهر ضمن الشيفرة، يمكن الانتقال من قسم يبدأ بالمحرفين || إلى آخر بالبحث عن هذين المحرفين. /* || تنسيقات عامة */ /* … */ /* || تنسيق خطوط الكتابة */ /* … */ /* || تنسيق الترويسات وعناصر التنقل الرئيسية */ /* … */ لا حاجة إلى كتابة تعليقات حول كل ما تفعله شيفرتك، فالكثير من القواعد تشرح نفسها بنفسها، لكن ما تحتاج إلى التعليق عليه هو عادةً نقاط محددة اتخذت قرارًا عندها لأسباب خاصة، فقد تستخدم خاصية محددة بطريقة معينة لتحاشي مشكلات التوافق مع المتصفحات الأقدم. إليك مثالًا: .box { background-color: red; /* fallback for older browsers that don't support gradients */ background-image: linear-gradient(to right, #ff0000, #aa0000); } قد تستخدم كذلك قواعد تنسيق وجدتها في دورة تعليمية لكنها ليس واضحة تمامًا أي لا تشرح نفسها بنفسها، لذا من الأفضل في هذه الحالة إضافة تعليق يضم عنوان URL لتلك الدورة التعليمية. ستدرك أهمية ذلك عندما تعود إلى هذا الملف بعد فترة طويلة محاولًا تذكر أنك تعلمت شيئًا من دورة تعليمية مميزة حول موضوع تحتاجه ولا تتذكر أين اطلعت عليها. تقسيم ملف CSS إلى أقسام منطقية من الجيد أن تضع التنسيقات العامة الأكثر شيوعًا في بداية الملف، ونقصد بذلك جميع التنسيقات التي تطبّق على العناصر عمومًا ما لم ترد تخصيص قواعد محددة لعنصر محدد، وستضع غالبًا قواعد لتنسيق العناصر التالية: متن صفحة الويب body. الفقرات p. العناوين الرئيسية h1, h2, h3, h4, h5. القوائم المرتبةul وغير المرتبة ol. خصائص الجداول table. الروابط التشعبية. نضع في هذا القسم من ملف الشيفرة التنسيق الافتراضي لعناصر الموقع مثل تنسيقات جداول البيانات والقوائم وهكذا: /* || قواعد تنسيق عامة */ body { /* … */ } h1, h2, h3, h4 { /* … */ } ul { /* … */ } blockquote { /* … */ } يمكن أن نعرّف بعد هذا القسم مجموعةً من الأصناف المساعدة، مثل الأصناف التي تزيل تنسيق بعض القوائم التي نعرضها بأكثر من طريقة، فإذا أردت استخدام خيارات تنسيق متعددة وتعرف أنك ستغيّر تنسيق العديد من العناصر المختلفة لإنجاز كل خيار، من الأفضل إذًا وضع قواعد كل خيار في صنف خاص في هذا القسم. /* || الأصناف المساعدة */ .nobullets { list-style: none; margin: 0; padding: 0; } /* … */ نضع بعد ذلك كل التنسيقات التي تُستخدم على كامل الموقع، مثل تخطيط الصفحات الأساسي والترويسات وتنسيق أدوات التنقل وما شابه في قسم خاص: /* || تنسيقات كامل الصفحات */ .main-nav { /* … */ } .logo { /* … */ } نخصص أخيرًا قسمًا يضم تنسيقات CSS لأغراض مخصصة، أو ما يمكن أن يتغير مع سياق الصفحة، أو لصفحات معينة، أو حتى لمكوّنات معينة: /* || صفحات المخزن */ .product-listing { /* … */ } .product-box { /* … */ } يساعدك هذا الترتيب على الأقل في تكوين صورة عن المكان الذي تبحث فيه ضمن ملف الشيفرة عن شيءٍ ما تريد تغييره أو استبداله. تجنب استخدام محددات شديدة التخصيص عندما تبني محددًا مخصصًا جدًا، ستجد أنك ستعيد استخدام فقرات من شيفرتك مرارًا لتطبيق نفس قواعد هذا المحدد على عناصر أخرى، فلو أردت بناء محدد يستهدف الفقرات <p> التي تمتلك الصنف box وتتواجد ضمن العناصر <article> التي تمتلك الصنف main على النحو التالي: article.main p.box { border: 1px solid #ccc; } وأردت أن تكرر نفس القواعد على عناصر لا تمتلك الصنف main أو على عنصر آخر غير، فعليك حينها إضافة محدد جديد إلى هذه القواعد، أو بناء مجموعة جديدة من القواعد. يمكنك بدلًا من ذلك استخدام محدد بسيط box. لتطبيق قواعدك على أي عنصر يمتلك الصنف box: .box { border: 1px solid #ccc; } لاشك أن قد تضطر أحيانًا إلى إنشاء محدد شديد التخصيص، لكن هذا الأمر استثنائي عمومًا وليس شائعًا. تقسيم ملفات التنسيق الكبيرة إلى ملفات أصغر في الحالات التي تحتاج فيها إلى تنسيقات مختلفة جدًا لأجزاء محددة من موقعك، قد ترى ضرورة وجود ملف يتضمن القواعد العامة، إضافةً إلى ملفات أصغر تضم قواعد مخصصة لتنسيق تلك الأجزاء، ويمكنك طبعًا ربط أي صفحة باكثر من ملف تنسيق، إذ تنص قواعد التعاقب أن التنسيقات الموجودة في آخر ملف يربط مع الصفحة ستطبّق أولًا. لنفترض على سبيل المثال أن قسمًا من موقعك هو متجر إلكتروني ويحتاج إلى الكثير من القواعد المختلفة لتنسيق قوائم المنتجات والنماذج الخاصة بعمل المتجر، فمن المنطقي هنا وضع تلك القواعد في ملف تنسيق خاص يرتبط فقط مع صفحات المتجر، وهذا يسهل ترتيب شيفرتك وتنظيمها أكثر، وفي الحالات التي يعمل فيها أكثر من مطوّر على كتابة التنسيقات، ستقل منطقيًا عدد الحالات التي يُضطر فيها أكثر من مطور للعمل على الملف ذاته. أدوات أخرى قد تساعد في تنظيم شيفرة CSS ليس لدى تنسيقات CSS طريقةً خاصةً كي تُنظّم، لهذا يعتمد مستوى تناسقها عليك في المقام الأول. لقد طوّرت مجتمعات الويب أدوات كثيرة ونُهجًا تساعدك في إدارة مشاريع CSS الضخمة، وقد تصادف بعضها عند العمل مع آخرين، وطالما أنها مفيدة غالبًا، سنتحدث عن بعضها باختصار. أساليب CSS بدلًا من ابتكار قواعد خاصة في كتابة CSS، قد تستفيد من أحد النهج التي صممها مجتمع الويب واختبرها في مشاريع كثيرة. أساليب CSS هي أساسًا دليل لكتابة التنسيقات تتخذ نهجًا مهيكلًا في كتابة الشيفرة وتنظيمها. تميل هذه الأساليب إلى تصيير CSS مطوّلًا مقارنةً بما قد تفعله إذا كتبت وحسّنت كل محدد ليضم مجموعةً مخصصةً من القواعد لتنسيق المشروع. قد تكون هيكلية الملفات أضخم عند اعتماد أحد هذه الأساليب، وطالما أن الكثير منها واسع الاستخدام، فقد يفهم المطورون الآخرون هذا النهج ويستخدمونه لكتابة شيفرات CSS بنفس الأسلوب بدلًا من محاولة فهم أسلوبك الخاص. أسلوب OOCSS تدين معظم النهج التي ستواجهها بالفضل إلى مبدأ تنسيقات CSS غرضية التوجه Object Oriented CSS -أو اختصارًا OOCSS، وهو نهج اشتهر نتيجةً لأعمال نيكول سوليفان Nicole Sullivan. تنص الفكرة الأساسية لهذا النهج على فصل شيفرة CSS إلى كائنات يمكن استخدامها من جديد في أي مكان تريده في موقعك، ومن الأمثلة النموذجية لنهج OOCSS هو النمط الذي يوصف بأنه كائن الوسائط المتعددة Media Object، ويتكون هذا النمط من صورة ثابتة الحجم أو فيديو أو غيرها من العناصر من ناحية، كما يضم حاوية مرنة للمحتوى من ناحية أخرى. يُستخدم هذا النمط كثيرًا ضمن مواقع الويب لعرض التعليقات أو القوائم وغيرها. إذا لم تستخدم نهج OOCSS، لربما ستنشئ قواعد CSS مخصصة للأجزاء المختلفة التي استًخدم فيها هذا النمط، إذ قد تنشئ مثلًا صنفين أحدهما يُدعى comment ويضم جملةً من القواعد التي تنسق أجزاء المكوّن، والآخر يُدعى list-item ويضم نفس القواعد التي يضمها الصنف مع استثناءات بسيطة، إذ يضم الصنف list-item حافةً سفلية وليس لصورته حواف بينما لصور الصنف comment حواف على محيطها. .comment { display: grid; grid-template-columns: 1fr 3fr; } .comment img { border: 1px solid grey; } .comment .content { font-size: 0.8rem; } .list-item { display: grid; grid-template-columns: 1fr 3fr; border-bottom: 1px solid grey; } .list-item .content { font-size: 0.8rem; } في المقابل، ستنشئ إذا اعتمدت نهج OOCSS نمطًا واحدًا يُدعى media يضم كل التنسيقات المشتركة بين النمطين السابقين، وسيكون صنفًا أساسيًا يضم الأشياء التي تحدد كائن الوسائط المتعددة عمومًا، ثم يمكن إضافة صنف إضافي للتعامل مع الاختلافات البسيطة، وهذا ما يوسّع التنسيق السابق من عدة نواحٍ: .media { display: grid; grid-template-columns: 1fr 3fr; } .media .content { font-size: 0.8rem; } .comment img { border: 1px solid grey; } .list-item { border-bottom: 1px solid grey; } إذ ستحتاج إلى تطبيق كلا الصنفين media و comment ضمن شيفرة HTML: <div class="media comment"> <img src="" alt="" /> <div class="content"></div> </div> وكذلك ستحتاج إلى كلا الصنفين media و list-item لتنسيق عناصر القائمة: <ul> <li class="media list-item"> <img src="" alt="" /> <div class="content"></div> </li> </ul> ما فعلته نيكول سوليفان عند توصيف هذا النهج وتطويره هو دفع الأشخاص الذين لا يتبعون تمامًا نهج OOCSS لإعادة استخدام CSS عمومًا بهذا الأسلوب، وبالتالي أثرت على طريقة فهمنا لتنظيم شيفرات التنسيق. أسلوب BEM هو اختصار لعبارة Block Element Modifier وبالعربية معدّل عنصر الكتلة. تُعرّف الكتلة في BEM على أنها كيان قائم بذاته، مثل الأزرار والقوائم والشعارات. العنصر هو شيء ما، مثل عناصر القائمة أو العنوان الذي يرتبط ارتباطًا وثيقًا بالكتلة ويقع داخلها؛ أما المُعدّل modifier فهو راية تشير إلى تغيّر في تنسيق الكتلة أو العنصر. ستميز الشيفرة التي تستخدم هذا النهج من الاستخدام المكثف للشرطة السفلية والشرطة العادية ضمن أصناف CSS. يمكن على سبيل الاطلاع رؤية الأصناف المطبّقة على شيفرة HTML الخاصة بالصفحة BEM Naming conventions: <form class="form form--theme-xmas form--simple"> <label class="label form__label" for="inputId"></label> <input class="form__input" type="text" id="inputId" /> <input class="form__submit form__submit--disabled" type="submit" value="Submit" /> </form> تتشابه الأصناف الإضافية هنا مع تلك المستخدمة في مثال OOCSS، لكنها تستخدم الأسلوب الصارم في تسمية الأصناف وفق BEM. يُستخدم BEM كثيرًا في مشاريع ويب الأضخم، ويكتب الكثيرون تنسيقات CSS وفق هذا الأسلوب. من المؤكد أنك ستواجه الكثير من الأمثلة والدورات التعليمية التي تستخدم صياغة BEM دون أن تذكر سبب هيكلة CSS فيها بهذا الشكل. بعض الأنظمة الشائعة الأخرى لتنسيق شيفرة CSS هناك الكثير من الأنظمة الشائعة الأخرى، بما في ذلك معمارية CSS القابلة للتوسع والتقسيم Scalable and Modular Architecture for CSS -أو اختصارًا SMACSS- التي أنشأها جوناثان سنوك Jonathan Snook، و ITCSS لمؤلفها هاري روبيرتس Harry Roberts، و Atomic CSS (ACSS) من إنتاج ياهو أساسًا. إذا واجهتك بعض المشاريع التي تستخدم أيًا من الأساليب السابقة، ستجد لحسن الحظ العديد من المقالات والأدلة التي ترشدك إلى طريقة كتابة الشيفرات وفقها، لكن الناحية السلبية فيها هي التعقيد الزائد وخاصة عند كتابة تنسيقات لمشروعات صغيرة. الأنظمة الجاهزة لكتابة CSS من الطرق الأخرى المستخدمة في تنظيم شيفرة CSS هي استغلال بعض الأدوات المتاحة لمطوري الواجهات الأمامية، والتي تتيح نهجًا قريبًا من النهج البرمجي لكتابة CSS. فهناك العديد من الأدوات التي نشير إليها على أنها أدوات معالجة أولية pre-processors أو نهائية post-processors؛ إذ تعمل المعالجات الأولية على الملفات الخام وتحوّلها إلى ملفات تنسيق؛ بينما تعمل المعالجات النهائية على ملفات التنسيق الجاهزة، ربما لتحسينها كي تُحمّل بسرعة أكبر. لا بد أن تكون بيئة التطوير التي تستخدمها قادرةً على تنفيذ سكربتات المعالجات الأولية والثانوية قبل أن تفكر في استخدام تلك الأدوات. تدعم الكثير من محررات الشيفرة هذه الأمور، كما تستطيع تثبيت أدوات تعتمد على أسطر الأوامر لمساعدتك في ذلك. من أكثر المعالجات الأولية شعبيةً هي Sass. لن نتوسع في شرح هذا المعالج بل سنكتفي بتوضيح بعض الأشياء التي يقدمها Sass، فهي مفيدة حقًا من باب تنظيم شيفرة التنسيق حتى لو لم تستخدم أية ميزات أخرى تقدمها. وإذا أردت تعلم المزيد، يمكنك العودة إلى توثيق Sass على موسوعة حسوب. تعريف متغيرات تمتلك CSS حاليًا خاصيات مخصصة أصيلة، مما يقلل أهمية ميزة المتغيرات، لكن من الأمور الجيدة التي تقدمها Sass في هذا الصدد هي القدرة على تعريف جميع الألوان والخطوط المستخدمة في المشروع على شكل إعدادات، ثم استخدام المتغيرات ضمن كامل المشروع، فلو أدركت مثلًا أنك استخدمت الدرجة الخاطئة من اللون الأزرق، عليك عندها تغييرها في مكان واحد فقط. عند استخدام متغير يُدعى base-color$ على سبيل المثال كما في السطر الأول من الشيفرة التالية، يمكننا عندها استخدامه في أي مكان من ملف الشيفرة نحتاج فيه إلى هذا اللون: $base-color: #c6538c; .alert { border: 1px solid $base-color; } عندما تُصرّف شيفرة Sass سينتهي بك الأمر إلى شيفرة CSS التالية: .alert { border: 1px solid #c6538c; } تصريف ملفات تنسيق المكونات رأينا سابقًا أن أحد طرق تنظيم CSS هي تقسيم الملف إلى ملفات أصغر، وعند استخدام Sass، يمكنك الاستفادة من هذا الأسلوب إلى حد بعيد وسينتج لديك الكثير من الملفات الصغيرة جدًا إلى درجة وجود ملف منفصل لكل مكوّن. ستتمكن عند استخدام الوظيفة "partials" المدمجة مع Sass من تصريف جميع هذه الملفات إلى عدد أقل بكثير من الملفات النهائية التي تربطها بموقع الويب، فقد يكون لديك مثلًا عدة ملفات تنسيق ضمن مجلد واحد، ولتكن foundation/_code.scss و foundation/_lists.scss و foundation/_footer.scss و foundation/_links.scss وغيرها، يمكنك حينها استخدام القاعدة use@ لتضمينها ضمن ملفات أخرى: // foundation/_index.scss @use "code"; @use "lists"; @use "footer"; @use "links"; إذا جرى تحميل جميع الأجزاء ضمن الملف "index" كما حدث في الشيفرة السابقة، يمكن حينها تحميل كامل المجلد ضمن ملف آخر بخطوة واحدة: // style.scss @use "foundation"; ملاحظة: من السهل تجريب Sass باستخدام موقع CodePen، إذ ستتمكن من تمكين Sass عند العمل مع شيفرة CSS عن طريق إعدادات "Pen"، وعندها سيشغّل CodePen محلل Sass كي ترى نتيجة عملك وكأنك طبقت قواعد CSS نمطية. قد ترى أحيانًا أن دورات تعليم CSS تستخدم Sass بدلًا من CSS النمطية في أمثلتها المكتوبة عن طريق CodePen، لهذا سيفيدك الإطلاع على ذلك قليلًا. تحسين الشيفرة باستخدام أدوات المعالجة النهائية إذا كنت تقلق من زيادة حجم ملفات CSS بزيادة كمية التعليقات مثلًا أو زيادة المساحات الفارغة، فخطوة المعالجة النهائية مفيدة هنا في التخلص من أي شيء غير ضروري في نسخة الإنتاج. من الأمثلة على أدوات المعالجة النهائية هو cssnano. الخلاصة هذا هو المقال الأخير ضمن مجموعة المقالات التي تغطي وحدات بناء CSS، وكما ترى يمكنك اتباع أساليب عدة في متابعة رحلتك في استكشاف CSS انطلاقًا من هذه النقطة. ترجمة -وبتصرف- للمقال Organizing your CSS اقرأ أيضًا تنسيقات المتصفحات المخصصة ودعمها وأداءها في CSS مدخل إلى Sass مواضيع متقدمة في CSS أنواع محددات التنسيق في CSS
-
يشيع استخدام مصطلح صفحة هبوط Landing Page لتسمية صفحات ويب محددة في مجال التجارة الإلكترونية وهي عادة تلك الصفحات التي تنقلنا إليها روابط دعائية أو صور المنتجات التي يجري تسويقها. ونظرًا لأهمية هذه الصفحات في عالم التسويق الإلكتروني والتجارة الإلكترونية، لابد من الاهتمام بتصميمها بأسلوب عصري فعّال قادر على جذب العميل وتوفير كل المعلومات التي يحتاجها بطريقة سهلة وواضحة، وهذا ما نهدف إليه في هذا المقال. ما هي صفحات الهبوط صفحات الهبوط هي صفحات محددة ضمن موقع ويب أو متجر إلكتروني تخدم غاية واحدة تتمثل في تحويل الزائر إلى عميل أو إلى عميل محتمل عندما ينقر على رابط دعائي أو صورة منتج في نفس الموقع أو في مواقع أخرى ويقوده ذلك إلى هذه الصفحة. وحتى نقول أن صفحة ويب ما هي صفحة هبوط لا بد من توافر الميزات التالية فيها: أن تتمكن هذه الصفحة من الحصول على بيانات ومعلومات عن الزائر طواعية مقابل اطلاعه على العرض الذي تقدمه له، وقد يكون ذلك عن طريق ملء نموذج أو تنزيل استبيان والإجابة عليه ثم تحميله من جديد. أن يكون الغرض الوحيد من هذه الصفحة تحويل الزائر إلى عميل محتمل، لذلك لا بد من تصميم صفحة الهبوط على هذا النحو دون أي تشويش على الهدف الرئيسي. كيف تعمل صفحات الهبوط تبدأ العملية عندما يشاهد الزائر رابطًا إلى الصفحة ضمن موقع إلكتروني ما. قد يكون هذا الرابط صورة أو زر أو عبارة تدفع الزائر بأسلوب جذّاب للنقر عليه ويصل به الأمر إلى صفحة الهبوط (تُدعى هذه الصور أو الأزرار بمحفزات اتخاذ القرار Call Of Action). تضم صفحة الهبوط غالبًا شرحًا مقتضبًا عن الموضوع بخط جلي وأسلوب محفّز، مع وجود زر مميز يسترعي انتباه الزائر ويدفعه للنقر عليه. سيصل الأمر بالزائر بعد النقر إلى نموذج من حقول عدة يطلب منه ملؤها بالبيانات الشخصية، وقد تطلب منه الصفحة قبل النقر على الزر أن يضع بريده الإلكتروني، ولهذا الأمر أهميته لأنها تمكن صاحب الموقع من الحصول على البريد الإلكتروني للزائر إذا قرر لاحقًا عدم المتابعة في تقديم بياناته الشخصية. إن قدّم الزائر بياناته الشخصية أو بريده الإلكتروني على الأقل، فسترسل الصفحة هذه البيانات إلى التخزين ضمن قواعد بيانات العملاء والأدلاء lead database. وستكون الخطوة التالية استهداف هذا العميل المحتمل بعروض تتناسب مع بياناته، وخاصة عند تجميع معلومات عن نوع العروض التي تحفّز هذا الشخص. تُدعى هذه التقنية بتكوين العميل المحتمل lead nurture، والعميل المحتمل الذي هُيّئ بهذا الشكل، لن يستغرق وقتًا حتى يصبح عميلًا فعليًا وهذا ما سينعكس إيجابًا على أعمالك. ترى الفلسفة الكامنة وراء صفحات الهبوط أن تقديم لزائر بياناته طوعيًا للاطلاع على العرض المقدم في هذه الصفحة يدل على أهمية هذا المنتج أو الخدمة بالنسبة له، وهذه البيانات في المقابل قيّمة جدًا بالنسبة للمسوقين وستكون النتيجة ربحًا لكلا الطرفين. ما الفرق بين صفحات الهبوط والمواقع الإلكترونية تتكون المواقع الإلكترونية مهما اختلفت أنواعها وحجومها والغاية منها من عدد محدود من صفحات الويب، ولكل صفحة ويب هدف معين سواء كان عرض محتوى معين، أو التفاعل مع المستخدم، أو تقديم خدمة معينة. وصفحات الهبوط ليست استثناءً، فهي صفحات ويب تشبه تمامًا من ناحية التصميم والبرمجة بقية صفحات الويب لكنها تنفرد بوظيفة محددة وبالتالي يجب أن يراعي تصميمها هذه الميزة. تستخدم المواقع الإلكترونية وخاصة تلك التي تروّج للشركات والأعمال العديد من صفحات الهبوط، وعليك أن تفكّر بصفحات الهبوط في هذه الحالة بأنها جزء من الموقع قد يصله الزائرون دون الدخول إلى موقعك مباشرة بل عن طريق روابط خارجية لمتابعة عروضك الخاصة، فهي بمثابة بطاقات دعوة أو اشتراك من قبلك تقدمها لزوّارك بغية الحصول على بياناتهم وولائهم لعلامتك التجارية ولمنتجاتك في مراحل قادمة. ما هي أنواع صفحات الهبوط تنقسم صفحات الهبوط إلى ثلاثة أنواع رئيسية: صفحات هبوط مستقلة standalone كصفحات التمهيد click through وصفحات اصطياد العميل lead capture. المواقع المصغّرة microsites وهي مواقع صغيرة مكونة من عدة صفحات وتأتي عادة مكملة لموقع رئيسي. صفحات هبوط داخلية وهي صفحات هبوط تعريف بالمنتجات ضمن الموقع الإلكتروني نفسه. لنتعرف على أبرز مميزات الأنواع المختلفة لصفحات الهبوط والفرق بينها. صفحات التمهيد تُعد صفحات التمهيد click through من أبسط أنواع صفحات الهبوط، وتكون غايتها الأساسية توضيح تفاصيل العرض المقدّم وميزاته بأسلوب قادر على إقناع الزائر اتخاذ قرار الشراء أو المشاركة. إذًا مهمتها فقط شرح العرض ثم النقر على الزر المخصص للانتقال بك إلى موقع الشركة لإكمال العملية. صفحات اصطياد العملاء إن المهمة الأساسية لهذه الصفحات هي استخلاص بيانات الزوار وخاصة الاسم والبريد الإلكتروني لهذا تُعرف أحيانًا بصفحات العصر squeeze pages. تصمم هذه الصفحات بأسلوب يمنعك من التراجع إلى الصفحة السابقة ولا تضم أية روابط أو عناصر تنقل بل زر إرسال البيانات فقط. تستخدم الشركات هذا النمط من الصفحات لبناء قوائم بريد إلكتروني للعملاء المحتملين للعمل على تحويلهم إلى عملاء فعليين. صفحات الإعلانات وهي بمثابة الأقنية الإعلامية لعالم التسويق الإلكتروني وتتميز بأنها مليئة بالإعلانات عن عروض كثيرة. إذ تستمر بالتمرير إلى الأسفل لتجد المزيد والمزيد من العروض وترى نفسك غارقًا في متابعة وقراءة شروحات ومزايا براقة تدفعك إلى معرفة المزيد عن هذا العرض. وحتى لو بدأت تشكك في مصداقيته، لكنك ستحاول معرفة نهاية العرض سواء لمجرد الفضول أو آملًا أن يكون العرض صحيحًا. قد تستخدم الشركات هذه النوع من الصفحات لكي تُعرف منتجاتها على أوسع نطاق. صفحات الهبوط سريعة الانتشار تُستخدم صفحات الهبوط سريعة الإنتشار Viral land pages من قبل الشركات لنشر اسم الشركة ومنتجاتها ضمن أكبر قدر ممكن من المواقع. تضم هذه الصفحات عادة بعض الألعاب أو مقاطع الفيديو أو الطرائف الجميلة مع رابط إلى الشركة التي أنشأت هذه الصفحة على شكل شعار صغير أو مع عبارة تشير إلى دور الشركة في أسفل الصفحة. تنتشر هذه الصفحات بسرعة عن طريق تقديم محتوى خفيف ومميز ضمن مواقع يكثر متابعينها أو عن طريق إضافة روابط لمواقع التواصل الاجتماعي كي يتمكن معجبو هذه الصفحات بمشاركتها على أوسع نطاق ممكن. المواقع المصغرة وهي مواقع جانبية تكمّل الموقع الرئيسي للشركة وتضم محتوىً خاصًا يتعلق بحملة إعلانية ولفترة محدودة. على الرغم من أنها تضم أكثر من صفحة لكنها تعد صفحات هبوط لأنها تستقطب الزوار والعملاء المحتملين من كل مكان ضمن شبكة ويب. وكمثال عليها صفحة هبوط لتعريف بمنتج جديد أو الدعاية لفرع محلي يقدم خدمات لعملاء الشركة وهكذا. تستخدم هذا النوع من صفحات الهبوط الكثير من الشركات المعروفة التي تهتم بتخصيص محتوى مميز لتسويق منتج أو خدمة. صفحات هبوط لعرض تفاصيل المنتج وهي صفحات ويب نمطية ضمن موقع الويب تضم كل المعلومات المتعلقة بالمنتج الذي تسوّقه الشركة. فهي صفحات غير مخصصة كليًا للتعريف بالمنتج أو تقديم العرض بل هي جزء من الموقع لهذا لن تكلّف كثيرًا من ناحية التصميم لكنها ستضم بالتأكيد بعض المحتوى الذي يشتت تركيز الزائر كونها جزء من الموقع مثل الترويسة وأزرار التنقل. أفكار لتصميم وبناء صفحات هبوط ناجحة إن الغاية الأساسية من صفحات الهبوط كما أسلفنا هي تحويل الزوار إلى عملاء، لهذا لا بد من الاهتمام ببعض التفاصيل عند بناء صفحات الهبوط نستعرضها في الفقرات القادمة. 1. استخدم عناوين ملفتة لا بد من جذب انتباه الزائر مباشرة إلى العنوان الأساسي لصفحة الهبوط، فهو أول ما تقع عينا الزائر عليه عند وصوله إلى هذه الصفحة. فإن كان العنوان واضحًا ومشجعًا ومباشرًا سيدفع الزائر إلى إكمال قراءة العرض ليعرف التفاصيل ويزداد احتمال طلبه للعرض أو مشاركة الصفحة مع غيره. فإن كان عرضك هو حسم على منتج معين فاكتب عنوانًا ينص عن مقدار هذا الحسم وعلى أية منتج بخط كبير مستخدمًا لونًا يبرز العنوان بوضوح عن الخلفية مع بعض المساحات الفارغة حوله. 2. أعلم الزائر بفائدة عرضك مباشرة دون مواربة عليك صياغة محتوى صفحة الهبوط صياغةً واضحةً تنقل فكرة عرضك والفوائد التي سيجنيها الزائر من المشاركة. لا تخبئ للزائر أية مفاجئات ولا تجعله يتخبط فيما يقرأ ولا تدع مجالًا للغموض في المفردات المستخدمة كأن تشير إلى تخفيضات مميزة دون ذكر قيمة هذه التخفيضات وأنواع المنتجات التي تُطبق عليها. حاول أن تستخدم قائمة من النقاط لتشرح عرضك باختصار لأن الزائر سيفقد اهتمامه بالصفحة إن وجد محتواها كثيفًا ولن يتابع القراءة بكل تأكيد. 3. فكر جيدا قبل تصميم نموذج استخلاص بيانات الزائر النموذج هو مجموعة من الحقول التي يملؤها الزائر ببياناته ثم ينقر على زر الإرسال لتنقل هذه البيانات وتخزن في المكان المناسب. تأكد قبل كل شيء من نوع صفحة الهبوط، فإن كانت تمهيدية، لا تزد عدد حقول النموذج عن حقلين الأول للاسم والثاني للبريد الإلكتروني وإن استخدمت حقلًا واحدًا فقط للبريد الإلكتروني فهذا أفضل غالبًا. فإن قرر الزائر الانتقال إلى صفحة المشاركة في العرض، ليكن عدد حقول البيانات متناسبًا مع المرحلة التي وصل إليها الزائر في رحلة الشراء أو المشاركة. أي بعبارات أخرى لا تصدم الزائر بعدد كبير من الحقول التي عليه ملؤها، فسيؤدي ذلك إلى مغادرته دون المشاركة. 4. تحاشى استخدام قوائم التنقل والروابط إلى خارج الصفحة قوائم التنقل هي أزرار تنقلك إلى الصفحة التالية أو السابقة، وبما أن الغاية الرئيسية من صفحات الهبوط هو أسر الزائر بالمحتوى أو العرض الذي توصله، لهذا فوجود مثل هذه القوائم ستشتت الزائر وقد تدفعه مباشرة إلى النقر عليها والخروج دون المشاركة. لا تضع مثل هذه القوائم أو أية روابط تسمح للزائر بالخروج من الصفحة سوى بالانتقال إلى المشاركة عن طريق النقر على زر أو رابط المشاركة CTA أو Call To Action وهذا ما يدفعه إلى قراءة العرض. فإما أن يتابع لأن العرض قد يعجبه، وإما أن يتابع ليجد طرقًا للخروج! 5. استخدم صور مناسبة تأكد من استخدام صورة واضحة وملائمة لطبيعة العرض الذي تقدّمه كي تجذب انتباه الزائر. فأغلب الظن أن الزائر سيبقى أطول في صفحتك إن لفتت الصورة انتباهه وقدمت له تفاصيل سواء مرسومة أو مكتوبة بطريقة ملفتة. 6. استخدم أيقونات المشاركة على مواقع التواصل الاجتماعي على الرغم من انها روابط بشكل أو بآخر إلا أنها مفيدة لمشاركة العرض مع آخرين ينشطون على مواقع التواصل الاجتماعي. لكن انتبه عند استخدام هذه الأيقونات بأن تفتح نافذة جديدة تقود مباشرة إلى مشاركة عرضك مع آخرين، لا أن تنقل الزائر من صفحتك إلى صفحة أخرى. 7. قد يفيدك استخدام شهادات الآخرين أو الإشارة إلى شركاء موثوقين من الجيد أن تشتري شيئًا أو تترك بخدمة يشيد بها الآخرون بعد تجريبها، لهذا إن وجدت أن بعض الآراء التي تشيد ببعض مزايا منتجك مفيدة فافعل ذلك دون أن يكون الأمر فجًا. وإن كان منتجك قد حصل على جائزة ما أو شهادة جودة فمن الجي الإشارة إلى ذلك عن طريق صورة صغيرة معبرة أسفل العرض، كأن يكون منتجك قد حصل على شهادة ايزو للجودة مثلًا! 8. اجعل صفحة الهبوط متجاوبة واختبر صحة عملها تأكد من أن الصفحة متجاوبة مع الهواتف الجوالة وأنها تعمل كما هو مطلوب وأن النقر على زر الدعوة لاتخاذ إجراء CTA سينفّذ العمل المطلوب منه دون أخطاء فهو المفصل الأهم في صفحات الهبوط. من المهم أيضًا أن تبقى تفاصيل العرض كاملة واضحة ضمن صفحة واحدة كي لا يضطر الزائر إلى التنقل نحو الأسفل لمتابعة القراءة فهذا سيسبب إلهاءً له، ونستثني من ذلك صفحات الإعلانات فهي مخصصة لهذا الغرض. وأخيرًا، ابق صفحة الهبوط ظاهرة بأكملها على شاشة جهاز المستخدم لا أن يكون جزءًا منها فقط ظاهرًا. لهذا السبب لابد من تصميم صفحة الهبوط بشكل متجاوب أي أن تتمكن من عرضها جيدًا على أي جهاز قد يستخدمه الزائر سواء حاسوب أو هاتف محمول. كيف تصمم صفحة هبوط يتعلق جواب هذا السؤال بك أولًا وأخيرًا، فإن كان هدفك استخدام قوالب جاهزة وتعديلها بما يناسبك حاجتك، ستجد ضالتك في الكثير من التطبيقات التي تساعدك على ذلك. أما إن أردت أن تحترف بناء صفحات الهبوط وتكون قادرًا على التعبير عن أفكارك بكل حرية وصولًا إلى مرحلة تصميم وبناء قوالب الصفحات وبيعها فعليك أن تتعلم تصميم صفحات الويب. استخدام تطبيقات لبناء صفحات الهبوط ستجد الكثير من تطبيقات أو مواقع ويب أو تطبيقات سطح المكتب التي تساعدك على بناء صفحة هبوط تشمل: صفحات لترقب العروض. صفحات لعرض منتجات. صفحات لتنسيق المناسبات والمؤتمرات والأحداث. قوالب جاهزة لنماذج استخلاص بيانات الزوار. قوالب جاهزة لتحضير صفحات الهبوط التمهيدية. تأتي الكثير من هذه التطبيقات مع واجهة مستخدم سهلة التعلم والاستخدام وتتيح عروض مجانية لاستضافة هذه الصفحات لكنها بالطبع محدودة من ناحية عدد الصفحات أو حجمها. نذكر من هذه التطبيقات Wix و SITE123 و Jimdo و ConvertKit و Carrd و ConvertFlow و Canava وغيرها الكثير. تصميم وبناء صفحات الهبوط من الصفر قد لا تتيح لك التطبيقات والقوالب الجاهزة جميع الإمكانات التي تتوقعها أو تطمح في تصميمها لإيصال أفكارك بالطريقة التي تريدها، لهذا لا بد من تعلم تصميم وتنسيق صفحات الويب. كما يتيح لك تعلم أساسيات تطوير الواجهات الأمامية لموقع الويب (واجهات المستخدم) الخبرات والأدوات اللازمة لتصمم وتبني أقوى وأفضل صفحات الهبوط ولن تجد بعدها صعوبة في تطبيق جميع الأفكار التصميمية التي تعزز عمل صفحاتك وتجعلها احترافية. تعلم تصميم صفحات الويب وصفحات الهبوط عبر أكاديمية حسوب تقدم أكاديمية حسوب دورة تطوير واجهات المستخدم والموجّه إلى الراغبين في دخول عالم تصميم وبرمجة واجهات المستخدم من الصفر دون الحاجة لخبرة مسبقة على مدى 66 ساعة فيديو تدريبية مع متابعة مستمرة لتطور مسيرتك من قبل مشرفين مختصين وتحصل في نهاية مسارات الدورة على شهادة معتمدة من أكاديمية حسوب. تعتمد الدورة على التطبيق العملي لبناء مشاريع حقيقية حتى تصبح مؤهلًا كمطوّر واجهات مستخدم وصفحات ويب وصفحات هبوط ومتاجر إلكترونية محترف. تضم الدورة المسارات التالية: أساسيات تطوير ويب. بناء واجهة مستخدم متطورة تشبه واجهة موقع YouTube. بناء صفحات الهبوط. تطوير متجر إلكتروني. تطوير موقع شركة. تطوير لوحة تحكم بالموقع. فإن كنت لا تمتلك خبرة مسبقة في مجال تطوير المواقع وواجهات المستخدم وصفحات الهبوط وتريد الانطلاق بثقة، أو كنت تمتلك خبرة بسيطة وترغب في صقل مهاراتك بالتعلّم الذاتي فهذه الدورة هي الخيار المثالي لك. خاتمة صفحات الهبوط هي صفحات ويب بميزات خاصة تساعد على ترويج منتجاتك التجارية وخدماتك من جهة وتوفير قاعدة بيانات تضم معلومات عن الزوار المهتمين بالعروض التي تقدمها وطبيعة ونوع هذه العروض وبالتالي ستتمكن من العمل بطريقة منهجية لكي تحولهم إلى عملاء. تحدثنا في هذا المقال عن أنواع صفحات الهبوط وكيف يعمل كل منها وتحدثنا عن أهم الممارسات التي يجب تعودها عند تصميم صفحات الهبوط والطرق المتاحة لتصميم صفحاتك سواء باستخدام تطبيقات جاهزة أو بتعلم تصميم صفحات الويب لتكون قادرًا على إيصال منتجاتك إلى أوسع شريحة من المهتمين وتزيد الوعي بعلامتك التجارية. اقرأ أيضًا 9 مبادئ لتصميم صفحة هبوط احترافية لماذا يجب استخدام صفحات الهبوط في التسويق عبر البريد الإلكتروني؟ ما الفرق بين تصميم المواقع الإلكترونية وتطوير المواقع الإلكترونية؟ تصميم مواقع الإنترنت وصفحات الهبوط لإنجاح التسويق الإلكتروني
-
قد تجد أن شيفرة CSS أحيانًا لا تنفّذ ما هو متوقع منها، فقد تعتقد أن محددّا ما لا بد وأن يطابق العنصر الذي تريده، لكن لا شيء يحدث، أو قد يكون الحجم الذي تريده لصندوق ما أكبر مما هو متوقع. لهذا سنرشدك في هذا المقال كيف تتعامل وتنقح اخطاءً كهذه في CSS، كما سنتحدث عن طريقة استخدام أدوات مطوري ويب DevTools الموجودة في كل المتصفحات الحديثة لتقصي المشاكل التي تواجهك. ننصحك قبل المتابعة في قراءة هذه المقال أن: تطلع على أساسيات استخدام الحاسوب وتصفح الويب. تحضّر بيئة عمل بسيطة كما تحدثنا مسبقًا في المقال تثبيت البرمجيات الأساسية، وتتفهم طريقة إنشاء وإدارة الملفات كما شرحناها في مقال التعامل مع الملفات. تطلع على أساسيات HTML كما شرحناها في سلسلة المقالات مدخل إلى HTML. تتفهم أساسيات CSS كما شرحناها في سلسلة المقالات خطواتك الأولى في CSS. الوصول إلى أدوات مطوري ويب عبر المتصفحات ستجد في مقال سابق بعنوان "أدوات مطوري ويب المدمجة في المتصفحات" دليلًا حديثًا يصف كيفية الوصول إلى أدوات مطوري ويب في متصفحات ويب ومنصات متعددة، وطالما أنك ستختار غالبًا متصفحًا محددًا عندما تبدأ تطوير المواقع، فستألف التعامل مع الأدوات المدمجة معه، لكن من المهم أن تعرف كيف تصل إلى هذه الأدوات في متصفحات أخرى، وهذا ما يساعدك على تكوين صورة واضحة عن الطريقة التي تصيّر فيها المتصفحات المختلفة صفحات الويب. سترى أيضًا كيف تركز المتصفحات على نقاط مختلفة عندما تبني أدوات تطوير الويب الخاصة بها، إذ يقدم لك متصفح فايرفوكس مثلًا أدوات ممتازة للتمثيل المرئي لتخطيطات CSS تسمح لك بتفحص وتحرير تخطيط الشبكة Grid Layouts أو الصندوق المرن Flexbox أو الأشكال Shapes وغيرها. وتمتلك معظم المتصفحات عمومًا الأدوات الأساسية نفسها كالأدوات المستخدمة في تفحّص الخاصيات وقيمها المطبقة على عناصر صفحة الويب، إضافةً إلى توفير إمكانية لتغيير هذه القيم من خلال نافذة المحرر. سنلقي نظرةً في هذا المقال على بعض الميزات المفيدة التي تقدمها أدوات مطوري ويب المدمجة مع متصفح فايرفوكس والمخصصة للتعامل مع CSS، لهذا السبب سنستخدم ملفًا معدًا لهذا الغرض، ويمكنك تحميله في نافذة جديدة ضمن المتصفح إذا أردت العمل عليه ومتابعة قراءة المقال في نفس الوقت، لكن لا تنسَ أن تفتح أدوات مطوري ويب كما أوردنا في المقال الذي أشرنا إليه قبل قليل. أسلوب شجرة DOM مقابل أسلوب عرض المصدر قد يثير الفرق بين ما تراه عند عرض الشيفرة المصدرية لصفحة الويب أو إلقاء نظرة على ملف HTML الموجود على الخادم، وما يمكن أن تراه في نافذة HTML Pane الموجودة ضمن أدوات مطوري ويب القلق لديك لاسيما إذا كنت حديث العهد بأدوات مطوري ويب DevTools، فعلى الرغم من أنهما متشابهتان نوعًا ما إلا أن هناك بعض الاختلافات. عندما يصيّر المتصفح ملف HTML ويبني شجرة DOM، قد يسوّي بعض شيفرات HTML، كأن يصحح تلقائيًا بعض الأخطاء أو الشيفرات المكتوبة خطأ؛ فعندما تغلق عنصرًا بطريقة خاطئة كأن تنهي الوسم <h2> بالوسم <h3/>، سيكتشف المتصفح ما تعنيه ويصحح ذلك تلقائيًا ضمن شجرة DOM، كما ستعرض شجرة DOM أية تغيرات ناتجة عن تطبيق شيفرة جافا سكريبت. تمثّل في المقابل الشيفرة المصدرية شيفرة HTML المخزّنة على الخادم، وهذا ما تعرضه شجرة HTML الخاصة بأدوات مطوري ويب، وهكذا ستبقى في صورة ما يجري في الواقع. استعراض قواعد CSS المطبقة على الصفحة اختر عنصرًا من عناصر صفحتك بالنقر عليه بالزر الأيمن ثم اختر " استعراض Inspect" من القائمة، أو اختر العنصر من شجرة HTML إلى يسار أدوات مطوري ويب. حاول اختيار العنصر الذي يمتلك الصنف box1 وهو أول عنصر في الصفحة ويحيط به صندوق رسمت حوله حواف. سترى إذا نظرت إلى "عارض القواعد Rules view" إلى يمين شيفرة HTML قواعد CSS المطبقة على العنصر مع قيمها بما في ذلك القواعد المطبقة مباشرةً من خلال المحدد box1 وتلك الموروثة من العنصر الأب وهو <body> في حالتنا. لهذا فائدته في التحقق من قواعد مطبقة لم تتوقع وجودها والتي قد تكون موروثة من العنصر الأب وتحتاج إلى إلغائها وفقًا لموضع العنصر في سياق الصفحة، كما تفيد في توسيع الخاصيات المختصرة لفهم آلية تطبيقها كما هي حال الخاصية المختصرة margin في مثالنا. انقر على زر السهم الصغير لتوسيع عرض الخاصيّة المختصرة كي ترى الخاصيات المختلفة التي تضمها وقيمها، كما يمكنك تغيير القيم في لوحة عارض القواعد إذا كانت مفعّلة. عندما تنقر على الخاصية بالفأرة وتطيل النقر، ستظهر صناديق تحقق لجميع القواعد ويمكنك عندها تفعيل أو إلغاء تفعيل أي قاعدة. يمكنك استخدام الطريقة السابقة للمقارنة بين حالتين تُطبق قواعد معينة في إحداها ولا تطبق في الثانية، كما تساعدك في التنقيح كأن تتحقق مثلًا من عدم استخدام الخاصية border-radius التي يسبب وجودها أخطاءً في تطبيق التخطيط الذي تعتمده. تعديل قيم الخاصيات يمكنك أيضًا من خلال أدوات مطوري ويب تعديل قيم الخاصيات أيضًا إضافةً إلى تفعيلها أو تعطيلها، فقد ترغب في تجريب ألوان أخرى أو تغيير حجم عنصر ما، إذ توفّر أدوات مطوري ويب وقتك في تحرير قواعد CSS وإعادة تحميل الصفحة مع القيم الجديدة. اختر المحدد (box1 مثلًا)، ثم انقر على الدائرة الملونة الصغيرة التي تظهر اللون المطبق على الحواف ليظهر لك مربع اختيار اللون. انقر على اللون الذي تريده وسترى كيف سيُطبق اللون الجديد مباشرةً على صفحتك. وبنفس الأسلوب ستكون قادر على تغيير قيم أية خاصية مثل حيّز الحواف أو تنسيقها. إضافة خاصية جديدة تستطيع أيضًا إضافة خاصيات جديدة من خلال أدوات مطوري ويب، فقد لا ترغب مثلًا أن يرث الصندوق حجم الخط من العنصر الأب <body> بل تريد ضبط حجم الخط بنفسك. تساعدك أدوات مطوري ويب في تجربة هذا الأمر قبل تغيير القواعد في ملف CSS. انقر على القوس المعقوص في القاعدة كي تدخل تصريحًا جديدًا ضمنها، ثم ابدأ بكتابة اسم الخاصية وستعرض لك أدوات مطوري ويب قائمة إكمال تلقائية للقواعد التي تطابق الحرف الذي تكتبه، وبعد أن تختار الخاصية font-size، ادخل القيمة التي تراها مناسبة. يمكنك أيضًا النقر على الزر "+" لإضافة تصريح جديد إلى نفس القاعدة، أو إضافة قواعد جديدة. ملاحظة: ستجد بعض الميزات المفيدة الأخرى في "عارض القواعد" كأن تجد الخاصيات التي أسندت إليها قيم خاطئة قد شطبت. نظرة أقرب إلى نموذج الصندوق في CSS ناقشنا في مقال سابق نموذج الصندوق المتبع في تنسيق CSS، كما تعرفنا على حقيقة وجود نموذج صندوق بديل يغيّر طريقة حساب حجم العنصر بناءً على الحجم الذي تريد، إضافةً إلى قيم الحشوات padding والحواف borders. لهذا، يمكنك الاستعانة بأدوات مطوري ويب في فهم كيفية حساب أبعاد العناصر، إذ تظهر لك لوحة "عارض التخطيط Layout view" عرضًا لنموذج الصندوق وقد أحاط بالعنصر الذي اخترته إضافة إلى وصف الخاصيات وقيمها وكيفية تموضع العنصر، ويتضمن ذلك أيضًا وصفًا للخاصيات التي لم تستخدمها صراحةً على العنصر بل تلك التي تأخذ قيمًا أساسية. من الخاصيات التي تجد تفصيلها في هذه اللوحة الخاصية box-sizing التي تحدد نموذج الصندوق المستخدم مع العنصر الذي تختاره، ولكي ترى كيفية عملها تابع المثال التالي: قارن بين كلا الصندوقين الذين يمتلكان الصنفين box1 و box2 ولهما نفس الحيّز width وقيمته (400 بكسل) لكن يبدو الصندوق box1 أوسع. لاحظ من خلال لوحة التخطيط كيف يستخدم هذا الصندوق القيمة content-box التي تأخذ الحجم الذي تضعه للصندوق ثم تضيف إليه حيّز الحشوة padding width وحيّز الإطار border width لهذا سيبدو أوسع. يستخدم العنصر الذي يمتلك الصنف box2 القيمة border-box التي تطرح قيمة حيّز الحشوة والإطار من الحيّز الذي وضعته، وهذا يعني أن حيّز الصندوق سيبقى مساويًا للحيّز الذي اخترته بدايةً وهو (400 بكسل). حل المشاكل المتعلقة بتخصيص محددات CSS قد تجد صعوبةً أحيانًا في تطبيق بعض قواعد CSS أثناء تطوير صفحات ويب، وخاصةً عند العمل على تنسيقات جاهزة على موقع موجود، فلن تتمكن من تطبيق القواعد التي تريدها على العنصر مهما حاولت. ما يحدث عادةً في هذه الحالات هو وجود محدد معين يلغي التغييرات التي تحاول تطبيقها كونه أكثر تخصيصًا (أي له الأولوية)، وهنا ستساعدك أدوات مطوري ويب كثيرًا. ستجد في الملف الذي نعمل عليه كلمتان محاطتان بالعنصر <em>، أحدهما تُعرض باللون البرتقالي والأخرى بالزهري، وإليك قاعدة CSS المطبقة: em { color: hotpink; font-weight: bold; } لكن هنالك أيضًا وقبل هذه القاعدة المحدد special.: .special { color: orange; } لقد ناقشنا موضوع تخصيص المحددات في المقال الذي يتحدث عن تعاقب قواعد CSS والوراثة ورأينا أن محددات الصنف class selectors أكثر تخصيصًا من محددات العناصر element selectors وبالتالي ستطبق قواعد هذه المحددات. ستساعدك أدوات مطوري ويب في حل هذا النوع من المشاكل، خاصةً إذا كانت المعلومات مختبئة في مكان ما من ملف تنسيق ضخم. استعرض الوسم <em> ذو الصنف special.، وستدلك أدوات مطوري ويب أن اللون البرتقالي هو ما يُطبّق وستجد أن الخاصية المطبقة على الوسم <em> قد شُطبت، وهكذا ستلاحظ أنه محدد الصنف قد تجاوز محدد العنصر. تفاصيل أكثر عن أدوات مطوري ويب المدمجة مع متصفح فايرفوكس ستجد الكثير من المعلومات عن أدوات مطوري ويب من خلال شبكة مطوري موزيلا MDN، كما يمكنك إلقاء نظرة على قسم أدوات مطوري ويب لتتعمق في الأفكار التي طرحناها باختصار في هذا المقال. تنقيح مشاكل CSS تقدم لك أدوات مطوري ويب دعمًا كبيرًا لحل مشاكل تنسيق CSS، لهذا إذا واجهتك المشاكل ووجدت أن التنسيق المطبق يختلف عما تتوقع، فقد تساعدك الخطوات التالية: تراجع خطوة إلى الخلف وألق نظرة على المشكلة قد تكون الأخطاء في كتابة الشيفرة أمرًا محبطًا وخاصة عند التعامل مع لغة CSS، لأنك لن ترى غالبًا أية رسالة خطأ كي تبحث عن سببها في الإنترنت وتجد الحل. إذا أصابك الإحباط فاترك المشكلة كما هي لفترة، اخرج لتتمشى قليلًا أو تحدث مع زميلك، أو اعمل على موضوع آخر، فقد يظهر الحل فجأة إذا توقفت عن التفكير في المشكلة، فإن لم يظهر ستجد أن العمل على حلها من جديد بعد الاستراحة سيكون أسهل. هل شيفرة HTML و CSS مكتوبة جيدًا؟ تتوقع المتصفحات أن تكون شيفرات HTML و CSS مكتوبةً صحيحًا بدون أخطاء، ومع هذا تتساهل المتصفحات كثيرًا مع الأخطاء وتحاول جهدها عرض صفحاتك حتى لو احتوت اخطاءً في التوصيف أو التنسيق، إذ تحاول المتصفحات توقع ما تريده، وقد تتخذ قرارات تخالف ما نويت إنجازه. إضافةً إلى ذلك قد يتخذ متصفحان مختلفان قرارين مختلفين حيال نفس المسألة، لذلك عليك أن تنفّذ شيفراتك ضمن محللات validator خاصة لاستكشاف هذا النوع من الأخطاء وإصلاحها أولًا، مثل محلّل CSS ومحلل HTML. هل يدعم المتصفح الخاصية التي تستخدمها وقيمها؟ تتجاهل المتصفحات خاصيات CSS التي لا تفهمها، فإذا لم تكن الخاصية أو القيمة مدعومةً من قبل المتصفح فلن تلاحظ ذلك، إلا أن الخاصية أو القيمة لن تعملا. تُظلل أدوات مطوري ويب الخاصيات والقيم غير المدعومة بطريقة معينة كما تظهر لقطة الشاشة التالية، إذ لا يدعم المتصفح المستخدم القيمة subgrid للخاصية grid-template-columns: يمكنك أيضًا إلقاء نظرة على جداول دعم المتصفحات المختلفة للخاصيات والقيم، إذ تظهر هذه الجداول دعم المتصفح لخاصية أو قيمة كما يُظهر إمكانية فشل المتصفح في استخدام الخاصية أو القيم في أشكال معينة للاستخدام. هل هناك شيء آخر يتجاوز قواعد CSS التي تكتبها؟ تظهر هنا أهمية المعلومات التي تعلمتها عن تخصيص المحددات، فإذا كان هناك فعلًا ما يتجاوز القاعدة التي تريد تطبيقها ستضطر حينها إلى الدخول في متاهة البحث عن الموضوع ولن يكون الأمر سهلًا. قد تساعدك هنا أدوات مطوري ويب في تحديد الخاصية التي تُطبّق وبالتالي ستتمكن من اختيار محدد أكثر تخصيصًا لتطبيق القواعد التي تريدها. حاول بناء اختبار محدود للتحقق من مشكلتك إذا لم تُحلّ المشكلة باتباع الخطوات السابقة، لا بد حينها من التحري عن صلب المشكلة أكثر، وأفضل شيء يمكنك فعله في هذه الحالة هو ما يُدعى "الاختبار المحدود Reduced test case"؛ فالقدرة على اختزال مشكلتك مهارة مفيدة جيدًا، إذ تساعدك على إيجاد المشاكل في شيفرتك وشيفرة زملائك، وتمكنك من الإبلاغ عن الثغرات وطب المساعدة بفعالية أكبر. أما الاختبار المحدود فهو شيفرة تعرض المشكلة بأبسط شكل ممكن دون أي ارتباط بالمحتوى المجاور ودون أية تنسيقات مسبقة، ويعني ذلك اجتزاء الشيفرة التي تسبب المشكلة وصنع مثال بسيط عنها يعرض الشيفرة أو الميزة التي سببت حدوث المشكلة. ينبغي عليك اتباع الخطوات التالية لبناء الاختبار المحدود: إذا كانت شيفرة HTML مولّدة ديناميكيًا (عبر نظام إدارة محتوى مثلًا)، ابنِ نسخةً ساكنةً من الخرج الذي يسبب المشكلة. قد تساعدك في هذا الأمر بعض المواقع، مثل CodePen التي يُعد موقعًا مفيدًا لاستضافة الاختبارات المحدودة، إضافةً إلى إمكانية الوصول إليها عبر الإنترنت وبالتالي ستسهل مشاركتها مع الزملاء. يمكنك أن تبدأ العملية بعرض الشيفرة المصدرية للصفحة، ثم نسخ شيفرة HTML إلى موقع CodePen، ثم تحضر تنسيقات CSS أو شيفرة جافا سكريبت وإضافتها إلى الاختبار أيضًا. تحقق عندها إذا استمرت المشكلة في الظهور أم لا. إذا لم يحل حذف شيفرة جافا سكريبت المشكلة، لا حاجة لتضمين ملفات جافا سكريبت في الاختبار المحدود، لكن إذا حل حذفها المشكلة، حاول حذف أكبر قدر ممكن من الشيفرة لإبقاء الشيفرة التي تسبب المشكلة فقط. احذف شيفرة HTML التي لا تتعلق بالمشكلة، وحاول أن تحذف المكوّنات أو حتى العناصر الرئيسية للتخطيط، أي حاول باختصار أن تقلل حجم الشيفرة قدر الإمكان كي تبقى فقط تلك التي سببت المشكلة. احذف تنسيقات CSS التي لا تتعلق بالمشكلة. قد تكتشف خلال تنفيذك الخطوات السابقة سبب المشكلة، أو تتمكن على الأقل من تجاوزها وإعادتها عن طريق حذف بعض الأشياء أو إعادتها. قد يفيدك أيضًا إضافة بعض المكوّنات إلى شيفرتك عندما تكتشف دليلًا إلى المشكلة، كما ننصحك بعرض ما فعلته على من تطلب منه مساعدتك. ربما ستكون المعلومات التي تحصل عليها كافية للبحث عن المشاكل المحتملة والعمل على حلها. إذا استمرت المعاناة في البحث عن المشكلة، ستساعدك المعلومات التي حصلت عليها من الاختبار المحدود في طلب العون عن طريق نشرها ضمن منتديات متخصصة أو عرضها على زميل، إذ ستزداد فرصة الحصول على المساعدة إن استطعت أن تُظهر كيف اختزلت المشكلة واستطعت تحديد مكانها تمامًا، وهكذا قد يتمكن مطوّر أكثر خبرة من رصد المشكلة بسرعة ويوجهك نحو الحل الصحيح أو على الأقل تساعده في إلقاء نظرة سريعة على المشكلة على أمل تقديم بعض المساعدة؛ أما في الحالة التي تكون فيها مشكلتك ثغرة في المتصفح نفسه، فقد يساعدك الاختبار المحدود في صياغة ملف الإبلاغ عن ثغرات وتوجيهه إلى المسؤول عن الأمر. عندما تغدو أكثر خبرة في استخدام تنسيقات CSS، ستكون أسرع في فهم المشاكل، لكن مع ذلك، تواجه أكثر المطورين خبرة بعض المشاكل المحيّرة، لهذا لا بد من اتباع طريقة منهجية لحل المشكلة، وعادة ما يكون بناء اختبار محدود وشرح هذه المشكلة لزملاء آخرين مفتاحًا للحل. الخلاصة تعرفنا في هذا المقال على أساليب تنقيح شيفرة CSS، وحاولنا تزويدك ببعض المهارات المفيدة التي تعتمد عليها عندما تبدأ بتنقيح CSS وغيرها من الشيفرات التي تواجهها لاحقًا خلال مسيرتك المهنية. ترجمة -وبتصرف- لمقال Debugging CSS اقرأ أيضًا التنسيقات الأساسية للعناصر في CSS تنسيقات المتصفحات المخصصة ودعمها وأداءها في CSS كيفية فهم وإنشاء قواعد CSS وحدات القياس والقيم في CSS التحكم في تموضع العناصر في CSS
-
لن يكون تنسيق الجداول أمرًا مهمًا، لكن علينا فعل ذلك أحيانًا، لهذا سنوّفر لك في هذا المقال دليلًا لتعرض جداول HTML بأسلوب أنيق إضافة إلى تطبيق بعض التقنيات الخاصة في تنسيقها. ننصحك قبل المتابعة في قراءة هذه المقال أن: تطلع على أساسيات العمل مع HTML. تطلع على أساسيات العمل مع الجداول في HTML كما شرحناها في المقال أساسيات بناء الجداول فيHTML. تتفهم أساسيات CSS كما شرحناها في سلسلة المقالات خطواتك الأولى في CSS. الجدول النمطي في HTML لنبدأ العمل بإلقاء نظرة على هيكلية الجدول النمطي في HTML من خلال الجدول التالي الذي يوصّف بعض الفرق الموسيقية في المملكة المتحدة. ستبدو الشيفرة على النحو التالي: <table> <caption> A summary of the UK's most famous punk bands </caption> <thead> <tr> <th scope="col">Band</th> <th scope="col">Year formed</th> <th scope="col">No. of Albums</th> <th scope="col">Most famous song</th> </tr> </thead> <tbody> <tr> <th scope="row">Buzzcocks</th> <td>1976</td> <td>9</td> <td>Ever fallen in love (with someone you shouldn't've)</td> </tr> <tr> <th scope="row">The Clash</th> <td>1976</td> <td>6</td> <td>London Calling</td> </tr> <!-- several other great bands --> <tr> <th scope="row">The Stranglers</th> <td>1974</td> <td>17</td> <td>No More Heroes</td> </tr> </tbody> <tfoot> <tr> <th scope="row" colspan="2">Total albums</th> <td colspan="2">77</td> </tr> </tfoot> </table> توصّف الشيفرة السابقة الجدول المطلوب جيدًا بفضل بعض الميزات، مثل scope و caption وغيرها، لكن لسوء الحظ لن يكون مظهرة جيدًا عندما يُصيَّر على الشاشة. يُطبق المتصفح التنسيق الافتراضي على الجدول السابق لهذا تراه صعب القراءة وممل، وهنا يأتي دور CSS لتحسين مظهره. تنسيق الجدول السابق سنعمل في هذه الفقرة على تنسيق الجدول السابق باتباع الخطوات التالية: حضّر نسخةً من الشيفرة السابقة عن طريق تنزيلها من غيت -هب، ثم نزّل الصورتين (noise و leopardskin)، وضع الملفات الثلاثة في مجلد واحد على حاسوبك. أنشئ تاليًا الملف "style.css" واحفظه في نفس المجلد السابق. اربط ملف CSS بملف HTML بوضع سطر الشيفرة التالي ضمن الوسم <head>: <link href="style.css" rel="stylesheet" /> توسعة الجدول وتخطيطه لا بد قبل كل شيء من ضبط المساحات في الجدول وضبط تخطيطه، إذ يبدو بحال سيئة، وحتى ننجز الأمر، ضِف الشيفرة التالية إلى الملف "style.css": /* spacing */ table { table-layout: fixed; width: 100%; border-collapse: collapse; border: 3px solid purple; } thead th:nth-child(1) { width: 30%; } thead th:nth-child(2) { width: 20%; } thead th:nth-child(3) { width: 15%; } thead th:nth-child(4) { width: 35%; } th, td { padding: 20px; } إليك أهم النقاط التي يجدر ملاحظتها في الشيفرة السابقة: ضبط قيمة الخاصية table-layout على القيمة fixed أمرٌ جيدٌ عادةً، فهو يجعل سلوك الجدول متوّقع افتراضيًا، إذ تأخذ أعمدة الجدول في الحالة الطبيعية حجمها وفقًا لكمية المحتوى التي تضمه، وهذا ما قد يعطي نتائج غريبة قليلًا، لكن باستخدام القاعدة table-layout: fixed ستتمكن من ضبط حيّز الأعمدة وفقًا لحيّز ترويساتها ومن ثم التعامل مع المحتوى وفقًا لذلك. لهذا استخدمنا أربع قواعد تنسيق مختلفة (thead th:nth-child(n لنستهدف الترويسات الأربع للجدول، بحيث يختار المحدد nth-child: العنصر الابن "n" الذي يمثّل العنصر <th> ضمن السلسلة، داخل العنصر <thread>، وأعطينا كلًا من الترويسات حيّزًا بنسبة مئوية من الحيّز الكلي. سيأخذ الآن كل عمود حيّز الترويسة وهي طريقة جيدة لتحديد الحجم. استخدمنا أيضًا فكرة أن تكون قيمة الخاصية width هي %100، وبالتالي سيملأ الجدول أي حاوية تضمه، وسيتجاوب جيدًا عند تغيير شاشة العرض، على الرغم من أنه يتطلب بعض العمل الإضافي ليبدو جميلًا ضمن الشاشة الأضيق. يُعد ضبط قيمة الخاصية border-collapse على collapse أسلوبًا معياريًا في تنسيق أي جدول. فعندما تضبط حواف الخلايا ضمن الجدول، سيظهر فراغ فيما بينها افتراضيًا، وقد لا يبدو الأمر جميلًا (إلا إن أردت فعلًا أن تظهر). لاحظ الصورة التالية: لكن بتطبيق القاعدة ;border-collapse: collapse ستختفي حواف الخلايا ويبدو الجدول على النحو التالي: وضعنا حوافًا border حول كامل الجدول، لأننا سنحتاج إليه عندما نضع حوافًا حول ترويسة وتذييل الجدول لاحقًا، إذ سيبدو الجدول غريب الشكل إذا لم نضع له حوافًا من الخارج وسينتهي الأمر بوجود فراغات مزعجة. وضعنا حشوة padding حول العنصرين <th> و <td> لكي نمنح البيانات المكتوبة بعض الفسحة ليظهر الجدول أكثر قبولًا. سيبدو الجدول حتى اللحظة على النحو التالي: بعض التنسيقات الكتابية البسيطة سنحاول تاليًا ترتيب النص قليلًا، لهذا سنبحث عن خط كتابة مناسب ضمن خطوط جوجل ليلائم محتوى الجدول الذي يتحدث عن فرق موسيقية، كما يمكنك اختيار أي خط كتابة آخر يعجبك؛ فكل ما عليك فعله في هذه الحالة هو استبدال العنصر <link> في شيفرتنا وخاصية التنسيق font-family مع تصريحه بالقيم التي تحددها لك مكتبة خطوط جوجل. أضف بدايةً العنصر <link> إلى ترويسة ملف HTML قبل العنصر <link> الموجود أصلًا: <link href="https://fonts.googleapis.com/css?family=Rock+Salt" rel="stylesheet" type="text/css" /> أضف بعد ذلك تنسيقات CSS إلى الملف style.css تحت ما هو موجود أصلًا: /* typography */ html { font-family: "helvetica neue", helvetica, arial, sans-serif; } thead th, tfoot th { font-family: "Rock Salt", cursive; } th { letter-spacing: 2px; } td { letter-spacing: 1px; } tbody td { text-align: center; } tfoot th { text-align: right; } لا يوجد هنا حقيقيةً أية تنسيقات مخصصة تمامًا للجداول، وكل ما نفعله هو التلاعب بخطوط الكتابة لتسهيل قراءة المحتوى: اخترنا الخط sans-serif وهو خيار تزييني بحت، كما اخترنا خط كتابة مخصص في ترويسة الجدول داخل العناصر <thead> و <tfoot> ليناسب محتواهما. أضفنا بعض المساحات الفارغة letter-spacing ضمن ترويسة الجدول وخلاياه لأهمية ذلك في تسهيل قراءة المحتوى، وهو مجددًا خيار تزييني. وضعنا النص في منتصف كل خلية <tbody> كي تحاذي الترويسات، علمًا أنها تحاذى افتراضيًا إلى اليسار من خلال ضبط الخاصية text-align على left، بينما تُحاذى الترويسات إلى المنتصف center. سيبدو المظهر أفضل عمومًا إذا كانت محاذاة الترويسات <tfoot> ومحتوى الخلايا وفق النمط ذاته، وسنكتفي بالخط السميك bold لنص الترويسات كي تتميز عن سائر خلايا الجدول. ستبدو النتيجة أفضل الآن: الرسوميات والألوان لنتجه الآن نحو الرسوميات والألوان لإعطاء الجدول بعض الخصوصية في التنسيق ليلائم المحتوى، وسنبدأ بإضافة شيفرة CSS التالية إلى أسفل الملف style.css: /* graphics and colors */ thead, tfoot { background: url(leopardskin.jpg); color: white; text-shadow: 1px 1px 1px black; } thead th, tfoot th, tfoot td { background: linear-gradient( to bottom, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.5) ); border: 3px solid purple; } تذكّر أن ما فعلناه ليس مخصصًا للجداول تحديدًا لكن من الأفضل إلقاء نظرة: أضفنا صورة خلفية للجدول باستخدام الخاصية background-image على العنصر <thead> و <tfoot> وغيرنا لون color جميع النصوص داخل الترويسات والتذييل إلى اللون الأبيض ومنحناها تأثير الظل text-shadow لتبدو مقروءةً على نحوٍ أفضل. أضفنا أيضًا تدرجًا لونيًا خطيًا Linear gradient إلى العنصرين <th> و <td> الخاصين بالترويسات والتذييل لتبدو الخلفية أجمل، كما منحناهما حوافًا بنفسجية. من المفيد أن يكون لديك مجموعةً من العناصر المتداخلة كي تطبق التنسيق على شكل طبقات متتالية، وقد كان ممكنًا تطبيق خلفيات وتدرجات لونية على عناصر الترويسات والتذييل في نفس الوقت، لكننا قررنا أن نفصل بينهما كي نحرص على دعم المتصفحات الأقدم التي لا تدعم صور الخلفيات أو التدرج اللوني. خطوط حمار الوحش Zebra قررنا تخصيص هذه الفقرة لعرض طريقة إظهار صفوف الجدول بلونين متناوبين والتي تدعى خطوط حمار الوحش zebra stripes، مما يسهّل قراءة البيانات وتحليلها. لهذا أضف الشيفرة التالية إلى ملف style.css: /* zebra striping */ tbody tr:nth-child(odd) { background-color: #ff33cc; } tbody tr:nth-child(even) { background-color: #e495e4; } tbody tr { background-image: url(noise.png); } table { background-color: #ff33cc; } رأينا سابقًا كيف يُستخدم المحدد nth-child: لاستهداف عنصر ابن محدد، كما يُمكن أن يُعطى صيغة لها معاملات وبالتالي يمكن اختيار سلسلة من العناصر لاستهدافها؛ فالصيغة 2n-1 ستختار جميع الأبناء ذوي الترتيب الفردي مثل الولد الأول والثالث والخامس وهكذا؛ كما تُستخدم الصيغة 2n لاختيار الأبناء ذوي الترتيب الزوجي. استخدمنا في الشيفرة التعليمتين odd و even اللتين تنفذان الفكرة التي تحدثنا عنها، وهكذا سنعطي الصفوف الزوجية لونًا متوهجًا مختلفًا عن الفردية. استخدمنا أيضًا خلفية متكررة لكل على جميع الصفوف وهي صورة نصف شفافة من النوع png. لتغطي الصفوف معطية انطباعًا متشابكًا texture لمظهر الجدول. منحنا كامل الجدول خلفية لونية كي تظهر الصفوف ملونة في المتصفحات التي لا تدعم المحدد nth-child:. سيبدو الجدول الآن بالشكل التالي: قد يبدو ما فعلناه بالجدول مبالغًا فيه، وقد لا يناسب ذوقك، لكنها طريقة لأن نقول أن الجداول يمكن تنسيقها لتكون أكثر حيوية. تنسيق العناوين هناك شيء أخير سنفعله وهو تنسيق عنوان الجدول. لهذا عليك إضافة الشيفرة التالية إلى أسفل الملف style.css: /* caption */ caption { font-family: "Rock Salt", cursive; padding: 20px; font-style: italic; caption-side: bottom; color: #666; text-align: right; letter-spacing: 1px; } لا شيء مميز في تلك الشيفرة باستثناء الخاصية caption-side التي أسندنا إليها القيمة bottom وهذا ما يجعل عنوان الجدول في الأسفل إضافةً إلى وضع بعض لمسات التنسيق الأخرى عليه ليكون تنسيق الجدول ككل قد اكتمل كما في الشكل التالي: تلميحات سريعة لتنسيق الجداول إليك قائمة بأفضل نقاط التنسيق التي ناقشناها في المقال: بسّط شيفرة HTMl الخاصة بالجدول قدر المستطاع، وامنح عناصر الجدول المرونة الكافية كأن تضبط القياسات بنسب مئوية وبهذا سيكون الجدول أكثر استجابة. استخدم قاعدة التنسيق table-layout: fixed كي تنشئ جدولًا بتخطيط نمطي يمكّنك من ضبط أبعاد الأعمدة بسهولة باستخدام الخاصية width على ترويساتها <th>. استخدم القاعدة border-collpse: collapseلتخفي حواف الخلايا مما يعطي الجدول مظهرًا أكثر أناقة. استخدم خطوط حمار الوحش لتمنح أسطر الجدول لونين متناوبين وبالتالي سهولة أكبر في القراءة. استخدم الخاصية text-align لمحاذاة النصوص في عنصر الترويسة <th> والتذييل <td> كي يظهر الجدول أكثر أناقة وأسهل متابعة. الخلاصة بعد أن تعرفنا في هذه المقل على طريقة تنسيق الجداول، لا بد من الانطلاق إلى أفكار جديدة، لهذا سنتابع في المقال التالي تنقيح شيفرة CSS، وكيفية حل المشاكل المتعلقة بالتخطيطات التي لا تبدو كما هو مطلوب أو الخاصيات التي لا تعطي التأثير المطلوب الذي تعتقده. سنعرّج أيضّا على طريقة استخدام أدوات مطوري ويب DevTools المدمجة مع المتصفحات لإيجاد حلول لمشاكلنا. ترجمة -وبتصرف- لمقال Styling tables. اقرأ أيضًا كيفية إنشاء جدول أنيق بـ HTML و CSS أساسيات بناء الجداول في HTML الجداول (Tables) في CSS HTML و CSS للمبتدئين: مقدمة إلى تنسيقات CSS