اذهب إلى المحتوى

حسام برهان

الأعضاء
  • المساهمات

    215
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • عدد الأيام التي تصدر بها

    31

كل منشورات العضو حسام برهان

  1. هناك بعض الصعوبة بالتأكيد، ولكن كونه مبتدئ لن يستطيع العمل مع c++ على أيّة حال فهي ليست للمبتدئين. أمّا بالنسبة للعمل مع بايثون فالهدف منه فهم بنية البرنامج واكتساب التفكير المنطقي السليم لحل أيّ مشكلة برمجيّة. فستكون عمليّة الانتقال المستقبلي إلى أيّ لغة برمجة أخرى (إن تتطلّب الأمر كذلك) لا يتعدّى تعلّم الصيغة النحوية لها syntax. فالمبرمج كما نعلم، ينبغي أن يمتلك التفكير المنطقي والتحليلي لحل أي مشكلة تصادفه بصرف النظر عن لغة البرمجة التي يستخدمها.
  2. إذا كان صديقك مبتدئ تمامًا في البرمجة، فأنصحه بشدة بلغة Python. فهي لغة سهلة التعلّم ومرنة إلى حدّ كبير، فضلًا على أنّها لغة قويّة وتقبل البرامج المكتوبة بها أن تعمل على منصّات مختلفة. كما أنّ المصادر التعليميّة لها كثيرة ومتنوّعة وباللغتين العربية والانجليزية. أنصحه بالبدء بتعلّم الإصدار 3.0 من بايثون Python. بعد تعلّم بايثون وفهم مبادئ البرمجة، يمكنه الانتقال إلى أيّ لغة برمجة أخرى تناسب احتياجاته بسهولة ويسر. بالنسبة للمصادر العربية فيمكنه العمل مع سلسلة تعليم بايثون هنا على أكاديميّة حسّوب: https://academy.hsoub.com/programming/python/ اهم المصادر الانجليزيّة برأيي هي الدروس التي يوفرها الموقع الرسمي للغة: https://docs.python.org/3/tutorial/ بالإضافة إلى هذا الموقع التعليميّ، الذي يوفّر إمكانيّة اختبار البرامج المكتوبة بلغة بايثون مباشرةً على الويب: http://www.learnpython.org/
  3. يمكنك تنفيذ البرامج الموجودة ضمن هذه السلسلة (كما وسبق أن ذكرنا في المقدّمة) بطريقتين مختلفتين: الأولى هي تحميل وتنصيب بيئة التطوير المجّانيّة Visual Studio 2015 Community من مايكروسوفت. توفّر هذه البيئة خدمات عظيمة للمطوّر وتسهّل عمليّة كتابة البرامج إلى حدّ كبير. ويمكنك الاستفادة من مزايا تنقيح الأخطاء debugging المتقدّمة التي يوفّرها المنقّح debugger المرفق ضمن هذه البيئة. يمكنك تحميل نسختك المجّانيّة من هنا. الطريقة الثانية هي في استخدام الموقع NET Fiddle. الذي يوفّر مزيّة تنفيذ البرامج التي تكتبها على خادم خاص به، ومن ثمّ يعرض لك خرج البرنامج، بدون أن تمتلك نظام تشغيل ويندوز حتى. البرنامج الأول سنبدأ بمثال عمليّ لنسبر سريعًا أغوار هذه اللغة. شغّل برنامج Visual Studio 2015 Community ثم من القائمة File اختر الأمر New > Project. من نافذة مشروع جديد New Project، اختر من القسم الأيسر #Visual C ومن القسم الأيمن اختر Console Application. اكتب HelloWorld ضمن حقل الاسم Name في القسم السفلي، ثم اضغط زر OK. انظر الشكل التوضيحي التالي: قد تبدو الصورة مختلفة بعض الشيء لديك بحسب إعدادات الإظهار التي اخترتها. سيعمل Visual Studio على إنشاء هذا التطبيق وفتح ملف مُجهّز خصيصًا لك اسمه Program.cs. امسح محتويات هذا الملف بالكامل ثم انسخ الشيفرة التالية ضمنه: 1 using System; 2 3 namespace HelloWorld 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 Console.WriteLine("Hello World!"); 10 } 11 } 12 } اضغط المفتاحين Ctrl+F5 معًا لتبدأ عملية بناء build البرنامج وتنفيذه لتحصل على العبارة Hello World! في خرج البرنامج (أو من القائمة Debug > Start Without Debugging). رغم أنّ البرنامج السابق بسيط جدًّا إلًا أنّه يحتوي على الكثير من المفاهيم الجديدة التي سنتناولها تباعًا في هذه السلسلة. يبدأ هذا البرنامج بتعريف نطاق اسم namespace (السطر 3) اسمه HelloWorld وهو نفس الاسم الذي زوّدناه للبرنامج، سنتكلّم عن نطاقات الأسماء في درس لاحق، ولكن يكفيك أن تعرف الآن أنّ نطاقات الأسماء هي وسيلة لتنظيم الأصناف ضمن مجموعات مترابطة منطقيًّا. يأتي بعد ذلك تعريف صنف class جديد اسمه Program (السطر 5). يحتاج أيّ برنامج مكتوب بالسي شارب إلى نقطة دخول entry point لكي يبدأ تنفيذه. نقطة الدخول يجب أن تكون عبارة عن تابع method اسمه Main (السطر 7)، تكون التوابع عادةً ضمن الأصناف، يكفيك الآن أن تفهم التابع على أنّه شبيه بالدّالة function في لغات البرمجة الأخرى. أي هو جزء من الشيفرة يمكن استدعاؤه لتنفيذ ناحية وظيفيّة مُحدّدة في البرنامج وقد يُرجع قيمة ما أو لا يُرجع أيّ شيء. العبارة الموجودة في السطر 9 هي عبارة برمجّية قياسيّة في لغة سي شارب. وظيفة هذه العبارة استدعاء التابع WriteLine من الصنف Console وتمرير النص "!Hello World" له لكي يُظهر النص !Hello World في خرج البرنامج. أيّ عبارة برمجيّة في سي شارب يجب أن تنتهي بفاصلة منقوطة (;)، وقد تكون العبارة البرمجيّة مجرّد استدعاء تابع أو أن تكون عمليّة إسناد إلى متغيّر، أو قد تكون مزيجًا بينهما. إذا كانت لديك معرفة سابقة بلغات برمجة مثل C أو ++C أو Java ستلاحظ أنّ الصيغة النحويّة syntax للغة سي شارب تشبه إلى حدٍّ كبير الصيغة النحويّة لهذه اللّغات. حيث تُستخدم الحاضنات { } مثلًا لتحديد البداية والنهاية للتابع method وللصنف class ولنطاق الاسم namespace. وحتى أنّهما يشكّلان حدود أيّ بنية برمجيّة في لغة سي شارب مثل العبارات التكراريّة. انظر على سبيل المثال إلى السطر 6 لتجد الحاضنة "{" الخاصّة بالصنف Program وإلى السطر 12 لتجد حاضنة الإغلاق "}" له. كما ينبغي التنبّه أيضًا إلى كون لغة سي شارب حسّاسة لحالة الأحرف كما هو الحال في لغات البرمجة C و ++C و Java. ملاحظة يمكن استخدام المفتاح F6 في بيئة Visual Studio (أو من القائمة Build > Build Solution) لبناء البرنامج دون تشغيله (تنفيذه) وذلك اعتبارًا من الشيفرة والحصول على ملف تنفيذي منه له الامتداد exe في حال كان البرنامج لا يحتوي على أيّ خطأ. برنامج بسيط لجمع عددين صحيحين لنعمل الآن على برنامج عمليّ أكثر. سنكتب برنامج يعمل على جمع عددين صحيحين وإظهار النتيجة للمستخدم. اتبع نفس الخطوات التي أجريناها في البرنامج السابق لإنشاء برنامج جديد باسم SumTwoNumbers، انسخ محتويات الشيفرة التالية إلى الملف Program.cs: 1 using System; 2 3 namespace SumTwoNumbers 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 int a; 10 int b; 11 int c; 12 13 a = 3; 14 b = 4; 15 16 c = a + b; 17 18 Console.WriteLine("3 plus 4 equals: " + c.ToString()); 19 20 } 21 } 22 } يُقدّم هذا البرنامج البسيط مفهوم التصريح عن المتغيّرات والتعامل معها. صرّحنا في الأسطر من 9 إلى 11 عن ثلاثة متغيّرات a و b و c من النوع int. يجب التصريح في لغة سي شارب عن كل متغيّر قبل استخدامه في البرنامج. لاحظ أنّ التصريح عن متغيّر يتمّ بذكر نوعه ومن ثمّ اسمه. يستطيع المتغيّر من النوع int استيعاب أي عدد صحيح (دون فاصلة عشريّة) يقع بين 2,147,483,648- و 2,147,483,647. لاحظ أنّه قد أسندنا القيمتين 3 و 4 إلى المتغيّرين a و b على الترتيب، وذلك في السطرين 13 و14. نجري عملية الجمع والإسناد إلى المتغيّر c في السطر 16. وفي السطر 18 نعرض رسالة للمستخدم. يمكن إسناد قيمة للمتغيّر مباشرةً عند التصريح عنه. فمن الممكن مثلًا إسناد القيمتين 3 و 4 للمتغيّرين a و b على الترتيب عند التصريح عنهما وذلك بالشكل التالي: int a = 3; int b = 4; كما يمكن استخدام عبارة تصريح واحدة للتصريح عن عدّة متغيّرات بنفس الوقت. فمثلًا كان من الممكن التصريح عن المتغيّرات a و b و c السابقة بعبارة برمجيّة واحدة على الشكل التالي: int a, b, c; في الواقع هناك شكلان من أنواع المتغيّرات تدعمهما منصّة دوت نت. أنواع القيمة value types والأنواع المرجعيّة reference types. سنتحدّث عنهما لاحقًا. يُعتبر النوع int نوع قيمة. يجب إجراء عمليّة إسناد واحدة على الأقل إلى متغيّر قيمة قبل القراءة منه. وإلّا سنحصل على خطأ. جرّب حذف العبارة البرمجيّة الموجودة في السطر 16 والمسؤولة عن إسناد قيمة المجموع إلى المتغيّر c. نفّذ البرنامج وستحصل على الخطأ التالي: Use of unassigned local variable 'c' سبب ذلك أنّنا حاولنا قراءة المتغيّر c في السطر 18 دون أن نُسند أيّ قيمة له. العبارة البرمجيّة الموجودة في السطر 18 مسؤولة عن عرض الرسالة إلى المستخدم كما أسلفنا. ستلاحظ أنّنا مرّرنا التعبير expression التالي إلى التابع WriteLine: "3 plus 4 equals: " + c.ToString() التعبير البرمجي هو مفهوم موجود في جميع لغات البرمجة تقريبًا، وهو ببساطة ناتج عمليّة برمجيّة باستخدام عامل operator واحد أو أكثر، أو استدعاء إلى تابع أو مزيج بينهما. نسمّي عمليّة معالجة التعبير بتقييم التعبير expression evaluation. العامل المُستخدم هنا هو عامل ضمّ النصوص (+)، ولعلّك تستغرب لماذا أدعوه بعامل ضمّ النصوص رغم أنّه يشبه عامل الجمع العادي الذي يجمع عددين مع بعضهما (انظر السطر 16). يعود السبب في ذلك إلى نوع المُعامِلَين operands الموجودين على طرفيه. يمكنك أن تلاحظ بسهولة أنّ المعامل الأيسر هو النص: "3 plus 4 equals: " أمّا المعامل الأيمن فهو: c.ToString() وهو أيضًا نص ويعود سبب ذلك إلى استدعاء التابع ToString من المتغيّر c المعرّف أصلًا أنّه متغيّر من نوع int. ولكنّ استدعاء هذا التابع من المتغيّر c يؤدّي إلى الحصول على التمثيل النصّي للقيمة العددية الموجودة ضمنه أصلًا. فإذا كان المتغيّر c يحمل القيمة العددية 7، فإنّ التابع ToString سيُرجع النص "7"، الذي يعمل عامل الضم + على ضمّه مع النص الذي يسبقه لتكون نتيجة التعبير ككل هي: "3 plus 4 equals: 7" سيُمرّر هذا النص إلى التابع WriteLine لعرضه للمستخدم. أعتقد أنّك قد بدأت بفهم طريقة الوصول إلى التوابع واستدعائها في لغة سي شارب. فنحن نستخدم اسم الصنف (أو الكائن object كما سنرى لاحقًا) الذي يحوي التابع المراد استدعاؤه متبوعًا بنقطة ثم باسم التابع المطلوب، وبعد ذلك قوسين هلاليّين نمرّر بينهما الوسائط التي يطلبها التابع إذا اقتضت الضرورة لذلك. برنامج محسن أكثر لجمع عددين لقد تعلّمنا العديد من المفاهيم الجديدة من خلال البرنامجين السابقين. ولكن لعلّك قد لاحظت من برنامج جمع العددين السابق أنّ البرنامج جامد بعض الشيء. فهو يجمع عدّدين مُحدّدين سلفاً. سنعمل في هذه النسخة المطوّرة من البرنامج على استقبال العددين المراد جمعهما من المستخدم ومن ثمّ إجراء عمليّة الجمع عليهما وعرض النتيجة على المستخدم، مع بعض التحسينات الإضافيّة الأخرى. أنشئ مشروعًا جديدًا باسم EnhancedSumTwoNumbers ثمّ استبدل محتويات الملف Program.cs بالشيفرة التالية: 1 using System; 2 3 namespace EnhancedSumTwoNumbers 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 string str1, str2, result; 10 double num1, num2, sum; 11 12 //prompt user to get input for first value. 13 Console.Write("Input first number: "); 14 str1 = Console.ReadLine(); 15 16 //prompt user to get input for second value. 17 Console.Write("Input second number: "); 18 str2 = Console.ReadLine(); 19 20 //convert the input values to double numbers. 21 num1 = double.Parse(str1); 22 num2 = double.Parse(str2); 23 24 //perform sum operation. 25 sum = num1 + num2; 26 27 /*concatenate strings to form output 28 message which contains the result.*/ 29 result = num1.ToString() + " + " + num2.ToString() + " = " + sum.ToString(); 30 31 Console.WriteLine(result); 32 33 } 34 } 35 } نفّذ البرنامج بضغط المفتاحين Ctrl+F5 معًا. سيطلب منك البرنامج في البداية إدخال قيمة العدد الأوّل. أدخل القيمة المرغوبة ثم اضغط مفتاح الإدخال Enter. بعد ذلك سيطلب منك البرنامج إدخال قيمة العدد الثاني. أدخلها واضغط Enter. سيعرض البرنامج بعد ذلك النتيجة المطلوبة على شكل رسالة مناسبة. تحتوي هذه النسخة من برنامج جمع الأعداد على عدّة تحسينات: أصبح برنامجنا يدعم جمع أعداد تقبل فاصلة عشرية من خلال التصريح عن متغيّرات من النوع double (انظر السطر 10). والنوع double هو النوع الذي يقبل أعدادًا ذات فاصلة عائمة مزدوجة الدقّة. مجال الأعداد التي يقبلها يقع بين ±5.0*10-324 حتى ±1.7*10308. أصبح بإمكان مستخدم البرنامج أن يُدخل الأعداد المراد جمعها مباشرة من لوحة المفاتيح، وذلك من خلال التابع ReadLine من الصنف Console (انظر السطرين 13 و 16) يُوقف هذا التابع تنفيذ البرنامج وينتظر المستخدم أن يُدخل قيمة ما ويضغط مفتاح الإدخال Enter ليتابع البرنامج التنفيذ. أضفنا تعليقات توضيحيّة ضمن البرنامج. هذه التعليقات لا يكترث بها المترجم، ووظيفتها هي جعل الشيفرة البرمجيّة مقروءةً وسهلة الفهم والتعديل لاحقًا. في الحقيقة تُعتبر عمليّة كتابة التعليقات البرمجيّة فنًّا بحد ذاته، وأنصح أن يمارسها كلّ مبرمج بأيّ لغة برمجة كانت. في الواقع ليس مطلوبًا كتابة التعليقات البرمجيّة قبل كلّ عبارة برمجيّة، فعلى المرء أن يكون حكيمًا في استخدامها بالشكل الذي يحافظ فيه على التوازن بين جعل الشيفرة واضحة ومقروءة، وعدم الإفراط في كتابة التعليقات بدون ضرورة. تدعم لغة سي شارب نوعين من التعليقات: التعليقات على مستوى السطر، حيث يتجاهل المترجم compiler كلّ ما يقع على يمين الرمزين//. والتعليقات التي تمتد على عدّة أسطر، حيث يتجاهل المترجم المحتوى الموجود بين الرمزين /* والرمزين */. انظر الأسطر 12 و 16 و 20 و 24 من أجل التعليقات على مستوى السطر، والسطرين 27 و 28 من أجل التعليقات التي تمتدّ على عدّة أسطر. استخدمنا التابع Write بدلًا من التابع WriteLine (انظر السطرين 13 و 17)، والسبب في ذلك هو أنّنا نريد أن يطلب البرنامج من المستخدم إدخال القيمة على نفس السطر الذي تُعرَض فيه الرسالة وليس على سطرٍ منفصل. فالتابع Write يعرض النص المُمرّر إليه ولا يُحدِث سطرًا جديدًا. في حين يسلك التابع WriteLine نفس سلوك التابع Write ولكن ينتقل إلى سطر جديد بعد عرض النص. يمكنك أن تجرّب استبدال التابع WriteLine بالتابع Write لترى الفرق. جعلنا عمليّة تشكيل النص الذي سيُعرض على المستخدم ضمن سطر منفصل (السطر 29) وأسندنا هذا النص إلى المتغيّر result من النوع string. الهدف من هذا الأمر هو جعل الشيفرة نظيفة وواضحة وسهلة للقراءة. النوع string هو من الأنواع المرجعيّة reference types ويُستخدم للتعبير عن النصوص. ولكن تبقى هناك بعض العيوب التي لم نعالجها والتي قد تسبّب توقّف البرنامج عن العمل: تُعتبر القيم التي يدخلها المستخدم بواسطة التابع ReadLine أنّها قيم نصيّة. وحتى نستطيع التعامل معها كأعداد تقبل فاصلة عشريّة يجب تحويلها إلى قيم عددية من النوع double. نستطيع ذلك بسهولة من خلال التابع Parse من الصنف double. يقبل هذا التابع أن نُمرّر إليه قيمة نصيّة ليعيد إلينا التمثيل العددي لها من النوع double. ولكنّ السؤال هنا أنّه ماذا لو أدخل المستخدم بشكل غير مقصود (أو مقصود) القيمة النصيّة التالية "abc" للعدد الأوّل؟ عندما يصل تنفيذ البرنامج إلى السطر 21 سيعمل التابع Parse على تحويل القيمة "abc" إلى التمثيل العددي من النوع double وهذا ما لا يمكن حدوثه بالطبع، لذلك فسيرمي التابع Parse استثناءً Exception سيؤدّي إلى توقّف البرنامج عن العمل فورًا! سنتحدّث عن الاستثناءات في درس لاحق. وعلى أيّة حال يمكن حلّ هذه المشكلة بطريقتين مختلفتين سنتحدّث عنهما لاحقًا في هذه السلسلة. ولكنّ المغزى هنا هو أنّه لا تثق بمدخلات المستخدم مطلقًا. تُعتبر عملية ضم النصوص التي أجريناها في السطر 29 غير عمليّة وعادة برمجيّة غير جيّدة. يتعلّق هذا الأمر بالحقيقة طريقة تعامل سي شارب مع النصوص، سأترك الحديث عن هذه المشكلة وطرق حلّها عندما نتحدّث عن النصوص والتعامل معها في الدرس السادس. تمارين داعمة تمرين 1 اكتب برنامجًا يطبع العبارات التالية كما يلي على الشاشة: Today is Sunday. Tomorrow is Monday. Yesterday is Saturday. تمرين 2 اكتب برنامجًا يطلب من المستخدم إدخال قيمتين عدديتين، ومن ثمّ يوجد حاصل الضرب لهما (استخدام العامل *) وبعرض النتيجة على الشاشة. يجب أن يدعم البرنامج الأعداد ذات الفاصلة العشرية. الخلاصة تعرّفنا في هذا الدرس على الشكل الأساسيّ لأيّ تطبيق مكتوب بلغة سي شارب. كما تعاملنا مع ثلاثة برامج بسيطة للغاية وضّحت مبادئ كتابة برنامج باستخدام سي شارب. سنتناول في الدرس القادم موضوع المتغيّرات وأنواعها والعوامل والتعابير expressions بتفصيل أكبر.
  4. يُعتبر إطار العمل دوت نت NET Framework. من شركة مايكروسوفت من أُطر العمل المشهورة جدًّا، فمنذ الإصدار التجريبي الأوّل أواخر عام 2000 وحتى الإصدار 4.6 حاليًّا شهد تحسينات كبيرة جعلت من لغات البرمجة التي تعمل بالاعتماد عليه لغات برمجة غنيّة ومعاصرة. يُعتبر إطار العمل دوت نت الكيان الأساسيّ التي تعتمد عليه التطبيقات في تنفيذ المهام المطلوبة منها. فهو يوفّر الوسائل اللازمة لوصول مثل هذه التطبيقات إلى الملفات والتعامل مع HTTP والوصول والتعامل مع قواعد البيانات وغيرها من المهام الأساسيّة التي قد يحتاجها أيّ تطبيق حاسوبيّ. صُمّم إطار العمل دوت نت منذ البداية لكي يعمل على أيّ نظام تشغيل أو أيّ عتاد صلب متاح، وعلى الرغم من أنّ مايكروسوفت لم تدعم تشغيل إطار العمل هذا سوى على أنظمة تشغيل ويندوز، إلّا أنّه جرت محاولات مستقلة لنقله إلى لينكس عن طريق مشروع mono مفتوح المصدر. وقد نجحت هذه المحاولة بصورة لا بأس بها واستمر المشروع لعدّة سنوات، ثمّ توّج بنقله إلى أنظمة تشغيل الأجهزة الذكيّة وهذا ما قامت به شركة Xamarin التي استحوذت عليها شركة مايكروسوفت قبل أقل من شهر من الآن، حيث تمكّنت Xamarin من ذلك بالاعتماد على مشروع mono مفتوح المصدر. تُعتبر لغة سي شارب #C لغة البرمجة الأساسيّة ضمن إطار العمل دوت نت، وقد واكبْتُ تطوّرها منذ الإصدار الأوّل وحتى اليوم. ومما لا شكّ فيه أنّها قد شهدت تحسينات كبيرة ومزايا مفيدة تجمع بين القوّة والمرونة لتطوير طيف واسع من التطبيقات البرمجيّة تشمل تطبيقات سطح المكتب Desktop Applications وتطبيقات ويب باستخدام ASP.NET وتطبيقات خدمات ويب مثل WCF (اختصار لـ Windows Communication Foundation) وحتى تطبيقات الأجهزة الذكيّة التي تعمل على نظام تشغيل Windows Phone أو التي تعمل على باقي الأنظمة مثل Android و iOS من خلال منصّة Xamarin. لن ندخل في التفاصيل الدقيقة لمعمارية إطار العمل دوت نت، وذلك لجعل هذه السلسلة مبسّطة قدر المستطاع. يكفيك أن تعلم أنّ إطار العمل هذا يتكوّن من قسمين رئيسيّين: بيئة التنفيذ المشتركة Common Language Runtime وتُدعى اختصارًا CLR. مكتبة أصناف إطار العمل Framework Class Library وتُدعى اختصارًا FCL. حول هذه السلسلة سنتعلّم في هذه السلسلة كتابة تطبيقات باستخدام لغة سي شارب #C بأسلوب مبسّط وسلس وذلك من خلال تطبيقات موجّه الأوامر Console Applications، وسبب تفضيلي لهذه التطبيقات عن سواها، هو أنّه تسمح لك بالتركيز على تعلّم اللغة نفسها دون تشتيت الانتباه إلى العديد من الجوانب التي تتطلّبها أنواع التطبيقات الأخرى كتطبيقات سطح المكتب لويندوز على سبيل المثال، رغم أنّنا سنتحدّث القليل عنها في الدرس الأخير. ما الذي أحتاجه لكي أستفيد من هذه السلسلة؟ تفترض هذه السلسلة أنّك تمتلك معرفة عامّة بأساسيّات البرمجة. ستحتاج أيضًا إلى حاسوب ذو نظام تشغيل ويندوز 7.1 أو أعلى. بالإضافة إلى تحميل وتنصيب بيئة التطوير Visual Studio 2015 Community المجّانيّة. كما يمكنك تجريب معظم البرامج الموجودة في هذه السلسلة حتى ولو لم يكن لديك نظام تشغيل ويندوز أصلًا عن طريق موقع NET Fiddle. ولكن لن تستفيد بهذه الطريقة من المزايا الهامّة التي يوفّرها لك Visual Studio. الأقسام الأساسية لإطار العمل دوت نت سنتحدّث قليلًا عن القسمين الأساسيّين لإطار العمل دوت نت بالإضافة إلى مترجم سي شارب C# Compiler، لكي تتكوّن لدينا الصورة الواضحة لآليّة عمل تطبيقات دوت نت. بيئة التنفيذ المشتركة CLR هي البيئة التي تنفّذ البرامج المكتوبة بلغات دوت نت، وتشكّل حاضنةً لهذه البرامج من خلال عزلها عن العتاد الصلب hardware للجهاز التي تعمل عليه. تستطيع تشبيهها بالآلة الافتراضيّة Virtual Machine الخاصّة بلغة Java. وهي مسؤولة عن إدارة المصادر التي يحتاجها البرنامج في عمله، وفي مقدّمتها الذاكرة. حيث تعمل هذه البيئة على إدارة عمليّات إنشاء الكائنات التي يحتاجها البرنامج، ومن ثمّ التخلّص منها عند انتفاء الحاجة إليها. تتوفّر CLR بشكل افتراضيّ على معظم أنظمة تشغيل ويندوز (مع الاختلاف بالإصدارات) مثل Windows XP و Windows 7 و Windows 8 و Windows 10 و Windows Phone و Windows Server (بمعظم إصداراته). مكتبة أصناف إطار العمل FCL تحتوي هذه المكتبة الضخمة على آلاف الأصناف classes التي تسمح لنا بإنجاز أيّ مهمّة تخطر ببالنا. فمن التعامل مع النصوص والتعابير النظاميّة regular expressions إلى التعامل مع الاتصالات الشبكيّة network communications والتعامل مع بروتوكولات الانترنت الشهيرة مثل HTTP وFTP وغيرها، والوصول إلى قواعد البيانات والتعامل معها. تتكوّن FCL بدورها من عدّة مكتبات فرعيّة، فهناك مكتبة تساعدنا على تطوير وبرمجة تطبيقات سطح المكتب لويندوز، وأخرى تسمح لنا بتطوير تطبيقات ويب باستخدام تقنيّة ASP.NET، ومكتبة تسمح بإنشاء تطبيقات WCF وهكذا. بمعنى أنّه لن تحتاج إلى التعامل مع كامل مكتبة FCL بل ستنتقي منها ما تحتاجه بحسب متطلّبات عملك، فإذا كنت مطوّر ويب مثلًا فستهتم بالمكتبة الفرعيّة التي تسمح بإنشاء تطبيقات ويب باستخدام ASP.NET. ومن الجدير ذكره أنّ مكتبة FCL تحتوي أيضًا على مكتبة فرعيّة اسمها مكتبة الأصناف الأساسيّة Base Class Library أو اختصارًا BCL، تحتوي هذه المكتبة على الأصناف الأساسيّة التي تعمل مع جميع التطبيقات المنشأة باستخدام المكتبات الأخرى بصرف النظر عن نوعها. مترجم سي شارب C# Compiler لكي نتمكّن من تنفيذ البرامج التي نكتبها باستخدام سي شارب، نحتاج إلى مترجم سي شارب C# Compiler. يكون هذا المترجم مضمّنًا بشكل افتراضيّ مع إطار العمل دون نت. يعمل المترجم على تحويل التعليمات البرمجيّة الموجودة في الشيفرة والمكتوبة بلغة سي شارب إلى تعليمات برمجيّة مكتوبة بلغة تُعرف بلغة مايكروسوفت الوسيطيّة Microsoft Intermediate Language أو اختصارًا MSIL. تُعتبر هذه اللغة الوسيطيّة منخفضة المستوى، وهي شبيهة بلغة Assembly الشهيرة. في الواقع ستعمل بيئة التنفيذ المشتركة CLR على تنفيذ التعليمات المكتوبة بلغة MSIL. فبيئة CLR لا تحتاج أن تعرف لغة البرمجة التي كُتب بها البرنامج أصلًا وهي الميزة الأساسيّة التي تسمح للمبرمج الكتابة بأي لغة برمجة تدعم الدوت نت. فطالما أنّ لغة البرمجة تمتلك مترجمًا متوافقًا مع MSIL فلا مشكلة. وهذا ما جرى مع لغات برمجة أخرى مثل Visual Basic.NET ولغة #F وحتى لغة البايثون Python من خلال IronPython. انظر الشكل التوضيحي التالي: كيف ينفذ البرنامج باستخدام CLR؟ توضع الشيفرة البرمجيّة المكتوبة بلغة سي شارب عادةً في ملفات منفصلة لكلٍّ منها الامتداد cs، يعمل المترجم بعد ذلك على قراءة هذه الملفات التي تسمّى بملفّات النص المصدريّ source code files وتحويل التعليمات البرمجيّة المكتوبة بسي شارب إلى لغة MSIL وجعلها ضمن ملف تنفيذي (الملف MyApp.exe في الشكل السابق). عند تنفيذ البرنامج تقرأ CLR التعليمات البرمجيّة الموجودة ضمن الملف التنفيذي والتي تكون بلغة MSIL وتعمل على تنفيذها عن طريق تحويلها إلى تعليمات برمجيّة أصليّة native code مخصّصة لمعالج الحاسوب الذي يعمل عليه البرنامج حاليًّا. يجري كلّ هذا العمل بسرعة كبيرة جدًّا فعملية التحويل إلى native code لا تجري سوى أوّل مرّة فقط، وبعد ذلك يستفيد البرنامج من السرعة الكبيرة التي توفّرها هذه التعليمات الأصليّة عند التنفيذ. يُفسّر السيناريو السابق سبب قابليّة عمل برامج دوت نت على أيّ نظام تشغيل أو عتاد حاسوبي. فعمليّة كتابة الشيفرة البرمجيّة بأي لغة دوت نت ومن ثمّ تحويلها إلى لغة مايكروسوفت الوسيطيّة MSIL منفصلة تمامًا عن نظام التشغيل وعن العتاد الحاسوبي الذي سيعمل عليه البرنامج. ولعلّ من أبرز الأمثلة على ذلك البرامج المكتوبة بلغة سي شارب والموجّهة إلى أنظمة تشغيل الأجهزة الذكيّة عن طريق منصة Xamarin التي ذكرناها قبل قليل. فالعمل الأساسي الذي قامت به هذه الشركة هو انتاج بيئة CLR منفصلة لكلّ نظام تشغيل مثل Android و iOS مما يسمح للبرامج المكتوبة بلغة سي شارب الخروج من "قمقم" ويندوز إن صحّ التعبير. وأكثر من ذلك، فقد أنتجت مايكروسوفت مؤخّرًا نسخة خاصّة وخفيفة من نظام التشغيل Windows 10 أسمته Windows 10 IoT وهو مخصّص لإنترنت الأشياء. يمكن تنصيب نظام التشغيل هذا بكلّ سلاسة ويُسر على جهاز Raspberry Pi المشهور والموجّه لتطبيقات إنترنت الأشياء، وهذا يعني فتح المجال أمام التطبيقات المكتوبة باستخدام لغة سي شارب للعمل على هذا الجهاز وبالتالي الدخول في هذا المجال المهم والواعد. الخلاصة لغة سي شارب هي لغة عصريّة ولها مستقبل واعد في قطاع الأعمال. فهي اللغة الأساسيّة المستخدمة لكتابة مختلف أنواع التطبيقات الحاسوبيّة ضمن إطار العمل دوت نت. بالإضافة إلى أنّها سلسة وذات بنية مألوفة، ولكن تحتاج إلى قليل من الصبر في تعلّمها. سنتناول في الدروس اللّاحقة كيفيّة كتابة برامج بسيطة ولكن متدرّجة في الصعوبة حتى تكون ملمًّا بأساسيّات هذه اللغة الرائعة.
  5. لم يعد إنشاء تصاميم متجاوبة اختياريًّا، فلقد أصبحت شبكات CSS وعلى نحو سريع الخيّار المفضّل لإنشاء بنى منسجمة لمواقع ويب تبدو بمظهر رائع على مختلف أنواع الأجهزة. تزوّدنا شبكات CSS بطريقة سريعة لبناء أيّ موقع. فلا بدّ أن تكون قد عانيت مع خصائص التموضع والتعويم float في CSS من قبل. كل هذه المعاناة ستنتهي مع شبكات CSS. تجعل شبكات CSS3 من عمليّة إنشاء وتعديل موقع، شيئًا يسيرًا للغاية. سنتعلّم كيف تعمل هذه الشبكات ولماذا ينبغي علينا استخدامها، وكيف ننشئ شبكاتنا الخاصّة بنا لبناء layouts مُخصّصة. ما هو نظام شبكة CSS؟ قبل أن نبدأ بإنشاء بنية خاصّة بنا، هناك بعض الأمور التي نحتاج أن نعرفها مسبقًا. لإنشاء مخطّط لموقع ويب جديد نبدأ أولّا بشبكة. ستحتوي هذه الشبكة الأساسيّة على أسطر rows وأعمدة columns وخلايا cells ومسارات tracks وخطوط lines ومناطق areas. هناك أيضًا عناصر الشبكة وهي بشكل أساسي عبارة عن المحتوى الذي نضعه ضمن الشبكة. تشبه الشبكة الجدول من ناحية الإظهار. ولكن يكمن الفرق الكبير بينهما في وجود خصائص مُحدّدة وقويّة متاحة ضمن شبكة CSS، سنتحدّث عنها بعد قليل. تحمل الأسطر والأعمدة والخلايا نفس المعنى في كلّ من شبكات CSS وجداول HTML العاديّة. أمّا المسار track فهو عبارة عن سطر كامل أو عمود كامل. المسار track في الشبكة، عبارة عن سطر كامل أو عمود كامل. وبالنسبة للمنطقة فهي مكوّنة من خلايا تشكّل حاويةً مستطيلة الشكل للمحتوى، في حين أنّ خطوط الشبكة grid lines هي الفواصل بين الخلايا في البنية الشبكيّة، وهي تشبه على أية حال حدود الخلايا في جداول HTML العاديّة. تشكّل المناطق مقاطع بنيويّة ذات طبيعة متنوّعة، مثل المناطق الخاصة بالعنوان header والشريط الجانبي sidebar والمحتوى الأساسي والتذييل footer. تشكّل المنطقة area مقاطع بنيويّة متنوّعة في الشبكة. بتعريف هذه المناطق باستخدام شيفرة CSS الجديدة المتاحة، يمكننا إنشاء وتنسيق البنية الشبكيّة المطلوبة، بنفس السرعة التي تحتاجها لإنشاء بنية جدوليّة قديمة، ولكن بمزايا قابلية التعديل والتغيير بسهولة أكبر بكثير. المشكلة الوحيدة في شيفرة CSS الجديدة هي أنّها حتى هذه اللحظة ليست متوافقة بشكل كامل مع جميع المتصفّحات، ولكن تبقى مسألة وقت قبل أن تصبح قياسيّة في المدى القريب، بحيث تعمل على جميع المتصفّحات الأساسيّة المعاصرة. يمكنك تجربة مزايا الشبكة الجديدة مع جميع المتصفّحات من خلال إضافة يمكن الحصول عليها من هنا. يمكننا في متصفّح Chrome تفعيل منصّة الويب التجريبيّة experimental web platform بكتابة العنوان التالي في شريط عنوان المتصفّح: Chrome://flags انتقل إلى الأسفل حتى تصل إلى قسم تفعيل مزايا منصّة ويب التجريبيّة Enable Experimental Web Platform features ثم انقر Enable تحت العنوان. يمكننا اختبار شبكات CSS3 في متصفّح Chrome بإجراءات بسيطة. انقر بعد ذلك زر إعادة التشغيل الآن Relaunch Now وهذا كلّ شيء. أصبحنا الآن مستعدّين لتجربة شبكات CSS في Chrome ضمن أنظمة تشغيل Windows و Mac و Linux وحتى أجهزة Android. إعداد الشبكات باستخدام HTML5 الآن وبعد تفعيل الأدوات التجريبيّة، يمكننا البدء بإنشاء البنية الشبكيّة. نحتاج إلى صفحة لاختبار تأثيرات شيفرة CSS، انشأ ملف index.html. نحن مستعدّون الآن لإضافة شيفرة HTML5 أساسيّة لعرض أي شبكة ننشئها بعد قليل. سننشئ منطقة خاصّة بالعنوان header وأخرى خاصّة بالتذييل footer بالإضافة إلى منطقة خاصّة بالمحتوى content ومنطقة للشريط الجانبيّ sidebar على الجانب الأيمن من الصفحة. لنضيف الشيفرة التاليّة إلى الصفحة: <div id="grid"> <div class="header"></div> <div class="sidebar"></div> <div class="content"></div> <div class="footer"></div> </div> يمكننا وبشكل اختياري أن نضيف محتوى إلى كلّ قسم من الأقسام السابقة إذا أردنا أن نرى أين ستظهر الشبكة بعد الانتهاء. تنسيق الشبكة بشيفرة CSS قبل أن نبدأ بتنسيق الشبكة يجب أن نعلم أنّ هناك بعض تنسيقات CSS لا تعمل مع الشبكات: الخصائص column-* أي جميع الخصائص التي تبدأ بـ column- مثل column-span و column-width و column-rule. الخاصيّة float، وهذه الخاصيّة يمكن استخدمها إذا طبّقتها قبل تطبيق الخاصيّة display التي تُعيّن طريقة العرض إلى شبكة كما سنرى بعد قليل. لن يكون بالإمكان تعويم float المحتوى داخل الشبكة. الخاصيّة clear، حيث أنّه بمجرّد العمل مع بنى الشبكات فلا داعي لاستخدام هذه الخاصيّة لأنّ الشبكة تتجاهلها. الخاصيّة vertical-align، لا تمتلك هذه الخاصيّة أي تأثير على بنية الشبكة. العنصرين الزائفين first-line:: و first-letter:: لا يمكن تطبيقهما ضمن الشبكة. بالنسبة لأي خاصيّة CSS غير موجودة في القائمة السابقة فيمكن استخدامها مع الشبكات. قم بإنشاء الملف style.css لنعمل على تطبيق بنية الشبكة على التصميم. سنبدأ الآن باستخدام مُحدّد معرّف العنصر كما يلي: #grid { display:grid; } إذا وجدت أنّ تموضع الشبكة ليس مناسبًا، جرّب تغيير الخاصية السابقة لتصبح display:inline-grid حيث يؤدي ذلك إلى إنشاء البنية ضمن المنطقة التي تعمل ضمنها بدلًا من إنشاء حاوية مُخصّصة كما تفعل القيمة block عند استخدامها. نلاحظ أنّ الشبكة قد تمّ إنشائها ولكنّها فارغة. لإنشاء الخلايا يمكننا استخدام grid-template-rows و grid-template-columns بحيث نضعهم أسفل الخاصيّة display التي عرّفناها قبل قليل. القيم التي يمكن تزويدها لهاتين الخاصيّتين هي قيم أحجام الخلايا التي نرغب بإنشائها. فمثلًا إذا عرّفنا قيمة حجم واحدة من أجل سطر ما، فسيؤدّي ذلك إلى إنشاء سطر واحد فقط، في حين يؤدّي تعريف خمس قيم حجم إلى إنشاء خمسة أسطر. ويمكن تطبيق نفس الأسلوب على الأعمدة. فلإنشاء البنية السابقة المقترحة، يمكننا تعريف الأسطر والأعمدة على الشكل التالي: #grid { display:grid; grid-template-rows:100px auto 100px; grid-template-colums:repeat(9, 100px); } أنشأنا في المثال السابق ثلاثة أسطر وتسعة أعمدة. يبلغ ارتفاع السطر الأوّل 100 بيكسل، أمّا السطر الثاني فسيتم ضبطه تلقائيًّا بحيث يلائم المحتوى المُضاف بالنسبة إلى الشبكة، وسيبلغ ارتفاع السطر الثالث 100 بيكسل أيضًا. تسمح لنا الدالّة repeat بإنشاء أي عدد من الأعمدة أو الأسطر طالما أردنا أن يكون لها نفس القياس. في مثالنا هذا سننشئ تسعة أعمدة بعرض 100 بيكسل لكلٍّ منها. يبدو للوهلة الأولى أنّنا أضفنا عددًا عشوائيًّا من الأعمدة، خصوصًا أنّه لدينا خمس مناطق areas في البنية التي خطّطنا لها مسبقًا. تكمن الإجابة على ذلك أنّه بإمكاننا أن نجعل المناطق تمتد span على أكثر من خليّة، ويسمح لنا ذلك بضبط الحجم الافتراضي لكلّ منطقة بشكل فعّال. في مثالنا هذا ومن أجل سطر واحد يمكن أن تمتدّ المنطقة التي تضمّ المحتوى الرئيسي عبر سبعة أعمدة بحيث يبلغ العرض الافتراضي لها 700 بيكسل، كما يمتدّ الشريط الجانبيّ عبر عمودين ليصبح عرضه 200 بيكسل، وهكذا نحصل على عرض إجمالي قدره 900 بيكسل. لاحظ أنّه كان بإمكاننا تعريف عدد أقل من الأعمدة بعرض أكبر لكلّ منها، ولكننا لم نفعل ذلك. يكمن السبب في أنّه عند استخدام عدد أعمدة أكبر بعرض أصغر لكلّ منها، فإنّ ذلك سيؤدّي إلى تحكّم أكبر في عرض المناطق الممتدة على تلك الأعمدة، وخاصةً التي تحتاج إلى عرض قليل نسبيًّا مثل المنطقة التي نضع فيها حقوق التأليف والنشر مثلًا. تُطبّق نفس الفكرة تمامًا من أجل الأسطر، لكن لاحظ بأنّنا قد اخترنا عددًا قليلًا منها ممّا لا يمنحنا نفس المرونة المتوفّرة بالنسبة للأعمدة. على العموم لا بأس في ذلك، فهدفنا هنا هو تحقيق الفكرة والتعلّم حول الإمكانيّات المتوفّرة لتخطيط البنية الشبكيّة. لا تبدو الأمور حتى الآن كما هو مخطّط لها، لكن بمجرّد تعريف وتسمية مناطق الشبكة ستأخذ البنية الشبكيّة الشكل المطلوب. لتسمية المناطق فإنّنا نعيّن اسم المنطقة لكلّ عمود وسطر ستمتدّ عليه هذه المنطقة. يمكننا استخدام الخاصيّة grid-template-areas بحيث نضعها أسفل الخاصّتين المسؤولتين عن تعيين عدد الأسطر والأعمدة الّلتين أضفناهما قبل قليل، أي على النحو التالي: #grid { display:grid; grid-template-rows:100px auto 100px; grid-template-colums:repeat(9, 100px); grid-template-areas: "header header header header header header header header header" "content content content content content content content sidebar sidebar" "footer footer footer footer footer footer footer footer footer"; } نلاحظ من السطر الأوّل أنّ المنطقة header تمتدّ على كامل الأعمدة، وكذلك الأمر بالنسبة للمنطقة footer على السطر الثالث. أمّا السطر الثاني فسيحتوي على منطقة المحتوى الرئيسي main بالإضافة إلى منطقة الشريط الجانبي sidebar. حتى هذه اللحظة لم يتم إنشاء الشبكة بعد. في الحقيقة تُشير الأسماء المعرّفة توًّا: header و content و sidebar و footer إلى أسماء أصناف CSS سنعرّفها بعد قليل. بحيث نستخدم خصائص جديدة مع هذه الأصناف تُشير إلى بداية ونهاية كل منطقة بالنسبة للأسطر: grid-row-start و grid-row-end وبالنسبة للأعمدة: grid-column-start و grid-column-end. يمكن إضافة أصناف CSS هذه مباشرةً بعد شيفرة الشبكة السابقة: .header { grid-row-start:1; grid-row-end:2; grid-column-start:1; grid-column-end:10; } .content { grid-row-start:2; grid-row-end:3; grid-column-start:1; grid-column-end:8; } .sidebar { grid-row-start:2; grid-row-end:3; grid-column-start:8; grid-column-end:10; } .footer { grid-row-start:3; grid-row-end:4; grid-column-start:1; grid-column-end:10; } .content { grid-row-start:3; grid-row-end:4; grid-column-start:1; grid-column-end:7; } تُحتسب المناطق اعتبارًا من خطّ البداية (سطر أو عمود) إلى الخطّ الذي يلي خطّ النهاية الفعليّ حتى ولو لم يكن هذا الخط موجودًا، فإذا لم نأخذ هذا الأمر بعين الاعتبار، فمن الممكن إسناد نفس القيمة للبداية وللنهاية لمنطقة ما وبالتالي لا تظهر هذه المنطقة أبدًا. بهذا نكون قد انتهينا من إعداد الشبكة ويمكن البدء بإضافة التنسيقات المرغوبة. الأمر السلبيّ الوحيد في التصميم السابق أنّه ليس متجاوبًا مع شاشات الأجهزة المحمولة. جعل البنية متجاوبة مع الأجهزة المحمولة وفقًا لهذا التقرير فإنّ أكثر من نصف مجموع الأوقات التي قضاها المستخدمون على الانترنت في النصف الأوّل من عام 2015 كانت على الأجهزة المحمولة. وهذا يزيد بمقدار 11% عمّا كان عليه الوضع في العام السابق ويزيد بمقدار 39% عمّا كان عليه في عام 2008. من الملاحظ أنّ عدد الساعات التي يتمّ قضائها على الأجهزة المحمولة في ازدياد مطّرد، فإن لم نجعل موقعنا متجاوبًا مع هذه الأجهزة فسيفوتنا القطار! قد تبدو هذه العمليّة صعبة للوهلة الأولى، ولكنّ الأمر ليس بهذه الصعوبة. يوجد أسلوب أساسيّ يمكن من خلاله جعل البنية الشبكيّة متجاوبة، حيث يمكن باستخدام القاعدة media@ والخاصيّتان max-width و min-width أن نسمح للمتصفّح بعرض محتوى مناسب إذا استُخدم الجهاز المحمول لعرض الموقع. يمكن باستخدام القاعدة media@ تعريف أنماط تنسيق مُحدّدة للموقع بحيث تُطبّق عند استعراض هذا الموقع ضمن شاشة الجهاز المحمول. تسمح الخاصيّة max-width بشكل عام لأيّ عنصر بالالتزام بقياس مُحدّد عن طريق إسناد العرض الأعظمي للمنطقة التي يُسمح للمحتوى الخاص به أن يشغلها. تخبر هذه الخاصيّة موقعنا بأنّه من الممكن أن ندع محتويات المناطق تكبر أو تصغر طالما أنّها لا تتجاوز القيمة التي حدّدناها ضمن الخاصيّة max-width. أمّا عند استخدام الخاصيّة max-width مع القاعدة media@ فسيكون للخاصيّة max-width دور جديد وهو تحديد شرط لتطبيق أنماط تنسيق مُحدّدة عندما يتم استخدام شاشات صغيرة، كشاشات الأجهزة المحمولة. وينطبق نفس الأسلوب تمامًا على الخاصيّة min-width عند استخدمها مع القاعدة media@. الآن لنضع القاعدة التالية أوّل تنسيقات CSS التي أضفناها إلى ملف التنسيق: @media (max-width:900px) and (min-width:500px) { /* Your grid layout code goes here */ } ستُطبّق التنسيقات الموجودة ضمن القاعدة media@ عندما يُستخدم أيّ جهاز يتراوح عرض شاشته بين 900 بيكسل (العرض الأعظمي max-width) و500 بيكسل (العرض الأصغري min-width). لا ننسى بالطبع تعديل هذه القيم بما يتلاءم مع احتياجاتنا. التغييرات البسيطة في البنية لنضع الآن جميع التنسيقات مع بعضها البعض، ونضيف المزيد منها إلى البنية الجديدة. الشكل النهائي لملف تنسيقات CSS سيبدو مشابهًا لما يلي: @media (max-width:900px) and (min-width:500px) { #grid { display:grid; grid-template-rows:100px auto 100px; grid-template-colums:repeat(9, 100px); } } .header { grid-row-start:1; grid-row-end:2; grid-column-start:1; grid-column-end:10; } .content { grid-row-start:2; grid-row-end:3; grid-column-start:1; grid-column-end:8; } .sidebar { grid-row-start:2; grid-row-end:3; grid-column-start:8; grid-column-end:10; } .footer { grid-row-start:3; grid-row-end:4; grid-column-start:1; grid-column-end:10; } .content { grid-row-start:3; grid-row-end:4; grid-column-start:1; grid-column-end:7; } وهنا صورة تمثيليّة لما سنحصل عليه ضمن المتصفّح: صورة تمثيليّة للشكل الناتج يتألّف من ترويسة ومنطقة محتوى رئيسيّة وشريط جانبي ومنطقة للتذييل. إذا أردنا في أيّ وقت تعديل البنية الشبكيّة السابقة، فكل ما علينا فعله هو إعادة تعريف المناطق بتغيير مواقع البداية والنهاية لها لنحصل على الشكل المرغوب. وهذا يساعدنا على الانتقال إلى أيّ شكل جديد دون الحاجة لإعادة تصميم الصفحة بشكل كامل. توجد هناك تقنيّات متقدّمة يمكننا استخدمها لإضافة المزيد من المزايا إلى هذه البنية، يمكننا كما هو متوقّع استخدام تنسيقات CSS المألوفة لإكساب بنيتنا الجديدة تنسيقات جميلة وجذّابة. خاتمة نحن مستعدّون الآن لاستخدام آخر التحسينات في عالم CSS، يمكننا الآن فهم وإنشاء عناصر جديدة ومختلفة وتجميعها معًا لتشكيل بنية شبكيّة. أنصح بمراجعة وثائق العمل الحاليّة الخاصّة بالبنية الشبكيّة، وبشكل دوريّ، للاطّلاع على آخر المستجدّات حالما تصدر. ترجمة -وبتصرّف- للمقال Understanding CSS Grids for Modern WordPress Website Design لصاحبته Jenni McKinnon.
  6. أحيلك إلى هذا السؤال: ولكن أرجو التنبّه من أمرين: 1- هل تجدر الثقة في مثل هذا الشخص الوارد اسمه في تلك المشاركة. 2- مجرّد أن تدخلي إلى حساب paypal من سوريا سيعمل باي بال على إيقاف الحساب. أنصحك أن تجدي أحد أقربائك أو معارفك ممن تثقين بهم، ويفضّل أن يكونون بدول يمكن التحويل منها بسهولة إلى سورية كالإمارات مثلاً.
  7. يحتوي مشروع الملف الشخصي الخاص بنا على صفحة واحدة حتى الآن. من الواضح أنّ معظم مواقع الويب تمتلك أكثر من صفحة. سنُضيف في هذا الدرس صفحات إضافيّة. إنشاء صفحة جديدة سننشئ ثلاث صفحات جديدة، صفحة من أجل مدوّنة الموقع Blog، وصفحة من أجل المشاريع Projects وأخرى من أجل معلومات التواصل Contact. ستكون هذه الصفحات الرئيسيّة في الموقع. يجب أن نتذكّر دائمًا أنّه يمكن أن نضيف صفحات فرعيّة أخرى لاحقًا. فمثلًا سيكون هناك صفحة فرعيّة لكل تدوينة ضمن المدوّنة. لامتلاك بنية جيّدة ضمن الموقع من الأفضل إنشاء مجلّدات فرعيّة من أجل كلّ صفحة. سيكون لكل مجلّد فرعي ملف index.html خاص به يُعرَض افتراضيًّا عندما يفتح المتصفّح هذا المجلّد. يُعتبر إنشاء صفحة جديدة أمر سهلًا للغاية. من الأفضل نسخ ملف index.html الذي أنشأناه مسبقًا بحيث يكون لدينا البنية الأساسية جاهزة. بعد ذلك نُجري بالطبع بعض التعديلات المناسبة لكلّ صفحة جديدة. ملاحظة: يجب أن نتأكّد بأنّنا لا نستخدم أيّ رمز خاص أو فراغات عند تسمية أي مجلّد فرعي أو ملف. يجب أن نستخدم الأحرف القياسيّة ويُفضّل أن تكون بحالة صغيرة lower case، ومن الجيّد أيضًا فصل الكلمات عن بعضها باستخدام إشارة الناقص (-). صفحة المدونة أنشئ مجلّدًا فرعيًّا ضمن مجلّد portfolio وسمّه blog. انسخ الملف index.html إلى هذا المجلّد الفرعي الجديد. يجب الآن أن تبدو بنية الملفات لديك على الشكل التالي: افتح الملف المنسوخ blog/index.html في المتصفّح (إذا كنت تستخدم Brackets انقر زر Live Preview). ستلاحظ وجود أمرين لا يعملان بشكل صحيح: صور الصفحة لا تظهر. الألوان المعرّفة ضمن ملف css غير مُطبّقة في هذه الصفحة. يعود السبب في ذلك هو أنّنا ضمن مجلّد فرعي، فالمسار الخاص بملفات الصور لم يعد صحيحًا. لكي نسمح للصور بالظهور يجل أن نستخدم المسار marco.jpg/.. بدلًا من marco.jpg ضمن السمة src لعنصر الصورة img. ولكن من المؤكّد أنّنا لن نريد استخدام نفس الصور ضمن صفحة المدوّنة. لذلك يمكن إزالة العنصر img بشكل كامل. جرت العادة أن نعرّف قواعد css بحيث تكون شاملة لكل صفحات موقع الويب. وهكذا فإنّه من الضروري أن نشير إلى نفس ملف css الذي يحوي هذه القواعد وذلك ضمن ملف المدوّنة. يمكننا ذلك بتغيير عنوان URL من main.css إلى main.css/.. ضمن عنصر link. يوضّح السطر التالي شكل عنصر link بعد تعديل الملف blog/index.html: <link rel="stylesheet" href="../main.css"> سيؤدي تعديل عنوان ملف css ضمن عنصر link إلى تطبيق تنسيقات css الموجودة ضمن الملف main.css على صفحة المدوّنة. سنغيّر الآن عنوان ومحتوى صفحة المدوّنة. blog/index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="../main.css"> <title>Blog - Web Portfolio of Marco</title> </head> <body> <h1 class="title">Blog</h1> <p>I write about things I encounter while learning web programming.</p> <h2>Blog Entries</h2> <!-- Here will be a list of all the blog entries. --> </body> </html> يمكننا رؤية بعض الوسوم الجديدة في الشيفرة السابقة وهي <-- و --!> حيث يمكننا أن نكتب تعليق comment بين الرمزين السابقين. الهدف من التعليقات هو كتابة بعض الملاحظات التوضيحيّة لنا فقط، فهي لا تظهر لمستخدم الصفحة. التدوينة كصفحة فرعية تحتاج مدوّنتنا بالطبع إلى بعض المُدخلات (التدوينات). سننشئ صفحة HTML مستقلّة من أجل كل تدوينة. أنشئ مجلّدًا فرعيًّا ضمن المجلّد blog وسمّه first-entry ثمّ انسخ الملف blog/index.html إلى المجلّد الفرعي first-entry: افتح ملف التدوينة وغيّر محتوياته كما يلي: blog/first-entry/index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="../../main.css"> <title>First Entry - Web Portfolio of Marco</title> </head> <body> <h1 class="title">First Entry</h1> <p>April 7, 2015</p> <hr> <p>This is my very first blog entry.</p> </body> </html> لقد وضعت في الشيفرة السابقة عنصر HTML جديد وهو <hr> حاول أن تعرف وظيفته بمفردك، حاول مثلًا إزالته ومن ثمّ انظر إلى تأثير ذلك على الصفحة. أو يمكنك البحث عن معلومات عنه في الانترنت. لنبدأ بكتابة التدوينات أنصح دائمًا أن تبدأ فورًا بكتابة تدويناتك. يمكنك كتابة تدوينة قصيرة في كل مرّة تتعلّم شيئًا جديدًا حول البرمجة. يمكنك الاطلاع على بعض الأفكار التالية التي قد تساعدك في البدء بالتدوين: ماذا تعلّمت اليوم؟ أضف صور توضيحية. أضف روابط إلى مواقع مفيدة. ما هي المشاكل التي واجهتها؟ كيف حللت تلك المشاكل؟ ما العمل الذي يتوجّب عليّ إنجازه في المرّة القادمة؟ بمثل هذه التدوينات السابقة ستتقدّم سريعًا في احتراف البرمجة، وأسباب ذلك: ستكون ملّمًا بما تعلّمته بالتدريج. يمكنك أن تبحث عن المعلومات ضمن وثائقك الشخصيّة. ستتدرّب على HTML وCSS بينما تكتب هذه التدوينات. إذا نشرت موقعك على الانترنت يمكنك أن تجعل تدويناتك متاحة للآخرين. وهذا يساعد على مشاركة المعرفة التي اكتسبتها أو حتى أن تطلب من أحد الأشخاص أن يساعدك على حل مشكلة ما. إذا نشرت ملفّك الشخصي سيكون من الرائع مشاركته مع الآخرين للاطّلاع على إمكانيّاتك وأعمالك. التدوينة الثانية تلميح: أنشئ مجلّدًا فرعيًّا من أجل كل ملف تدوينة جديد. سيسمح لك هذا التنظيم بوضع الصور والملفات الأخرى لكل تدوينة بشكل منفصل عن ملفات التدوينات الأخرى. صفحة المشاريع من المفيد الاحتفاظ بصفحة خاصّة للمشاريع والمهام التي ننجزها. سنحضّر صفحة خاصّة لمثل هذه المشاريع على الرغم من عدم وجود أي محتوى بعد. لنكمل كما فعلنا من أجل صفحة المدوّنة ولننشئ مجلّدً فرعيً اسمه projects ضمن المجلّد الرئيسي portfolio ولننسخ الملف index.html إليه. projects/index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="../main.css"> <title>Projects - Web Portfolio of Marco</title> </head> <body> <h1 class="title">Projects</h1> <p>Here you will soon find my web projects.</p> </body> </html> صفحة التواصل سننشئ الآن الصفحة الأخيرة من الصفحات الرئيسيّة في الموقع وهي صفحة التواصل Contact. أنشئ مجلّدًا اسمه contact ضمن المجلّد الرئيسي portfolio وانسخ الصفحة index.html إليه. ملاحظة مهمّة: كُن حذرًا فيما يتعلّق بالمعلومات التي ترغب بنشرها للعموم. فمثلًا لا تنشر بريدك الإلكتروني الرئيسي، لأنّه من الممكن أن تستقبل بريدًا مزعجًا. contact/index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="../main.css"> <title>Contact - Web Portfolio of Marco</title> </head> <body> <h1 class="title">Contact</h1> <p> You can contact me by email: <a href="mailto:spammails@gmx.ch">spammails@gmx.ch</a> </p> <p> Marco Jakob<br> Switzerland </p> </body> </html> يمكننا أن نلاحظ وجود عنصر HTML جديد بجوار اسم Marco Jakob وهو العنصر <br>. يعمل هذا العنصر على الانتقال إلى سطر جديد ضمن الصفحة. نلاحظ أيضًا الرّابط الخاص mailto الذي يوجد على يسار البريد الإلكتروني (ضمن السمة href). سيعمل هذا الرّابط في حال نقره على فتح برنامج البريد الإلكتروني الافتراضي المثبّت على حاسوبك، مع فتح رسالة جديدة بعنوان البريد الإلكتروني المطلوب. لدينا الآن خمس صفحات HTML: سنزوّد موقعنا في الدرس السادس بوسيلة للتنقّل بين صفحاته. ترجمة -وبتصرّف- للمقال HTML & CSS Tutorial - Part 5: Blog and Other Pages لصاحبه Marco Jakob.
  8. تمتلك معظم المتصفّحات أداة خفيّة تسمح لنا بالنظر خلف كواليس ما يجري في صفحة الويب. يُعتبر هذا أمرًا مفيدًا جدًّا من أجل تفحّص مواقع الويب الخاصّة بنا أو من أجل الاستلهام من مواقع ويب الأخرى. يمتلك متصفّح Chrome حاليًّا أكثر هذه الأدوات فعاليةً والتي تُسمّى أدوات المطوّر Developer Tools أو اختصارًا DevTools. تعلمنا في الدروس السابقة كيفية إنشاء و نشر و تنسيق موقعنا الأول باستخدام CSS. سنقوم في هذا الدرس باستعمال أدوات المطور لتفحص موقعنا والتعديل عليه. فتح أدوات التطوير البرمجية في Chrome يمكن الوصول إلى هذه الأدوات بعدّة أساليب: انقر بز الفأرة الأيمن على أيّ عنصر في صفحة الويب ثم اختر Inspect. استخدم Ctrl+Shift+I من لوحة المفاتيح أو اضغط F12. لنجرّب ذلك على موقعنا الحالي. يجب أن تحصل على شكل شبيه بما يلي: ملاحظة: إذا كنت تستخدم المحرّر Brackets فمن الأفضل أن تلغي تفعيل ميزة Live Preview (التي تحدّثنا عنها في الدرس الأوّل: كيف تصمم أول صفحة ويب لك) ثم أعد تحميل الصفحة ضمن المتصفّح وإلّا فيمكن أن ترى معرّفات id إضافية في الشيفرة يُضيفها المحرّر Brackets تلقائيًّا. تفحص عنصر يمكن باستخدام أدوات التطوير DevTools تفحُّص أي عنصر ضمن صفحة الويب. كمثال على ذلك، لنتفحّص العنصر h2 وذلك بالنقر بزر الفأرة الأيمن على العنوان "Welcome" ثم اختيار Inspect. سيؤدّي ذلك إلى فتح DevTools والانتقال إلى العنصر h2 ضمن الرماز مباشرةً: تظهر هذه الأدوات في القسم الأيمن لنافذة المتصفّح (وقد تظهر في القسم السفلي منها)، ومن هناك يمكننا أن نشاهد التنسيقات المُطبّقة على العنصر h2. يجب أن نرى الألوان التي عرّفناها مسبقًا ضمن الملف main.css. يمكننا أن نرى قسمًا اسمه user agent stylesheet وفيه نجد قواعد التنسيق الافتراضيّة المطبّقة على أيّ عنصر من النوع h2 وذلك من قِبَل المتصفّح. أمّا في الأسفل فيمكننا أن نرى مستطيلًا ملوّنًا. يرينا هذا المستطيل الحجم والمسافات والحدود لعنصر h2 الذي نتفحّصه. فمثلًا نجد أنّ الخاصية padding تحمل القيمة 5 كما عرّفناها مسبقًا ضمن الملف main.css. تغيير التنسيقات ورماز HTML سنتناول الآن الجزء المثير في هذا الدرس. يمكننا تغيير أو إلغاء تفعيل التنسيقات بالإضافة إلى تحرير رماز HTML مباشرةً ضمن المتصفّح. فمثلّا إذا نقرنا على المربّع الملوّن الموجود بجوار background-color يمكننا تغيير لون الخلفيّة للعنصر h2 الذي نتفحّصه حاليًّا، أو حتى يمكننا إدخال قيمة جديدة للخاصيّة padding. يمكن تغيير رماز HTML بالنقر بزر الفأرة الأيمن على رماز العنصر في نافذة DevTools ثم اختيار Edit as Html. يُعتبر هذا الأسلوب فعّالًا للغاية في إجراء التجارب دون التعديل الفعلي ضمن مستند HTML الأصلي، فأيّة تعديلات نجريها ضمن المتصفّح ستكون مؤقّتة وستختفي بمجرّد إعادة تحميل الصفحة ضمنه. الاستلهام من مواقع ويب الأخرى يمكننا تفحّص أي صفحة باستخدام أدوات DevTools وإجراء تغييرات مؤقّتة عليها. حاول أن تصبح عادةً لديك، فمثلًا إذا رأيت لونًا أعجبك بينما تتصفّح صفحات ويب، يمكنك استخدام DevTools للحصول على القيمة الست عشرية له، بحيث تستطيع استخدام هذا اللون ضمن ملفات css الخاصّة بك. من أجل مواقع ويب الأكبر يمكن أن يكون عدد التنسيقات كبيرًا، فيمكن أن توجد عدة قواعد css لنفس العنصر تتجاوز بعضها البعض. يمكن أن نرى مثالًا على ذلك مع عنصر h1. فحجم الخط الذي عرّفناه لهذا العنصر في الدرس (مقدمة إلى تنسيقات CSS) يتجاوز حجم الخط القياسي المعرّف افتراضيًّا ضمن المتصفّح له، وهكذا يتم تجاوز التعريف الأصلي. سننشئ في الدرس الخامس ثلاث صفحات من أجل المدوّنة Blog والمشاريع Projects والتواصل Contact لمشروعنا. ترجمة -وبتصرّف- للمقال HTML & CSS Tutorial - Part 4: Development Tools in the Browser لصاحبه Marco Jakob.
  9. تعلّمنا في الدرسين السابقين كيفية إنشاء ونشر موقعنا الأوّل. في الحقيقة موقعنا حاليًّا بسيط وذو محتوى قليل وليس جذّابًا بعد. سنتعلّم في هذ الدرس كيف نستخدم تنسيقات CSS لتنسيق الصفحة. كما سنتعلّم في درس لاحق كيف نضيف المزيد من التنسيقات إلى موقعنا وذلك بمساعدة إطار عمل اسمه Bootstrap. البنية والتنسيق Structure and Style لنتذكّر معًا: يُعبّر HTML عن بنية صفحة الويب، في حين تُعرّف CSS المظهر العامّ للصفحة. يُعتبر فصل بنية الصفحة عن تنسيقها أمر في غاية الأهميّة وله الكثير من المزايا رغم أنّه ليس إلزاميًّا. لذلك سنعمل دومًا على جعل رُماز HTML وتنسيقات CSS في ملفات منفصلة. الربط مع ملف CSS ملف CSS هو ملف نص عادي له الامتداد (css.) ونربط معه من داخل ملف HTML. أنشئ ملف جديد ضمن المجلّد Portfolio وسمّه main.css. افتح الملف index.html واضف العنصر <link> ضمن العنصر <head>. سنخبر الصفحة index.html عن طريق العنصر <link> أن تُحمّل ملف CSS، أي سننشئ رابط بينهما: <link rel="stylesheet" href="main.css"> أضف العنصر السابق إلى العنصر <head>. ستبدو الشيفرة لديك مُشابهة لما يلي: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="main.css"> <title>Web Portfolio of Marco</title> </head> <body> <h1>Web Portfolio of Marco</h1> <h2>Welcome!</h2> <p>Thanks for stopping by.</p> <p>Please have a look around. In the blog section I document my experiences in programming. You may also look at my web projects. Have fun.</p> <img src="marco.jpg" alt="Picture of me"> <p>Marco :-)</p> </body> </html> ملاحظة مهمّة: لكي يكون من الممكن الوصول لملف CSS، يجب أن تحتوي السمة href على المسار الصحيح للملف. وهذا يعني بدوره أنّه إذا كان ملف CSS في مجلّد فرعي، يحب أن نضم هذا المجلّد الفرعي إلى مسار الملف كما هو واضح. يمكنك مراجعة هذا الموضوع في الدرس الأوّل في فقرة عناوين URL النسبيّة والمطلقة. الألوان إلى الآن ما يزال ملف CSS فارغًا، لنبدأ الآن بكتابة أولى تنسيقات CSS. تحوي CSS ما يُعرف بالقواعد CSS Rules. يمكننا باستخدام قاعدة CSS أن نُخبر المتصفّح كيف يُعالج جزءًا مُحدّدًا من مستند HTML. كمثال على ذلك، سنغيّر لون الخلفيّة ولون النص للعنوان من المستوى الثاني h2 ضمن الملف index.html الخاص بنا. أضف ما يلي إلى ملف CSS: الملف main.css h2 { background-color: #607d8b; color: #ffffff; } يجب أن تحصل على شكل شبيه بما يلي: أكواد الألوان Color Codes تظهر الألوان على الشاشة كمزيج من نسب متفاوتة من الأحمر والأخضر والأزرق (RGB). يمكن التعبير عن المزج بين هذه الألوان الثلاثة في CSS بطريقتين: كقيم RGB عشرية (محصورة بين 0 إلى 255 لكل لون) أو كقيم RGB ستة عشرية hex values. وفي الواقع تُستَخدم القيم الستة عشرية في الغالب. إذا نظرنا إلى مثالنا الأخير، فنجد أنّنا قد عيّنا لونًا أزرقًا مائلًا للرمادي كلون خلفية باستخدام كود اللون 607d8b# بالترميز الستة عشري. أمّا لو أردنا استخدام الترميز العشري المُكافئ له فسنكتب (rgb(96, 125, 139. في التمثيل الستة عشري، يُعبّر أوّل رمزين من اليسار عن اللون الأحمر، والرمزين في الوسط عن اللون الأخضر، ويُعبّر الرمزان الأخيران عن اللون الأزرق. العمل مع أكواد الألوان يُعتبر التعامل مع الألوان كأكواد، شائع جدًا لكنه صعب في الحقيقة. لأنّك تتعامل مع قيم ورموز وليس مع ألوان، يُنصح دوماً استخدام أداة لانتقاء الألوان color picker. إذا كنت تستخدم المحرّر Brackets عندها يمكن أن تفتح أداة انتقاء اللون الموجودة ضمن ملف CSS الذي تعمل ضمنه. فقط تحتاج لأن تنقر بزر الفأرة الأيمن على كود اللون وتختار تحرير سريع Quick Edit أو أن تضغط Ctrl+E من لوحة المفاتيح. يؤدي ذلك إلى ظهور أداة اختيار الألوان حيث يمكنك اختيار اللون الذي يناسبك بسهولة. كما يمكنك اختيار ترميز اللون بالصيغة التي ترغبها من خلال ثلاثة أزرار موجودة في الأسفل. أدوات اختيار الألوان من الانترنت إذا لم تتوفّر أداة لاختيار الألوان ضمن المحرّر لديك، فيمكنك استخدام عدد كبير جدًّا من هذه الأدوات ولكن على الانترنت، فعلى سبيل المثال لا الحصر: HTML Color Codes ColorPicker ألواح الألوان من الانترنت نحتاج في كثير من الأحيان إلى أكثر من لون واحد لاستخدامه في موقعنا. لذلك نحتاج إلى أداة تزوّدنا بمجموعة من الألوان المنسجمة، والتي تتناغم مع بعضها لإضفاء تأثير جميل على الموقع. وهذا ما تفعله ألواح الألوان color palettes. هناك بعض المواقع على الانترنت التي توفّر مثل هذه الميزة. أمثلة على مواقع بمجموعات ألوان معرّفة مسبقًا: Colour Lovers Design Seeds Google Color Palette أمثلة على مواقع تولّد مجموعات ألوان حسب رغبة المستخدم: Kuler: يُعرّف قاعدة لون (سنتكلّم عن القواعد بعد قليل)، ويسمح لنا بالحصول على خمسة ألوان منسجمة معًا. Paletton: أداة متقدّمة للحصول على مجموعات ألوان منسجمة. Colourco.de: مولّد ألواح ألوان عملي أيضًا. قواعد CSS رأينا كيف تُغيّر CSS من هيئة عناصر HTML من خلال تأثيرها على الألوان. لنلقي نظرة عن كثب حول CSS وطريقة عملها. تُعتبر القاعدة rule البنية الأساسية لـ CSS وهي تتكوّن من ثلاثة عناصر: المحدِّد Selector والخاصية Property والقيمة Value. تُشير القاعدة السابقة إلى أنّ جميع عناصر <h2> يجب أن يكون لها لون خلفية له الكود 607d8b#. محددات CSS تُقرّر المحدّدات أيّ عناصر HTML ستُطبّق عليها قاعدة CSS. ملاحظة: سنتعلّم هنا المحدّدات الأكثر أهمية. من أجل الاطلاع على أنواع المُحدّدات الأخرى ابحث في Google عن CSS Selectors. محددات النوع Type Selectors تستهدف محدّدات النوع جميع العناصر التي يكون لها وسم HTML مُحدّد. فلو أردنا مثلًا استهداف جميع عناصر الفقرة p ضمن المستند بتنسيقات معيّنة، فسنكتب شبيه بما يلي: CSS p { ... } HTML <p>...</p> <p>...</p> محددات الصنف Class Selectors تُستخدم هذه المحدّدات بشكل متكرّر، وتُعتبر أنّها مُخصّصة أكثر قليلًا من مُحدّدات النوع، كما أنّه بإمكانها استهداف مجموعة مخصّصة من العناصر بدلًا من عناصر النوع الواحد فقط. لاستخدام محدّدات الصنف نضيف السمة class إلى العنصر المراد استهدافه، ونسند إليها قيمة مُعبّرة من اختيارنا. عند استخدام محدّد الصنف فإنّنا نستخدم نقطة عادية يليها قيمة السمة class التي أضفناها إلى العنصر. سيستهدف محدّد الصنف في المثال التالي، جميع العناصر التي لها سمة class تحمل القيمة highlight: CSS .highlight { ... } HTML <p class="highlight">...</p> <p>...</p> <p class="highlight new">...</p> لاحظ من شيفرة HTML في الأعلى، أنّ التنسيق سيُطبّق على عنصر p الأوّل والثالث فحسب، لأنّ عنصر p الثاني لا يمتلك سمة class لها القيمة highlight. كما نلاحظ أنّ عنصر p الثالث له أكثر من قيمة ضمن سمة class الخاصة به (highlight وnew). في الحقيقة يمكن استخدام عدة قيم لعنصر واحد بشرط أن نفصل بينها بفراغات. محددات معرف العنصر ID Selectors تشبه هذه المحدّدات محدّدات الصنف. فهي تستهدف جميع عناصر HTML التي تملك السمة id بقيمة مُعيّنة. من المهم أن نوضّح أنّ السمة id عبارة عن مُعرّف العنصر ضمن شيفرة HTML ورغم أنّه ليس من الملزم وضعها مع كل عنصر، إلّا أنّه في حال وجودها يجب أن تكون القيمة التي تحملها فريدةً ضمن كامل مستند HTML. نستنتج إذًا أنّ أي محدّد معرّف عنصر سيستهدف في الواقع عنصر واحد فقط ضمن مستند HTML. عند استخدام محدّد معرّف العنصر فإننا نكتب الرمز # يليه معرّف العنصر (قيمة السمة id). سيستهدف محدّد معرّف العنصر في المثال التالي عنصر واحد فقط ضمن مستند HTML بحيث تكون قيمة السمة id له هي navigation: CSS #navigation { ... } HTML <p id="navigation">...</p> <p>...</p> محددات الفروع Descendant Selectors يمكنك باستخدام هذا النوع من المحدّدات استهداف العناصر الأبناء لعنصر مُعيّن. ونقصد بالعناصر الأبناء لعنصر معيّن، تلك العناصر التي تقع ضمن هذا العنصر بصرف النظر عن المستوى الذي تقع فيه. انظر المثال التالي: <p id="level1"> <p id="level2"> <a href="myfile.html">My File</a> </p> </p> نلاحظ بأنّ كلًّا من العنصر <p> (ذو المعرّف level2) والعنصر <a> هما ابنان للعنصر <p> (ذو المعرّف level1). لأنّهما يقعان ضمنه بصرف النظر عن المستوى. في حين يُعتبر العنصر (ذو المعرّف level2) ابنًا مباشرًا للعنصر <p> (ذو المعرّف level1). أمّا بالنسبة لمحدّدات الفروع فنلق نظرة خاطفة على هذ المثال البسيط قبل أن نبدأ بالشرح: CSS p a { ... } HTML <p> <a href="http://code.makery.ch">My Website</a> </p> <a href="http://www.example.com">Example Website</a> نلاحظ بأنّ محدّد الفروع p a يستهدف جميع عناصر <a> أينما وُجدَت داخل عنصر <p>. وبناءً عليه نجد أنّ التنسيق سيُطبّق على My Website وليس على Example Website لأنّ الأخيرة موجودة ضمن عنصر <a> لا يقع ضمن أي عنصر <p> كما هو واضح. ملاحظة: ليس من الضروري أن يكون العنصر <a> في المثال في الأعلى ابنًا مباشرًا للعنصر<p>. فمحدّد الفروع السابق يستهدف أي عنصر <a> موجود ضمن أي مستوى ضمن العنصر <p>. إذا أردنا استهداف الابن المباشر فحسب، فيمكننا استخدام مُحدّد الابن ( > ). خصائص CSS تُقرّر قواعد CSS كيف يجب أن تظهر عناصر HTML. هناك العديد من الخصائص التي يمكن تعريفها في CSS. في الواقع لقد صادفنا اثنتان منهم: background-color وcolor. لن نتوسّع في الحديث عن خصائص CSS المختلفة، لأنّ هذا الدرس ليس مرجعًا لهذه الخصائص، لكن سنتعلّم كيف نجد المزيد من المعلومات عنها بأنفسنا. سنستفيد بشكل أكبر عندما نتعلّم هذه الخصائص عندما نحتاج إليهم فعليّا. توجد حالتان مختلفتان يمكن أن نصادفهما لنتعلُّم المزيد عن CSS. الحالة الأولى: عندما نصادف خاصية CSS لا نعرفها في هذه الحالة نبحث عن معلومات عنها في الانترنت، اكتب اسم الخاصية متبوعًا بكلمة css ضمن محرّك البحث. يمكنك أن تجرّب هذه الطريقة الآن لتحصل على معلومات حول خاصية CSS جديدة وهي: padding: 5px; استخدم css padding كعبارة بحث. لا تكتفي بالاطلاع على نتيجة البحث الأولى، بل اطّلع على النتائج الخمس الأولى أو أكثر إن أحببت. بعد ذلك قرّر أيُّ المواقع ستوفّر المعلومات المناسبة لك. جرّب تطبيق قاعدة CSS السابقة (أي القاعدة padding: 5px) على عنصر h2 في مشروعنا. الحالة الثانية: نريد تغيير أسلوب عرض أحد العناصر ولكن لا نعرف خاصية CSS المناسبة ابحث في الانترنت عن الشيء الذي ترغب أن تقوم به، متبوعًا بكلمة css. ربما تحتاج إلى إجراء عدة عمليات بحث قبل أن تجد ضالّتك. فإذا أردنا مثلًا تغيير حجم النص. في هذه الحالة استخدم الكلمات التالية text size css في محرّك البحث. ومرّة أخرى لا تكتفي بالنتيجة الأولى فقط من نتائج البحث. قيم CSS لقد صادفنا قبل قليل بعضًا من قيم CSS، فمثلًا القيم الست عشرية مثل ffffff# أو تلك القيم المتعلّقة بتعيين قياسات الأحجام مثل 5px. يتوجّب علينا أحيانًا وبحسب خاصية CSS المستخدمة استخدام كلمات مُعيّنة مثل left أو right لمحاذاة النصوص على سبيل المثال. أكثر قيم CSS المستخدمة هي القيم المتعلّقة بتعيين قياسات الأحجام. لذلك سنتناولها بشيء من التفصيل. غالبًا ما يُعرّف الحجم باستخدام البيكسل Pixel، ونرمز له اختصارًا بالرمز px. p { font-size: 16px; } توجد إمكانية أخرى وهي تعيين الأحجام باستخدام النسبة المئوية Percentage. دائمًا ما تكون النسب المئوية نسبيّةً بالنسبة للعنصر الأب. في المثال التالي سيشغل العنصر p ما مقداره 60% من عرض width العنصر الأب الذي يقع ضمنه، في حين سيشغل العنصر الأب عرض النافذة كاملًا. p { width: 60%; } توجد وحدة قياس مشهورة أخرى للأحجام وهي em. والـ em ترتبط دومًا بحجم الخط. ويعني ذلك أنّنا إذا غيّرنا حجم الخط فإنّ حجم العنصر المُقاس بالوحدة em سيتغيّر أيضًا. كمثال على ذلك إذا كان لعنصر ما حجم خط مقداره 20px وعرض 5em، فسيكون عرض العنصر الفعلي في هذه الحالة 100px (أي 20 مضروبة بـ 5). انظر إلى الشيفرة التالية: p { font-size: 20px; width: 5em; } محددات الصنف في مشروعنا إذا أردنا تكبير العنوان الرئيسي في موقعنا: "Web Portfolio of Marco". فسيكون ذلك ممكنًا بتعريف قاعدة CSS للعنصر h1 كما يلي: h1 { font-size: 65px; } المشكلة التي ستصادفنا هنا أنّ جميع عناصر h1 الموجودة في المستند ستكبُر بتأثير هذه القاعدة. لذلك فإذا أردنا أن نُكبّر عنوان h1 الأوّل الموجود في المستند فسنستخدم لهذا الغرض مُحدّد صنف class selector. سنضيف السمة class إلى عنصر h1 المراد استهدافه، ويمكننا بالطبع إسناد أي قيمة لهذه السمة، سنختار القيمة title: <h1 class="title">Web Portfolio of Marco</h1> يمكننا الآن استهداف عنصر h1 هذا بكتابة قاعدة CSS بالشكل التالي: .title { font-size: 65px; } إذا جرت الأمور على ما يرام فستحصل على شكل شبيه بما يلي: سننتقل الآن إلى الدرس الرابع، والذي يتحدّث عن أدوات التطوير البرمجية المتاحة ضمن متصفّح الانترنت. ترجمة -وبتصرّف- للمقال HTML & CSS Tutorial - Part 3: Introduction to CSS لصاحبه Marco Jakob.
  10. أنشأنا في الدرس السابق موقع الويب الأوّل لنا، سنتعلّم الآن كيف سننشر موقع الويب هذا بشكل فعليّ على الانترنت. ملاحظة: لن يكون هناك الكثير من الزوار لموقعك في البداية، مالم تعط الناس عنوان الموقع على الانترنت. الاستضافة لكي يستطيع الجميع الوصول إلى موقعنا على الانترنت، نحتاج إلى مُخدّم Server يُخزّن موقعنا عليه، بالإضافة إلى عنوان URL يُشير إلى الموقع. هناك عدد هائل من الشركات التي يمكن أن تقدّم لك خدمة تأجير مساحة على المُخدّم لهذا الغرض. تُسمّى هذه الخدمة عادةً باستضافة ويب Webhosting. نستعرض بعض الاستضافات المجّانية المُتاحة. أنصح أن تبدأ بخدمة BitBalloon إذا كانت هذه هي التجربة الأولى لك. 1- الاستضافة على BitBallon خدمة BitBallon بسيطة ورائعة وأنصح بها. إليك الخطوات اللازمة للتسجيل: 1. اشترك ضمن موقع BitBalloon. وذلك بالنقر على زر التسجيل Sign Up ثم اختر Sign in Using Persona. بعد ذلك أدخل بريدك الإلكتروني وكلمة المرور. 2. عندما تسجّل الدخول، يمكنك ببساطة سحب كامل مجلّد موقع الويب (المجلّد Portfolio) إلى المكان المخصّص في صفحة الخدمة. 3. ربما تستغرب هذه البساطة، ولكن بمجرّد تحميل الموقع سيُولّد عنوان URL يُشير إلى موقعك الذي حمّلته قبل قليل. انقر هذا العنوان واختبر ظهور الموقع بشكل صحيح. 4. لتبسيط عنوان URL المولّد بشكل آلي، يمكننا النقر على Edit name وإدخال اسم مناسب. 5. من أجل التحديثات التي من الممكن أن تجريها على الموقع، اسحب مجلّد الموقع من جديد إلى الصندوق المسمّى Drag & Drop to Update your Site. 2- الاستضافة على Google Drive يمكن استخدام خدمة Google Drive كخدمة استضافة. الأمر السلبي الوحيد هنا، هو أنّك ستحصل على عنوان URL طويل جدًّا. لنجري الخطوات التالية للاستضافة: حمّل مجلّد الموقع إلى Google Drive. حدّد المجلّد المُحمّل ثم اختر مشاركة Share. انقر فوق خيارات متقدّمة Advanced وغيّر مستوى الوصول إلى Public on the web أي متاح للعموم على الانترنت. افتح المجلّد في Google Drive وتأكّد من أنّ جميع ملفّات الموقع قد حمّلت (index.html والصور …الخ). انسخ الرموز التي تأتي بعد الكلمة ( /folders#) ضمن شريط العنوان للمتصفّح. ستكون هذه الرموز هي المُعرّف الخاص بالمجلّد المُحمّل. أدخل في شريط العنوان للمتصفّح العنوان التالي http://googledrive.com/host متبوعًا بالرموز التي نسختها من الخطوة السابقة. يمكن الآن لأي شخص لديه هذا العنوان الوصول إلى موقعنا. 3- الاستضافة على Dropbox يمكن استخدام Dropbox كخدمة استضافة. ولكي نتمكّن من ذلك نحتاج إلى خدمة إضافية لتوجيه الطلبات إلى الموقع المُستضاف. توجد خدمتان يمكن استخدامهما وهما Pancake و DropPages. 4- الاستضافة على GitHub إذا كان لديك بعض الخبرة البرمجية فعندها يُعتبر GitHub طريقةً رائعة لاستضافة مواقع الويب. تُعتبر GitHub منصّة لتسهيل التشاركية بين المبرمجين، كما تُتيح هذه المنصة استضافة مجّانيّة لصفحات الويب وذلك على صفحات GitHub. تؤمّن صفحات GitHub المزيد من الخيارات (فمثلاً تستطيع استخدام النطاق domain الخاص بك)، لكنها تتطلّب بعض المهارات في التعامل مع نظام التحكم بالإصدارات البرمجية Git. دورة تطوير واجهات المستخدم ابدأ عملك الحر بتطوير واجهات المواقع والمتاجر الإلكترونية فور انتهائك من الدورة اشترك الآن تصغير عناوين URL يمكن أن يكون عنوان موقعك طويلًا جدًّا وذلك بحسب الاستضافة التي اخترتها. توجد بعض الخدمات البسيطة لتصغير عنوان URL الخاص بموقعك. لتصغير العناوين فائدة كبيرة، حيث يمكن إدخالها يدويًا بسهولة ضمن متصفح الويب في هاتفك الذكي مثلًا، كما توجد بعض الخدمات التي تزوّدك بكود QR للوصول السريع من هاتفك الذكي إلى الموقع مباشرة باستخدام كاميرا الهاتف فحسب. إليك قائمة من بعض خدمات تصغير العناوين: خدمة Goo.gl (تتضمن توليد كود QR). خدمة bit.ly. خدمة Tiny.cc. النطاق الخاص بنا ربما يأتي يوم نرغب فيه بأن نحصل على اسم نطاق خاص بنا مثل http://www.my-super-website.com. يمكنك في بعض الحالات تسجيل اسم نطاق ضمن مزوّد خدمة الاستضافة نفسه (كما هو الحال مع خدمة الاستضافة BitBallon). أو يمكنك الوصول إلى عدد كبير جدًّا من خدمات تسجيل النطاقات الخاصة، تقدّم بعضها عروضًا مختلفةً عن بعضها الآخر، يمكنك البحث في Google لتصل إلى عدد كبير منها. سنُضفي على الموقع في الدرس الثالث بعض تأثيرات التنسيق المختلفة عن طريق CSS. ترجمة -وبتصرف- للمقال HTML & CSS Tutorial - Part 2: Publishing Your Website لصاحبه Marco Jakob.
  11. رغم أنّ تحويلات CSS3 ثلاثية الأبعاد صار لها فترةً لا بأس بها من الزمن، إلّا أنّني اكتشفت عدم امتلاك الخبرة الكافية للعمل معها بعد. أستخدم Windows 8 منذ فترة من الوقت، ومن أوّل الأمور التي لفتت نظري كانت الانتقالات transitions والتحريكات animations المبنية ضمن لوح البداية Start Dashboard، لذلك خطرت ببالي فكرة رائعة، وهي لماذا لا تكون خبرتي الأولى مع تحويلات CSS3 ثلاثية البعد ببناء تطبيق يماثل في سلوكه تلك التحريكات والتأثيرات في Windows 8؟ وهذا ما حدث في هذا الدرس. سأستخدم خصائص CSS بدون أي بادئة prefix وذلك بغرض الاختصار، لكنك ستجد الخصائص كاملة ضمن النص المصدري للمشروع على Github. ستعمل مقاطع الشيفرة التي ستجدها هنا على متصفحات تدعم خصائص CSS المستخدمة. الرماز The Markupبنية هذا التطبيق بسيطة: يتكون لوح البداية من قائمة من القطع tiles بثلاثة قياسات وهي الصغير، الكبير، والكبير جدًا. لكل قطعة من هذه القطع صفحة page مرتبطة معها. والصفحة عبارة عن تغطية overlay تظهر عند النقر على إحدى القطع في لوح البداية. سنعتبر الصفحة أنّها تُحاكي تطبيق سطح مكتب في Windows 8، فتكون القطعة كما هو واضح اختصارًا له (للصفحة). عند النقر على قطعة ستُفتح الصفحة الموافقة لها. يوجد نوعان من الانتقالات للصفحة بعد فتحها يدعمهما اللوح في Windows 8. يفتح أحدهما الصفحة بتأثير دوران ثلاثي الأبعاد اعتبارًًا من يمين الشاشة، أمّا الآخر فتنزلق فيه الصفحة من وإلى اليسار. سنعرّف صنف CSS لكل نوع من نوعيّ الصفحة، حيث سيكون الصنف s-page للصفحات التي تنزلق من وإلى اليسار، أمّا الصنف r-page فسيكون للصفحات التي تدور من اليمين. ينبغي علينا من أجل كل قطعة تعيين نوع الصفحة التي ستفتحها القطعة (بالاعتماد على التأثير الذي نريده من أجل هذه الصفحة). سنعرّف نوع الصفحة لكلّ قطعة باستخدام سمة attribute مخصّصة سنسميها data-type-page، ستهتم هذه الـسمة بتطبيق أسماء أصناف CSS الصحيحة التي ستفعّل التحريكات المناسبة فيما بعد. يجب أن يكون لكل صفحة اسم. سيختلف اسم الصفحة لتطبيق معيّن عن اسم الصفحة لتطبيق آخر، فمثلًا الـقطعة المسمّاة Skype ستفتح صفحة اسمها skype-app وهكذا دواليك. لقد استخدمت اسميّ صفحة فقط في هذا المثال، وقد كرّرتهما من أجل جميع الـقطع الباقية بغرض التبسيط، كما استخدمت الاسم custom-page لآخر قطعة وذلك على سبيل المثال. ربما تحتاج أن تضيف صفحة مختلفة لكل قطعة، وهذا يعني اسم صفحة مختلف لكلٍّ منها. إليك الرماز الخاص بكامل اللوح (الـقطع والصفحات): <div class="demo-wrapper"> <div class="s-page random-restored-page"> <div class="page-content"> <h2 class="page-title">Some minimized App</h2> <div class="close-button s-close-button">x</div> </div> </div> <div class="s-page custom-page"> <div class="page-content"> <h2 class="page-title">Thank You!</h2> <div class="close-button s-close-button">x</div> </div> </div> <div class="r-page random-r-page"> <div class="page-content"> <h2 class="page-title">App Screen</h2> <p>Chew iPad power cord chew iPad power cord attack feet chase mice leave dead animals as gifts and stick butt in face chew iPad power cord. Chase mice. Run in circles use lap as chair why must they do that. Intrigued by the shower destroy couch leave hair everywhere sleep on keyboard chew iPad power cord. Use lap as chair. Missing until dinner time stand in front of the computer screen, intently sniff hand. Find something else more interesting. Destroy couch play time so inspect anything brought into the house hate dog burrow under covers. Sleep on keyboard destroy couch so hate dog so hide when guests come over. Chase mice destroy couch lick butt throwup on your pillow use lap as chair yet intrigued by the shower but climb leg. Stare at ceiling make muffins or hunt anything that moves claw drapes. Intently sniff hand intrigued by the shower. Why must they do that. Cat snacks leave dead animals as gifts or inspect anything brought into the house sweet beast so stare at ceiling give attitude. Flop over claw drapes but sun bathe lick butt, and chase mice. Rub face on everything lick butt leave hair everywhere lick butt, missing until dinner time for use lap as chair lick butt. Make muffins leave dead animals as gifts play time. Chew foot intrigued by the shower stare at ceiling inspect anything brought into the house yet hopped up on goofballs. Hunt anything that moves intently sniff hand for hunt anything that moves play time. Chew foot climb leg throwup on your pillow so lick butt yet make muffins hate dog. Intrigued by the shower. Intently sniff hand shake treat bag. Cat snacks burrow under covers make muffins but all of a sudden go crazy find something else more interesting. Flop over chase mice. Give attitude. Inspect anything brought into the house. Stick butt in face sun bathe so find something else more interesting and intrigued by the shower. Rub face on everything use lap as chair. Under the bed claw drapes chase mice but leave hair everywhere yet make muffins yet claw drapes. Use lap as chair. Find something else more interesting stretch for under the bed. Nap all day intrigued by the shower, hate dog sweet beast intently sniff hand so hate dog nap all day. Swat at dog hide when guests come over and mark territory chase mice for cat snacks. Use lap as chair. Lick butt throwup on your pillow need to chase tail. Mark territory. Stick butt in face shake treat bag yet hunt anything that moves, yet hopped up on goofballs yet stare at ceiling under the bed. Give attitude chase imaginary bugs stretch so hunt anything that moves so hide when guests come over but intrigued by the shower find something else more interesting. Make muffins behind the couch for chew foot. Sweet beast flop over but throwup on your pillow. Intently sniff hand use lap as chair and missing until dinner time and chase imaginary bugs. </p> </div> <div class="close-button r-close-button">x</div> </div> <div class="dashboard clearfix"> <ul class="tiles"> <div class="col1 clearfix"> <li class="tile tile-big tile-1 slideTextUp" data-page-type="r-page" data-page-name="random-r-page"> <div><p>This tile's content slides up</p></div> <div><p>View all tasks</p></div> </li> <li class="tile tile-small tile tile-2 slideTextRight" data-page-type="s-page" data-page-name ="random-restored-page"> <div><p class="icon-arrow-right"></p></div> <div><p>Tile's content slides right. Page opens from left</p></div> </li> <li class="tile tile-small last tile-3" data-page-type="r-page" data-page-name="random-r-page"> <p class="icon-calendar-alt-fill"></p> </li> <li class="tile tile-big tile-4" data-page-type="r-page" data-page-name="random-r-page"> <figure> <img src="images/blue.jpg" /> <figcaption class="tile-caption caption-left">Slide-out Caption from left</figcaption> </figure> </li> </div> <div class="col2 clearfix"> <li class="tile tile-big tile-5" data-page-type="r-page" data-page-name="random-r-page"> <div><p><span class="icon-cloudy"></span>Weather</p></div> </li> <li class="tile tile-big tile-6 slideTextLeft" data-page-type="r-page" data-page-name="random-r-page"> <div><p><span class="icon-skype"></span>Skype</p></div> <div><p>Make a Call</p></div> </li> <li class="tile tile-small tile-7 rotate3d rotate3dX" data-page-type="r-page" data-page-name="random-r-page"> <div class="faces"> <div class="front"><span class="icon-picassa"></span></div> <div class="back"><p>Launch Picassa</p></div> </div> </li> <li class="tile tile-small last tile-8 rotate3d rotate3dY" data-page-type="r-page" data-page-name="random-r-page"> <div class="faces"> <div class="front"><span class="icon-instagram"></span></div> <div class="back"><p>Launch Instagram</p></div> </div> </li> </div> <div class="col3 clearfix"> <li class="tile tile-2xbig tile-9" data-page-type="custom-page" data-page-name="random-r-page"> <figure> <img src="images/summer.jpg" /> <figcaption class="tile-caption caption-bottom">Fixed Caption: Some Subtitle or Tile Description Goes Here with some kinda link or anything </figure> </li> <li class="tile tile-big tile-10" data-page-type="s-page" data-page-name="custom-page"> <div><p>Windows-8-like Animations with CSS3 & jQuery © Sara Soueidan. Licensed under MIT.</p></div> </li> </div> </ul> </div> </div>حصلت على خط الأيقونة الذي استخدمته من Icomoon. الذي سيحدث الآن: ستحصل JavaScript على اسم ونوع الصفحة المراد فتحها عند نقر القطعة، وبعد ذلك، ووفقًا لنوع الصفحة ستعمل JavaScript على تطبيق أسماء أصناف CSS المناسبة على الصفحة (والتي سنحصل على اسمها أيضًا من السمة data-page-name) لفتحها بنمط تحريك معيّن لكل صنف CSS يتم تطبيقه. تنسيقات CSSأرجو ملاحظة أنّني أستخدم أنماط تنسيق تراعي الأجهزة المحمولة أولًا mobile-first، والتي سنجعلها لاحقًا ذات استجابية responsive عالية ضمن قسم استعلامات الوسائط media queries في CSS. سنتناول في البداية التنسيقات الخاصة بالحاوية (عنصر div) والتي ستحوي كامل المثال التوضيحي. سنعرّف تنسيقات عامّة ونتأكّد من ضبط الخاصية perspective بحيث يؤدي ذلك إلى تفعيل الفضاء ثلاثي البعد 3D، وإلّا سيبدو كامل المثال بشكل منبسط أي ثنائي البعد 2D. .demo-wrapper { padding: 2em .5em; width: 100%; height:100%; perspective: 3300px; position: relative; }لنبدأ الآن بتنسيقات وتحريكات لوح البداية. ستُنفَّذ أوّل تحريكة سنطبّقها على لوح البداية عند تحميل الصفحة ضمن متصفّح الويب. سيكون لوح البداية مخفيًّا في يمين الشاشة بادئ الأمر، ثمّ يظهر تدريجيًّا مع الانتقال إلى موقعه الأساسي عند تحميل الصفحة. .dashboard { margin: 0 auto; width: 100%; padding: 1em; transform: translateX(200px); opacity:0; animation: start 1s ease-out forwards; } @keyframes start{ 0%{ transform: translateX(200px); opacity:0; } 50%{ opacity:1; } 100%{ transform: translateX(0); opacity:1; } }يتضاءل لوح البداية ويختفي عند نقر قطعة منه. حيث ينتقل اللوح على طول محور z، ويتضاءل حجمه، كما تنخفض قيمة الخاصية opacity له تدريجيًا حتى تصبح في النهاية تساوي الصفر مما يعطي شعورًا بأنّ اللوح يختفي بالتدريج. أمّا عندما يُغلق المستخدم الصفحة فإنّ لوح البداية يعود للظهور مرّة أخرى. بالنسبة للأعمدة الثلاثة في لوح البداية فإنّها تظهر تدريجيًّا واحدًا تلو الآخر مع تأخير زمني طفيف بينها. عندما تُغلق الصفحة، سيُضاف اسم صنف CSS لكل عمود (بواسطة JavaScript) وكل من هذه الأصناف ستُفعّل تحريكة بتأخير زمني مُحدّد. فيما يلي أصناف CSS والتحريكات المطبّقة على لوح البداية عند نقر القطع tiles وإغلاق الصفحات. .fadeOutback{ animation: fadeOutBack 0.3s ease-out 1 normal forwards; } .fadeInForward-1, .fadeInForward-2, .fadeInForward-3 { opacity:0; transform: translateZ(-5em) scale(0.75); animation: fadeInForward .5s cubic-bezier(.03,.93,.43,.77) .4s normal forwards; } .fadeInForward-2{ animation-delay: .55s; } .fadeInForward-3{ animation-delay: .7s; } @keyframes fadeOutBack{ 0% {transform: translateX(-2em) scale(1); opacity:1;} 70% {transform: translateZ(-5em) scale(0.6); opacity:0.5;} 95% {transform: translateZ(-5em) scale(0.6); opacity:0.5;} 100% {transform: translateZ(-5em) scale(0); opacity:0;} } @keyframes fadeInForward{ 0% {transform: translateZ(-5em) scale(0); opacity:0;} 100% {transform: translateZ(0) scale(1); opacity:1;} }وبالنسبة لتنسيقات الصفحات: .r-page { width: 100%; height: 100%; text-align: center; font-size: 2em; font-weight: 300; position: absolute; right: 0; top: 0; left:0; bottom:0; opacity: 0; color: white; z-index: 10; padding:10px; transform-origin: 100% 0%; transform: rotateY(-90deg) translateZ(5em) } .s-page { color: white; z-index: 10; text-align: center; font-size: 2em; font-weight: 300; } .page-content{ overflow-y:auto; max-height:100%; font-size:.6em; padding:.6em; text-align:left; } .s-page, .r-page{ background-color: white; color:black; } .page-title { margin: .25em 0; font-weight: 100; font-size: 3em; text-align:center; } .close-button { font-size: 1.5em; width: 1em; height: 1em; position: absolute; top: .75em; right: .75em; cursor: pointer; line-height: .8em; text-align: center }لقد ضبطت الموقع الأصلي لكل صفحة من النوع r-page في الفضاء ثلاثي البعد بتدويرها حول محور التراتيب (محور y) بعد ذلك نقل الصفحة بمقدار 5em إلى يسار الشاشة باستخدام الخاصية translateZ (النقل على محور z). ينبغي ألّا ننسى أنّه عند تحويل (نقل – تدوير) عنصر في الفضاء ثلاثي البعد فمن الضروري تحويل نظام الإحداثيات الخاص به بنفس الصورة. الذي نريده الآن هو نقل الصفحة بمقدار 5em إلى يسار الشاشة، ولكن لاحظ أنّنا بدلًا من استخدام translateX استخدمنا translateZ، ويعود سبب ذلك إلى أنّه بعد التحويل الأوّل (الدوران حول محور y) يدور نظام الإحداثيات أيضًا، وهكذا يُشير محور z في هذه الحالة إلى اليسار وليس إلى الأعلى، أمّا محور الفواصل (محور x) فسيشير باتجاه المستخدم. يكون لجميع الصفحات باستثناء النوع s-page نفس موقع البداية في الفضاء ثلاثي البعد. بالنسبة للصفحات من النوع s-page فإنّها تكون بموقع يبعد بما يُعادل -150% يسار الشاشة (واضح أنّها لن تكون مرئية بهذه الحالة)، بحيث أنّها تنزلق لتعود إلى الشاشة عند تفعيل التحريكة الخاصة بها. عند نقر قطعة مرتبطة بصفحة ما، فسيُضاف صنف CSS الموافق بواسطة JavaScript إلى الصفحة، بالنتيجة ستحصل الصفحة على اسم صنف CSS يُعرّف التأثير ثلاثي البعد الواجب تطبيقه عليها. فيما يلي أسماء أصناف CSS التي تُفعّل عملية فتح وإغلاق الصفحات، بالإضافة إلى التحريكات المعرّفة من أجل كل صنف. .openpage{ animation: rotatePageInFromRight 1s cubic-bezier(.66,.04,.36,1.03) 1 normal forwards; } .slidePageLeft{ transform: rotateY(0) translateZ(0); opacity: 1; animation:slidePageLeft .8s ease-out 1 normal forwards; } .slidePageInFromLeft{ animation: slidePageInFromLeft .8s cubic-bezier(.01,1,.22,.99) 1 0.25s normal forwards; } .slidePageBackLeft{ opacity: 1; left: 0; animation: slidePageBackLeft .8s ease-out 1 normal forwards; }لاحظ أنّني أستخدم الخاصية animation بالشكل المختصر. تعود القيمة الأخيرة forward ضمن الخاصية animation إلى الخاصيّة الفرعية animation-fill-mode، وهذه القيمة ضرورية لها، وإلّا ستعود الصفحة إلى حالتها الابتدائية (المغلقة) فور انتهاء التحريكة التي ستُظهر الصفحة. إذًا لكي نُبقي الصفحة مفتوحة، ولكي نكون قادرين على إنشاء تحريكات متلاحقة، يجب على العنصر أن يبقى مُحتفظًا بحالته النهائية المعرّفة ضمن تحركية ما، ومن هذه "الحالة النهائية" يبدأ عمل التحريكة التالية، وهكذا. فيما يلي التحريكات لأصناف CSS المطبّقة على الصفحات. @keyframes rotatePageInFromRight{ 0% {transform:rotateY(-90deg) translateZ(5em);opacity:0} 30% {opacity:1} 100% {transform: rotateY(0deg) translateZ(0) ; opacity:1} } @keyframes slidePageLeft{ 0% {left:0; transform: rotateY(0deg) translateZ(0) ; opacity:1} 70% {opacity:1;} 100% {opacity:0; left:-150%; transform: rotateY(0deg)} } @keyframes slidePageInFromLeft{ 0% {opacity:0; } 30% {opacity:1} 100% {opacity:1; left:0;} } @keyframes slidePageBackLeft{ 0% {opacity:1; left:0; transform: scale(0.95);} 10% {transform: scale(0.9);} 70% {opacity:1;} 100% {opacity:0; left:-150%;} }أخيرًا وليس آخرًا، سنُنسّق قطع لوح البداية ونُعرّف الانتقالات والتحريكات المطبّقة عليها عند تحريك مؤشّر الفأرة فوقها. لاحظ أنّ التنسيقات العامّة تُعرّف حجم القطع. .tile{ float: left; margin: 0 auto 1%; color: white; font-size: 1.3em; text-align: center; height: 8em; font-weight: 300; overflow: hidden; cursor: pointer; background-color: #fff; color: #333; position:relative; transition: background-color 0.2s ease-out } .tile-2xbig{ height:16.15em; width:100%; } .tile-big { width: 100% } .tile-small { width: 49%; margin-right: 2% } .tile-small.last { margin-right: 0 }سيحتوي زوج من القطع على صورة مع عنوان لها، هاتان القطعتان ستحصلان على الصنف fig-tile وذلك لتمييز نوعهما في شيفرة JavaScript التي سنراها لاحقًا. سنحصل على الألوان المستخدمة من أجل النص والخلفية لصفحة ما من الألوان المستخدمة في العنوان، لذلك لا تنسى أن تُعرّفهم. بالنسبة للعنوان إمّا أن يكون ثابتًا أو أن يُعطي شعورًا بالانزلاق عندما يتحرك فوقه مؤشّر الفأرة: .tile-caption{ position:absolute; z-index:1; background-color: #455962; color:#fff; font-size:1em; padding:1em; text-align: left; } .caption-bottom{ left:0; bottom:0; right:0; height:40%; } .caption-left{ left:-100%; top:0; bottom:0; width:40%; transition: left .3s linear; } .tile:hover .caption-left{ left:0; }بالنسبة للقطع النظامية regular tiles التي لا تملك أي نوع من التحريك، فستغيّر لون خلفيّتها ولون النص عند تحريك الفأرة فوقها. لكي نتأكّد من أنّ النص مُوسّط عموديًا vertically centered في كل قطعة، سنضع في كل قطعة عنصر div يحوي بدوره عنصر فقرة (العنصر <p>) يحوي النص. سنستخدم القيمة table-cell للخاصية display وذلك لتوسيط النص عموديًا ضمن الفقرة: .tile div{ position:absolute; top:0; left:0; right:0; bottom:0; width:100%; height:100%; text-align:center; display:table; padding:0 1em; transition: all .3s ease; } .tile div p{ display:table-cell; vertical-align:middle; }سنترك الحديث عن أنماط التنسيق العامّة للقطع بهدف الاختصار، ولكن ينبغي علينا التأكّد من أنّنا سنعيّن لون النص والخلفية لجميع القطع، حتى تلك التي ستُغطّى بصورة، لأنّ هذه الألوان التي سنحصل عليها باستخدام JavaScript ستُستخدَم لضبط الألوان في الصفحة المرتبطة بها كما أشرنا قبل قليل. دعونا الآن نتحدّث عن التحريكات والانتقالات التي تحدث على قطعة ما. ستحتوي القطع المزوّدة بنص منزلق على عنصري div، سيبدو كل عنصر div كوجه أو كتلة منفصلة داخل القطعة. سيكون تموضعًا عنصريًا div مطلقًا positioned absolutely وسيتحرّكان عند تحرّك الفأرة فوقهما وذلك وفقًا لاتجاه الانزلاق المطلوب. فلكي ينزلق نص القطعة إلى الأعلى عندما يحوم مؤشّر الفأرة فوقه سنطبّق الصنف slideTextUp: .slideTextUp div:nth-child(2){ top:100%; } .slideTextUp:hover div{ transform: translateY(-100%); } .tile-1 p{ font-size:1.3em; }وبشكل مماثل ولكي ينزلق نص القطعة إلى اليسار وإلى اليمين سنطبّق الصنفين slideTextLeft و slideTextRight على الترتيب. .slideTextRight div:first-child{ left:-100%; } .slideTextRight:hover div{ transform: translateX(100%); } .slideTextLeft div:nth-child(2){ left:100%; } .slideTextLeft:hover div{ transform: translateX(-100%); }أمّا بالنسبة لزوج القطع التي ستنقلب، فسيكون لهما تأثير مختلف عندما يحوم مؤشّر الفأرة فوقهما، فهما يدوران ليُظهران الوجه الخلفي. يُعتبر هذا التأثير نوعًا بسيطًا جدًا من تأثير "انقلاب البطاقة" card flip. لن نخوض في تفاصيل هذا التأثير. لإنجاز هذا التأثير، سنطبّق الصنف rotate3d إلى القطعة التي نريد أن تنقلب. بالنسبة للقطعة التي نريد أن تنقلب عموديًّا، سنطبّق الصنف rotate3dy، أمّا بالنسبة للانقلاب الأفقي سنطبّق الصنف rotate3dx (مع الانتباه إلى وجوب وجود الصنف rotate3d في كلتا الحالتين). انظر إلى تنسيقات CSS التالية: .rotate3d{ perspective: 800px; overflow: visible; } .faces{ transform-style: preserve-3d; transition: transform 1s; } .faces div { display: block; position: absolute; top:0; left:0; right:0; bottom:0; width: 100%; height: 100%; backface-visibility: hidden; }لاحظ بأنّه عند تحريك مؤشّر الفأرة فوقهما بالتتالي، فسيظهر وجه أحدهما في حين ستظهر خلفية الآخر بنفس الوقت. .rotate3dY .back{ transform: rotateY( 180deg ); } .rotate3dX .back{ transform: rotateX( 180deg ); }وعندما يحوم مؤشّر الفأرة فوق القطعة فإنّ أي عنصر div يخضع للصنف faces. سيُدوّر ليُظهر وجهه الخلفي: .rotate3dY:hover .faces:hover{ transform: rotateY( 180deg ); } .rotate3dX:hover .faces:hover{ transform: rotateX( 180deg ); } لتنسيق القطع في الدوران ثلاثي البعد، ينبغي الانتباه إلى ضبط لوني الخلفية والنص للوجه الأمامي (ذو الصنف front.) بحيث يمكن الحصول على هذين اللونين واستخدمهما لاحقًا في الصفحة المتربطة بالقطعة عند فتحها. لنعرّف الآن تنسيقات تفاعلية للوح Dashboard. ستكون أعمدة اللوح ذات عرض كامل على الشاشات الصغيرة في البداية (تذكّر أنّنا نراعي متطلبات تصميم الأجهزة المحمولة أولًا mobile-first)، في حين أنّ هذه الأعمدة ستكون بجانب بعضها البعض في الشاشات الكبيرة. .col1, .col2, .col3 { width: 99%; margin: 1em auto } @media screen and (min-width: 43.75em) { .col1, .col2, .col3 { float: left; margin-right: 1%; width: 49% } .page-title{ font-size:2.5em; } .page-content{ font-size:1em; } .close-button{ font-size:2em; } } @media screen and (min-width: 64em) { .col1, .col2, .col3 { float: left; margin-right: .5%; width: 31% } .col3 { margin-right: 0 } .col1 { margin-left: 2em } .page-title{ font-size:3.5em; } } جافا سكريبت JavaScriptستُعالَج جميع أحداث النقر عن طريق JavaScript. سنستخدم مكتبة jQuery لهذه الغاية، وسنضبط معالج حدث event handler النقر لكل قطعة على لوح البداية، فعندما ينقر المستخدم على قطعة ما، يعمل معالج حدث النقر الموافق على الحصول على اسم ونوع الصفحة المرتبطة بهذه القطعة وذلك من السمتين data-page-name و data-page-type على الترتيب، حيث سنستخدم هذه المعلومات لفتح الصفحة المطلوبة. أمّا عند إغلاق الصفحة عند النقر زر الإغلاق لها، فسيعمل معالج حدث النقر لهذا الزر على تطبيق أسماء الأصناف المناسبة لإغلاق الصفحة. بالإضافة لذلك، ولكي نُكسِب كل صفحة لون خلفية ولون نص مماثل لتلك التي للقطعة المرتبطة بها، فإنّنا سنطوف بدايةً على جميع القطع، ونحصل على ألوانها، ثمّ نُطبّق هذه الألوان على الصفحات المرتبطة معها. في حال كان لقطعة ما الصنف rotate3d، فإنّنا سنبحث عن لون الخلفية لوجه face القطعة، ومن ثمّ نطبّق هذا اللون على الصفحة المرتبطة معها. function(){ $('.tile').each(function(){ var $this= $(this), page = $this.data('page-name'), bgcolor = $this.css('background-color'), textColor = $this.css('color'); if($this.hasClass('rotate3d')) { frontface = $this.find('.front'); bgcolor = frontface.css('background-color'); textColor = frontface.css('color'); } if($this.hasClass('fig-tile')) { caption = $this.find('figcaption'); bgcolor = caption.css('background-color'); textColor = caption.css('color'); } $this.on('click',function(){ $('.'+page).css({'background-color': bgcolor, 'color': textColor}) .find('.close-button').css({'background-color': textColor, 'color': bgcolor}); }); }); function showDashBoard(){ for(var i = 1; i <= 3; i++) { $('.col'+i).each(function(){ $(this).addClass('fadeInForward-'+i).removeClass('fadeOutback'); }); } } function fadeDashBoard(){ for(var i = 1; i <= 3; i++) { $('.col'+i).addClass('fadeOutback').removeClass('fadeInForward-'+i); } } $('.tile').each(function(){ var $this= $(this), pageType = $this.data('page-type'), page = $this.data('page-name'); $this.on('click',function(){ if(pageType === "s-page"){ fadeDashBoard(); $('.'+page).addClass('slidePageInFromLeft').removeClass('slidePageBackLeft'); } else{ $('.'+page).addClass('openpage'); fadeDashBoard(); } }); }); $('.r-close-button').click(function(){ $(this).parent().addClass('slidePageLeft') .one('webkitAnimationEnd oanimationend msAnimationEnd animationend', function(e) { $(this).removeClass('slidePageLeft').removeClass('openpage'); }); showDashBoard(); }); $('.s-close-button').click(function(){ $(this).parent().removeClass('slidePageInFromLeft').addClass('slidePageBackLeft'); showDashBoard(); }); })();وبهذا نكون قد وصلنا إلى نهاية الدرس. أرجو أن يكون ممتعًا ومفيدًا. بإمكانك استعراض مثال حيّ لهذا الدّرس من هنا. أما الشيفرة المصدرية فهي مُتوفّرة في هذا المُستودع. ترجمة -وبتصرّف- للمقال How to Create Windows-8-like animations with CSS3 and JQuery لصاحبته Sara Soueidan.
  12. سنتعلّم مبادئ HTML و CSS لإنشاء مشاريع ويب خاصة بنا. سيتميّز هذا الدرس بتركيزه على الجانب العملي بشكل كبير، حيث سنبدأ فورًا بإنشاء مشروع خاص بنا. أمّا بالنسبة للنواحي النظرية فسنشرحها عند الحاجة أثناء تقدّمنا ببناء المشروع. بهذه الطريقة سنكتسب أساسًا متينًا وسريعًا في مجال تطوير الويب. سأوجّهك خلال هذا المشروع إلى روابط خارجية تُشير إلى مصادر أخرى للتوسُّع في نقاط معيّنة إن أحببت ذلك. المشروع سيكون المشروع عبارة عن بناء ملف شخصي portfolio على الويب. سيضم صفحة بداية Home ومدوّنة Blog وصفحة تُظهر مشاريع ويب المستقبلية التي تنوي إنشائها Projects، بالإضافة إلى صفحة للتواصل Contact. الهدف من المشروع الهدف منه هو جعلك تدخل عالم برمجة الويب ومساعدتك كي تتعلّم كيفية إيجاد المزيد من المعلومات حول أي موضوع لوحدك. ستصبح قادرًا بعد ذلك على معالجة مشاريع ويب أكثر تعقيدًا. ما هو HTML و CSS؟ لغة الرُماز المعلَّم Hypertext Markup Language والتي ندعوها اختصاراً HTML هي لغة مسؤولة عن بُنية structure صفحة الويب. فمثلًا يمكنك تعريف عناوين headings وفقرات paragraphs ونصوص texts وصور images في HTML. أمّا بالنسبة لأوراق الأنماط المتتالية Cascading Style Sheet وندعوها اختصاراً CSS فهي مسؤولة عن تنسيق (تنميط) style وتخطيط layout صفحة الويب. يمكنك تعريف تنسيقات جديدة خاصة بالألوان والخطوط وطرق المحاذاة وحتى يمكنك إنشاء بعض التحريكات animations البسيطة في CSS. تذكّر: تزوّدنا HTML بالمحتوى في حين تُنسّق CSS هذا المحتوى. دورة تطوير واجهات المستخدم ابدأ عملك الحر بتطوير واجهات المواقع والمتاجر الإلكترونية فور انتهائك من الدورة اشترك الآن موقع ويب أم تطبيق ويب يمكننا بناء مواقع ويب websites معقّدة جدًّا باستخدام HTML و CSS فحسب. لكن ستكون مواقع الويب هذه ساكنة static، ويعني ذلك أنّ زوّار الموقع يمكنهم استعراض الصفحات لكنّهم لا يمكنهم التفاعل مع هذه الصفحات (باستثناء النقر على الروابط الموجودة في الصفحات). لبرمجة مواقع ويب ديناميكية dynamic تكون تفاعلية مع المستخدم، سنحتاج إلى لغة برمجة إضافية مثل JavaScript أو Dart. ويمكننا باستخدامهما تطوير (هو مفهوم أوسع من البرمجة) تطبيقات ويب Web Applications كاملة مثل التطبيقات التي تهتم بإجراء الحسابات المختلفة أو تطبيقات الألعاب أو تطبيقات المحادثة وغيرها الكثير. تعمل هذه التطبيقات في الواقع ضمن متصفّح الويب. كما توجد لغات برمجة وتقنيات أخرى مثل PHP وRuby وASP.NET تسمح ببناء تطبيقات ويب ديناميكية أيضًا ولكن تعمل هذه التطبيقات ضمن مزوّد خدمة الاستضافة (على المخدّم). كما يمكن المزج بين هذين الأسلوبين لإنشاء مواقع ويب فعّالة للغاية. يمكنك بعد الانتهاء من هذه الدروس، البدء بتعلّم مثل هذه اللغات والتقنيات وإنشاء تطبيقات ويب ديناميكية. الأجهزة المحمولة يُشكّل الوصول إلى مواقع الويب عن طريق الأجهزة المحمولة كالهواتف الذكيّة أو الأجهزة اللوحية نسبة كبيرة من عمليات الوصول العامة. وهكذا فإنّه من الضروري أن يظهر موقعنا بشكل جيّد على الشاشات الصغيرة. على العموم سنولي هذا الأمر اهتمامًا خلال هذه السلسلة التعليمية. الأدوات المستخدمة نحتاج إلى تطبيقين للدخول في عالم تطوير وبرمجة الويب، محرّر نصوص لإنشاء الملفات الخاصة بموقع الويب، ومتصفّح ويب لعرض وتجربة الموقع. 1- المحرر Editor سيكون كافيًا استخدام محرّر نصوص عادي (كبرنامج المفكرة Notepad في ويندوز مثلًا). ولكن من الأفضل استخدام محرّر نصوص يسهّل عملنا إلى حدٍّ كبير. لهذا الغرض أنصح باستخدام محرّر نصوص عصري ومخصّص لتحرير HTML. محرّر النصوص الذي أنصح به حاليًا هو Brackets (مجّاني من شركة أدوبي Adobe). يمكنك أن تستخدم أي محرّر تريده، ولكنّني في هذه السلسلة سأُشير أحيانًا إلى بعض وظائف تطبيق Brackets. يوجد محرّر نصوص جيّد أيضاً ويمكنك استخدامه وهو Atom، ويوجد محرّر نصوص آخر أيضًا، قديم قليلًا لكنّه جيّد وهو ++Notepad. حمّل ونصّب المحرّر Brackets إذا أردت ذلك. 2- المتصفح Browser يتوجّب على موقعنا أن يعمل على جميع المتصفحات الرئيسية بالطبع (Internet Explorer و Firefox و Chrome و Safari). على أية حال، أنصح باستخدام المتصفح Chrome لأغراض التطوير والبرمجة. يضم Chrome أدوات مفيدة للغاية لمطوّر الويب والتي سيستخدمها على نحو متكرّر. بالإضافة إلى ذلك، يدعم المحرّر Brackets المتصفّح Chrome بشكل جيّد، بحيث أنّ التغييرات التي تحدث في النص ستظهر مباشرةً ضمن Chrome (عن طريق ميزة اسمها Live Reload). حمّل ونصّب المتصفح Chrome الآن من هنا. إنشاء مستند HTML لنبدأ الآن بإنشاء مستند HTML الأوّل لنا من أجل موقع الويب: أنشئ مجلّدًا من أجل المشروع. سمّ المجلّد بالاسم Portfolio (أو أي اسم آخر ترغبه). افتح برنامج Brackets. من القائمة File اختر الأمر …Open Folder لتحديد وفتح المجلّد الذي أنشأناه قبل قليل. انقر بزر الفأرة الأيمن أسفل اسم المجلّد واختر New File لإنشاء ملف جديد، سمّه index.html. لديك الآن ملف نصّي فارغ اسمه index.html لماذا الملف index.html؟ في الواقع للملف index.html معنى خاص، فعندما نطلب من المتصفّح عنوان موقع ويب ما، وليكن مثلًا http://code.makery.ch، فعند ذلك سيُعرَض الملف index.html أولاً بشكل تلقائي، أي كأنّنا طلبنا العنوان http://code.makery.ch/index.html. بالنسبة إلينا، سيمثّل الملف index.html الصفحة الرئيسية. عمليتا العرض والتحديث يمكننا الآن تعبئة مستند HTML (الملف index.html) بالمحتوى. اكتب الأسطر التالية ضمن مستند HTML. لعرض الصفحة ضمن المتصفّح، انقر الأيقونة التي تُشبه البرق في الطرف الأيمن من البرنامج (المعاينة الحية Live Preview). سيُفتَح المتصفّح Chrome وسيُعرض المستند ضمنه، وفي حال أجريت أي تغيير جديد على مستند HTML فسترى نتيجة ذلك على المتصفّح مباشرةً، وهي في الحقيقة ميزة هامة وفعّالة. إذا لم تظهر الصفحة، اذهب إلى المكان الذي يوجد فيه الملف index.html وافتحه مباشرةً باستخدام Chrome أو أي متصفّح آخر. أمّا لم تُحدّث الصفحة تلقائياً، فاحفظ جميع الملفات المفتوحة (سننشئ ملفات أخرى تباعاً) ثم من نافذة المتصفح اضغط F5 على لوحة المفاتيح. تهانينا، لقد أنشأت موقع ويب الأوّل الخاص بك. التحييد Indentation لكي نُبقي الشيفرة نظيفة وواضحة، من المهم أن تعمل على تحييد النص بشكل صحيح باستخدام مفتاح الجدولة Tab من لوحة المفاتيح. يأخذ مفتاح Tab في برنامج Brackets أربعة فراغات بشكل افتراضي. بالنسبة لي أجد ذلك كثيراً بعض الشيء، لذلك أنصح أن تغيّر هذا لتصبح الفراغات spaces التي يأخذها المفتاح Tab تساوي 2، وذلك من أسفل نافذة Brackets. من المهم جدًّا أن ننتبه إلى تحييد الشيفرة من البداية، لكي نكتب شيفرة نظيفة وواضحة من بداية تعلّمنا للبرمجة عموماً. تلميح 1: استخدام Shift+Tab لكي تنقل المحاذاة إلى اليسار بدلاً من اليمين. تلميح 2: يمكنك محاذاة عدة أسطر بنفس الوقت إذا اخترتهم وضغطت Tab أو حتى Shift+Tab. عناصر HTML 1- الوسوم Tags في المثال السابق رأيت رموزًا مكتوبة ضمن رمزي <> تشكل هذه الرموز كلمات نُسميها الوسوم Tags. تتألف عناصر HTML عادةً (ولكن ليس دائماً) من وسمين، وسم للفتح opening tag ووسم للإغلاق closing tag. في مثالنا السابق كان <html> هو وسم للفتح، أمّا <html/> هو وسم للإغلاق حيث نلاحظ وجود محرف slash قبل اسم الوسم. أي نص موجود بين وسمي الفتح والإغلاق يُعتبر محتوى لعنصر HTML هذا. فمثلاً بالنسبة للوسمين <html> و <html/> نُخبر متصفّح الويب عن بداية ونهاية مستند HTML لصفحة الويب الخاصة بنا. أمّا الوسم الثاني الذي صادفناه هو الوسم <body>. يُحدّد هذا الوسم أنّ جميع المحتوى الواقع بين وسم الفتح <body> والإغلاق <body/> سيظهر بشكل مرئي للمستخدم في المنطقة الرئيسية من نافذة المتصفّح. 2- السمات Attributes تُعرّف السمات معلومات إضافية لعنصر HTML. وتقع هذه السمات ضمن وسم الفتح لعنصر HTML، ويكون لها دائماً اسم name وقيمة value. كمثال على السمات، دعنا ننظر إلى عنصر HTML الخاص بالروابط. وهو ربما من أهم العناصر على الإطلاق. يضم عنصر الروابط <a> السمة href (وهي اختصار للكلمتين hypertext reference) التي تحمل القيمة في هذا المثال http://code.makery.ch.ولكن سيعرض المتصفّح هذا الرابط على شكل النص التالي: My Website. البنية الأساسية لصفحة HTML لقد رأينا قبل قليل عنصري HTML وهما <html> و <body>. ولكن بنية صفحة (مستند) HTML تتكوّن عادةً من المزيد من العناصر. استبدل محتويات الملف index.html بالشيفرة التالية، بعد ذلك سنناقش كل عنصر HTML موجود فيها. بنية ملف (مستند) HTML <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Web Portfolio of Marco</title> </head> <body> <h1>Web Portfolio of Marco</h1> <p>Write anything you want to tell the world.</p> </body> </html> الشرح نضع في السطر الأوّل <DOCTYPE html!> دوماً. فهي تخبر المتصفّح عن نوع المستند. يشير الوسم <html> إلى بداية المستند والوسم <html/> إلى نهايته. يحتوي العنصر <head> (بين وسمي الفتح والإغلاق له) على معلومات إضافية حول الصفحة. وبشكل مختلف عن العنصر <body>، لا تظهر هذه المعلومات في نافذة المتصفح الرئيسية. يجب أن تكون هناك إشارة ضمن العنصر <head> حول الترميز character set المستَخدَم في هذا المستند: <"meta charset="utf-8>. إذا لم تحدّد الترميز المستَخدَم فإنّ بعض الرموز قد لا تظهر بصورة صحيحة. ربما قد لاحظت أنّ العنصر <meta> لا يمتلك وسم إغلاق. توجد بعض عناصر HTML التي لا تمتلك أيضًا وسوم إغلاق، ولكنها تعتبر استثناءً. نرى بعد ذلك الوسم <title> الذي يضم عنوان المستند والذي سيظهر على شريط العنوان لنافذة المتصفّح. كل شيء ضمن الوسم <body> سيظهر ضمن نافذة المتصفّح الرئيسية. يُعرّف العنصر <h1> العنوان الرئيسي الذي سيظهر للمستخدم ضمن صفحة الويب. ويمكن إنشاء عناوين فرعية أيضاً باستخدام العناصر <h2> <h3> <h4> <h5> <h6>. النص الموجود بين الوسمين <p> و <p/> يُعتبر فقرة مستقلة، وهذا ما يُعبّر عنه العنصر <p>. بعد كل وسم فتح لعنصر ما، يجب أن نحاذي العنصر التالي (بمفتاح الجدولة Tab) لتحسين عرض الشيفرة. ورغم أنّ ذلك ليس ضرورياً ولا يؤثّر أصلاً في عرض المستند، ولكن تأكّد من امتلاكك لهذه العادة الجيّدة. تلميح 1: يمكنك استخدام بنية HTML السابقة لأي صفحة HTML جديدة. تلميح 2: استخدم الاختصار Ctrl+S من لوحة المفاتيح لحفظ الملف الحالي. تلميح 3: استخدم الاختصار Ctrl+Z من لوحة المفاتيح للتراجع عن العمليات التي أجريتها. نحن مستعدّون الآن وبعناصر HTML البسيطة هذه، أن نرتقي بموقعنا إلى مستوى أعلى. في البداية لنُضِف صورة بحيث تبدو الصفحة الرئيسية لمشروعنا أكثر جمالًا. إدراج صورة لإدراج صورة نستخدم العنصر <img>. المثال التالي سيُدرج صورة موجودة ضمن ملف اسمه marco.jpg: <img src="marco.jpg" alt="Picture of me"> للعنصر <img> وسم فتح فقط ولا يوجد له وسم إغلاق. وهو يحتوي على سمتين src و alt. السمة src تُحدّد عنوان URL الذي يُعبّر عن اسم ملف الصورة ومساره. أمّا السمة alt فتمثّل النص البديل، وهو النص الذي يصف محتويات الصورة. يُستخدم هذا النص من قِبل محرّكات البحث، وفي حال تعذّر عرض الصورة ضمن الصفحة سيُعرض هذا النص بدلاً عنها. 1- عناوين URL النسبية والمطلقة تُستخدم عناوين URL من أجل السمة src الخاصة بعنصر الصورة، وأيضاً من أجل السمة href الخاصة بعنصر الارتباط. يُحدّد عنوان URL عنوان (مسار) ملف، وبصورة عامة العنوان هو مصدر resource قد يكون صورة أو صفحة ويب من موقع آخر. بالاعتماد على موقع الملف نستخدم إمّا العنوان النسبي relative أو العنوان المطلق absolute. فإذا كان الملف موجودًا ضمن نفس موقع الويب، عندها يمكن استخدام عنوان نسبي. فكما رأينا في المثال السابق اسم الملف وحده موجود دون عنوانه الفعلي (المطلق). يكون عنوان URL من النوع النسبي، نسبيًا دومًا إلى صفحة HTML الحالية، فإذا كان الملف المستهدف وصفحة HTML التي ستستخدمه موجودان ضمن نفس المجلّد فعندها يكفي الإشارة إلى اسم الملف فقط، أمّا إذا كانا ضمن مجلّدين مختلفين فعندها يحب أن يؤخذ ذلك بعين الاعتبار. فإذا فرضنا مثلًا أنّ ملف الصورة من المثال السابق موجودة ضمن مجلّد فرعي اسمه images سيكون عنوان URL النسبي لملف الصورة images/marco.jpg. أمّا إذا كان ملف الصورة موجود ضمن المجلّد الأب، فيمكنك عندئذ الوصول إليه باستخدام البادئة ( /.. ) أي سيصبح عنوان الملف في هذه الحالة marco.jpg/.. أمّا إذا كان الملف موجوداً ضمن موقع ويب آخر، فعندها يجب استخدام عنوان URL مطلق. تحتوي عناوين URL المطلقة على الاسم والمسار الكاملين للملف. حقائق عن عناوين URL: عنوان URL الذي يبدأ بـ //:http هو عنوان URL مطلق. عنوان URL بدون //:http هو عنوان URL نسبي بالنسبة إلى صفحة ويب الحالية. تُشير النقطة ( . ) إلى المجلّد الحالي. تُشير النقطتان ( .. ) إلى المجلّد الأب. أمثلة عن عناوين ويب النسبية والمطلقة: <!-- عناوين نسبية --> <a href="image-gallery.html">Image Gallery</a> <a href="blog/first-blog-entry.html">My First Blog Entry</a> <a href="../image-gallery.html">Back to Image Gallery</a> <!-- عناوين مُطلقة --> <a href="http://www.my-colleague.com/blog.html">Blog of a Colleague</a> 2- إضافة صورة إلى موقعنا لندرج صورة ضمن الصفحة، ينبغي نسخ ملف الصورة إلى المجلّد Portfolio. من الممكن أن تستخدم نفس الصورة الموجودة مع هذا الدرس، أو أن تستخدم صورة من عندك، ولكن احرص في جميع الأحوال على أنّك ستُحدّد اسم الملف مع الامتداد بدقّة. يجب أن تحصل على شيفرة شبيهة بما يلي (لاحظ أنّني أضفت عناوين فرعية بالإضافة إلى مزيد النصوص): الملف index.html مع الشيفرة اللازمة: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Web Portfolio of Marco</title> </head> <body> <h1>Web Portfolio of Marco</h1> <h2>Welcome!</h2> <p>Thanks for stopping by.</p> <p>Please have a look around. In the blog section I document my experiences in programming. You may also look at my web projects. Have Fun.</p> <img src="marco.jpg" alt="Picture of me"> <p>Marco :-)</p> </body> </html> والصورة التالية لما ستبدو عليه الصفحة في متصفّح الويب: إن أردت تعلم المزيد حول HTML و CSS وأن تصبح خبيرًا بهما وأن تطور مواقع وتطبيقات ويب عالية الجودة، فأنصحك بالاطلاع على دورة تطوير واجهات المستخدم المقدمة من أكاديمية حسوب. سنتعلّم في الدرس الثاني كيف ننشر موقعنا على الانترنت. ترجمة -وبتصرّف- للدّرس HTML & CSS Tutorial - Part 1: Your First Website لصاحبه Marco Jakob. اقرأ أيضًا المدخل الشامل لتعلم تطوير الويب دليل تعلم لغة HTML دليل تعلم البرمجة
  13. بالإضافة إلى ماتفضّل به الأخوة.. يمكنك أن تجرّب أيضًا أن تستنشق هواءً نظيفًا في الخارج، وأن تحاول التقيّد بنظام مُحدّد في العمل والنوم والاستراحة.
  14. عند استخدام التحريكات animations والانتقالات transitions ضمن واجهة المستخدم، فإنّه من الضروري أن يكون لها هدف واضح ومحدّد، ألا وهو تحسين تجربة المستخدم. تؤمّن لنا الانتقالات transitions الوسيلة المناسبة والمثالية لجعل الحركة سلسة وانسيابية أمام المستخدم. بدون تأثيرات الانتقال من الممكن أن يصبح المستخدم في حيرة من أمره حول الذي حدث بالضبط عند تنفيذه لأمر معين. في هذا المقال، سننشئ بعض التحريكات والانتقالات الإبداعية لإضافة وإزالة عناصر من قائمة، لقد أعجبتني الفكرة الواردة في مقال باسكويل دي سيلفيا. أمّا بالنسبة للشيفرة المسؤولة عن الإنتقالات في مقال باسكويل، فقد كتبه كريس كوير. سأعمل على تطوير المثال الوارد في مقال باسكويل، وذلك بإضافة المزيد من تأثيرات الانتقالات والتحريكات، وسأستخدم أيضاً شيفرة صغيرة من مقال كريس لإضافة خطوة إضافية في كل تحريكة، تتمثل بحجز مكان للعناصر المراد إضافتها إلى القائمة قبل إضافتها فعلياً. سأستخدم خصائص CSS بدون أي بادئة prefix وذلك بغرض الاختصار، لكنك ستجد الخصائص كاملة ضمن النص المصدري للمشروع على Github. ستعمل مقاطع الشيفرة التي ستجدها ضمن هذا الدرس على متصفحات تدعم خصائص CSS المستخدمة. لنبدأ العمل! الرماز The Markupلتوضيح فكرة الدرس بشكل جيد، أنشأت تطبيقاً بسيطاً خاصاً بالملاحظات البسيطة. يستخدم هذا التطبيق تقنية التخزين المحلي LocalStorage التي توفرها HTML5 وذلك لحفظ الملاحظات ضمن التخزين المحلي لمتصفح ويب لديك. يسمح لك التطبيق بأخذ ملاحظات وحفظها ضمن المتصفح إن أردت ذلك، في الحقيقة هو السبب الذي من أجله بنيت هذا التطبيق، وذلك من أجل ملاحظاتي الخاصة. لن أخوض في تفاصيل كيفية بناء هذا التطبيق لأنّ ذلك ليس هدف هذا الدرس. الرُماز markup المستخدم في هذا التطبيق هو مجرد نموذج form بسيط يحتوي على حقل نصي text field وزر إرسال submit button، بالإضافة إلى قائمة غير مرتّبة unordered list. ستُضاف الملاحظات إلى هذه القائمة بشكل تلقائي. كما يوجد أيضاً عنصري div لعرض التنبيهات، التي ستظهر عند حفظ أو إزالة أي عنصر، بالإضافة إلى عدّاد وزر لحذف جميع العناصر بنقرة واحدة. فيما يلي جميع رُماز HTML الذي سنحتاجه: <div class="notification undo-button"> Item Deleted. Undo? </div> <div class="notification save-notification"> Item Saved </div> <div class="reminder-container"> <header> <h1>mini reminders list</h1> </header> <form id="input-form"> <input type="text" id="text" placeholder="Remind me to.."/> <input type="submit" value="Add" /> </form> <ul class="reminders"> </ul> <footer> <span class="count"></span> <button class="clear-all"> Delete All </button> </footer> </div>يمكنك إضافة وتحرير وإزالة العناصر (الملاحظات) بالإضافة إلى إمكانية إستعادة العنصر المحذوف. في الواقع، تأتي أغلب التحريكات مرافقة لعملية إزالة وإستعادة العناصر. تُعتبر عملية إضافة العناصر بسيطة ولا تترافق مع الكثير من التحريكات، باستثناء التحريك الخاص بالظهور التدريجي fade in والسقوط إلى أسفل falling down واللذان سنتحدث عنهما عندما نبدأ العمل مع CSS. تنسيقات CSSستحصل العناصر المُضافة توّاً عن طريق JavaScript على الصنف new-item. (صنف CSS). أمّا العناصر المُزالة فستحصل على الصنف removed-item. كما ستحصل العناصر المُستعادة على الصنف restored-item. وكل صنف من الأصناف السابقة سيُفعّل التحريكات الخاصة به. ستبقى أسماء الأصناف السابقة ثابتةً لجميع الأمثلة التوضيحية، في حين ستختلف فيما بينها بالتوجيه المسؤول عن مظهر التحريك keyframes@. لنبدأ الآن بالمثال التوضيحي الأول. المثال الأول المثال الأول: العناصر المُزالة "تسقط إلى أسفل"، والعناصر المُستعادة ستعود بحركة معاكسة. ستسقط العناصر المضافة حديثاً من الأعلى، وهذا تأثير بسيط لكنه جميل. سيبدأ كل عنصر مُضاف حديثاً بالسقوط إلى أسفل وذلك من موقع يعلو 400 بيكسل عن الموقع النهائي الذي سيستقر فيه (أي الموقع النهائي ناقص 400 بيكسل) لا تنس أنّه يجب على الخاصية الفرعية animation-fill-mode أن تحمل القيمة forwards وذلك للتأكّد من أنّ العناصر ستبقى في موقعها النهائي ضمن القائمة، وإلّا فإنّها ستختفي بمجرّد انتهاء عملية التحريك. li.new-item { opacity: 0; animation: new-item-animation .3s linear forwards; } @keyframes new-item-animation { from { opacity: 0; transform: translateY(-400px); } to { opacity: 1; transform : translateY(0); } }ستسقط العناصر المزالة وتتلاشى fade out. بالنسبة لتحريكة السقوط إلى أسفل فهي بسيطة جداً، حيث ينتقل العنصر إلى أسفل وفق محور التراتيب (محور y) ليحاكي تحريكة السقوط، ويدور بينما يسقط ويتلاشى بالتدريج حتى يختفي تماماً (ستتحقّق شيفرة JavaScript من أنّ العنصر قد أُزيل كليّاً من DOM في نهاية هذه التحريكة). li.removed-item { animation: removed-item-animation 1s cubic-bezier(0.55, -0.04, 0.91, 0.94) forwards; transform-origin: 0% 100%; } @keyframes removed-item-animation { 0% { opacity: 1; transform: rotateZ(0); } 100% { opacity: 0; transform: translateY(600px) rotateZ(90deg); } }أمّا عندما نستعيد عنصرًا فستعمل تحريكة الاستعادة على عكس المنطق الموجود في تحريكة إزالة عنصر، لذلك فستكون الأُطر الأساسية keyframes مُعرّفة بشكل معاكس تماماً لما هو عليه في تحريكة إزالة عنصر: li.restored-item { animation: openspace 0.3s ease forwards, restored-item-animation 0.3s 0.3s cubic-bezier(0, 0.8, 0.32, 1.07) forwards; } @keyframes openspace { to { height: auto; } } @keyframes restored-item-animation { 0% { opacity: 0; transform: translateY(600px) rotateZ(90deg); } 10% { opacity: 1; transform: translateY(600px) rotateZ(90deg); } 100% { opacity: 1; transform: rotateZ(0); } }يمكنك أن ترى أننا نستخدم في الشيفرة السابقة مظهر تحريك اسمه openspace استعرته من مقال كريس كوير. يتأكّد مظهر التحريك هذا من أنّ العناصر التي تقع أسفل العنصر المُسترجع (إن وجدت)، ستنزلق إلى الأسفل وتفسح مجالاً للعنصر المُسترجَع ليعود إلى مكانه. إذاً عندما تنزلق العناصر إلى الأسفل لتفسح مجالاً open space للعنصر المُسترجَع، فإنّها فعلياً يجب أن تنتقل إلى الأسفل بشكل سلس، ولكن بما أنّ العناصر في هذا التطبيق لا تملك ارتفاعاً height ثابتاً، لذلك فإنّ إطار التحريك الأساسي to (انظر الشيفرة في الأعلى) سيجعل قيمة الارتفاع height لها لتصبح auto في نهاية عملية التحريك، سيؤدي ذلك لسوء الحظ إلى أنّ العناصر لن تنزلق إلى الأسفل، بل ستبدو كما لو أنّها تقفز إلى الأسفل. على أية حال توجد طريقة تجعل العناصر تغير مواقعها بشكل سلس، وهي تقنية كتب عنها ستيف ساندرسون Steve Sanderson هنا. لكنه يستخدم لهذا الغرض التموضع المطلق absolute positioning، وكمية لا بأس بها من شيفرة JavaScript. يمكنك تفقّد مقالته إذا كنت مهتماً بمعرفة المزيد عن التقنيّة التي يستخدمها، والتي تعطي في الحقيقة نتائج رائعة! المثال الثاني المثال الثاني: العناصر تكبُر وتتلاشى أمام المستخدم، وتُستَعاد بطريقة معكوسة. يعود الفضل في هذه الفكرة إلى تيم بيتروسكي Tim Pietrusky، حيث جاء بها عندما أخبرته أنّ الأفكار قد نفذت منّي بعد أن وضعت خمسة أمثلة توضيحية! في هذه الفكرة، تظهر العناصر المُضافة حديثاً (أي تلك العناصر التي لم تُزال من قبل ثم استُعيدت) بشكل تدريجي fade in ضمن موقعها. li.new-item { opacity: 0; animation: fadeIn .3s linear forwards; } @keyframes fadeIn { to { opacity: 1; } }عندما تُزال العناصر، فإنّها تكبُر وتتلاشى أمام المستخدم، أمّا العناصر المُستعادة فتسلك الأسلوب المعاكس، فعملية التحريك بالنسبة للعناصر المستعادة تماثل تماماً عملية التحريك بالنسبة للعناصر المزالة ولكن بالمقلوب. li.removed-item { animation: removed-item-animation .6s ease-out forwards; transform-origin: 50% 50%; } @keyframes removed-item-animation { 0% { opacity: 1; transform: scale(1); } 100% { opacity: 0; transform: scale(4); } } li.restored-item { animation: openspace .3s ease forwards, restored-item-animation .3s .3s ease-out forwards; } @keyframes openspace { to { height: auto; } } @keyframes restored-item-animation { 0% { opacity: 0; transform: scale(4); } 100% { opacity: 1; transform: scale(1); } }المثال الثالث المثال الثالث: ستنزلق العناصر المستعادة لتدخل من اليمين، أما العناصر المزالة فستنزلق يساراً إلى الخارج. يُعتبر المثال الثالث أبسط من سابقيه من الناحية الشكلية. فالعناصر المُضافة حديثاً سيكون لها نفس تأثير الظهور التدريجي كما في المثالين السابقين، لذلك سنتجاوز عملية التحريك الخاصة بإضافة عنصر جديد. بالنسبة للعناصر المُزالة فإنها ستنزلق يساراً إلى الخارج، مع ملاحظة تأثير جميل يحدث عند بدء عملية الإزالة باستخدام دالة توقيت من النوع Cubic Bezier، انظر إلى المثال التطبيقي لترى كيف تعمل هذه التحريكة. li.removed-item { animation: removed-item-animation .8s cubic-bezier(.65,-0.02,.72,.29); } @keyframes removed-item-animation { 0% { opacity: 1; transform: translateX(0); } 30% { opacity: 1; transform: translateX(50px); } 80% { opacity: 1; transform: translateX(-800px); } 100% { opacity: 0; transform: translateX(-800px); } }أمّا العناصر المستعادة فستنزلق إلى الداخل من اليمين، وذلك باستخدام نفس دالة التوقيت السابقة، ولكنها ليست الحالة المعاكسة تماماً لها (تفقّد المثال التطبيقي لترى النتيجة النهائية). li.restored-item { animation: openspace .3s ease forwards, restored-item-animation .5s .3s cubic-bezier(.14,.25,.52,1.56) forwards; } @keyframes openspace { to { height: auto; } } @keyframes restored-item-animation { 0% { opacity: 0; transform: translateX(300px); } 70% { opacity: 1; transform: translateX(-50px); } 100% { opacity: 1; transform: translateX(0); } } المثال الرابع المثال الرابع: ستكبر العناصر المستعادة والجديدة وتظهر تدريجياً ضمن موقعها، أمّا العناصر المزالة فإنّها ستصغر وتختفي تدريجياً. وهذا المثال بسيط أيضاً. فكل من العناصر الجديدة والمستعادة ستكبر وتظهر تدريجياً في مواقعها، أما العناصر المزالة ستصغر وتختفي تدريجياً. هناك إطارين أساسيين keyframes لهاتين التحريكتين: li.removed-item { animation: removed-item-animation .6s cubic-bezier(.55,-0.04,.91,.94) forwards; } @keyframes removed-item-animation { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(0); } } li.restored-item { animation: openspace .3s ease forwards, restored-item-animation .3s .3s cubic-bezier(0,.8,.32,1.07) forwards; } @keyframes openspace { to { height: auto; } } @keyframes restored-item-animation { from { opacity: 0; transform: scale(0); } to { opacity: 1; transform: scale(1); } } المثال الخامس المثال الخامس: تسقط العناصر الجديدة من الأعلى إلى الأسفل. العناصر المزالة تبقى معلّقة قليلاً ثم تسقط إلى الأسفل. أما العناصر المستعادة فتنزلق إلى الداخل من اليمين. في هذا المثال، عندما نُزيل أحد العناصر فإنّه يبقى معلّقاً قليلاً قبل أن يبدأ بالسقوط الفعلي ثم الإختفاء. في الحقيقة هذا هو الجزء الأهم في هذا المثال، لأنّ العناصر الجديدة ستسقط إلى الأسفل كما في المثال الأوّل، والعناصر المستعادة ستنزلق إلى الداخل من اليمين كما في المثال الثالث، ولكن مع فرق طفيف في دالة التوقيت timing function. لذلك فإنّ التحريكة الخاصة بإزالة العناصر هي التأثير الجديد الوحيد في هذا المثال. li.restored-item { transform: translateX(300px); animation: openspace .3s ease forwards, restored-item-animation .3s .3s cubic-bezier(0,.8,.32,1.07) forwards; } @keyframes openspace { to { height: auto; } } @keyframes restored-item-animation { to { opacity: 1; transform: translateX(0); } } li.removed-item { animation: removed-item-animation 2s cubic-bezier(.55,-0.04,.91,.94) forwards; transform-origin: 0% 100%; }يعطي تغيير زاوية الدوران للعنصر ضمن أُطر frames مختلفة (الأطر الرئيسية: 0% و 20% و 40% و 60% و 70% و 90% و 100%) انطباعاً بأنّ العنصر يتأرجح بينما يكون معلّقاً، وبعد ذلك يبدأ بالسقوط إلى الأسفل. @keyframes removed-item-animation { 0% { opacity: 1; transform: rotateZ(0); } 20% { opacity: 1; transform: rotateZ(140deg); } 40% { opacity: 1; transform: rotateZ(60deg); } 60% { opacity: 1; transform: rotateZ(110deg); } 70% { opacity: 1; transform: rotateZ(90deg) translateX(0); } 90% { opacity: 1; transform: rotateZ(90deg) translateX(600px); } 100% { opacity: 0; transform: rotateZ(90deg) translateX(600px); } } المثال السادس المثال السادس: ستختفي العناصر المزالة تدريجياً وتسقط إلى الأسفل باتجاه اليسار، أما العناصر الجديدة والمستعادة فستنزلق إلى الداخل من اليمين. سيكون لكل من العناصر الجديدة والمستعادة نفس السلوك في هذا المثال، حيث ستنزلق هذه العناصر إلى الداخل من اليمين ثم تخرج بشكل طفيف من الجهة اليسرى قبل أن تستقرّ في مكانها. li.restored-item { transform: translateX(300px); animation: openspace .3s ease forwards, restored-item-animation .5s .3s cubic-bezier(.14,.25,.52,1.56) forwards; } @keyframes openspace { to { height: auto; } } @keyframes restored-item-animation { 0% { opacity: 0; transform: translateX(300px); } 70% { opacity: 1; transform: translateX(-50px); } 100% { opacity: 1; transform: translateX(0); } }ستنزلق العناصر المزالة ببطء نحو اليسار، وبعد ذلك ستسقط إلى الأسفل باتجاه اليسار وتتلاشى. من المهم الآن أن نعمل على إعداد تحويل مناسب لموضع نقطة الأصل origin (مبدأ الإحداثيات)، بحيث أنّ التأثير المسؤول عن السقوط إلى أسفل يبدو أكثر واقعية. بغية ذلك، أجريت تحويلاً على نقطة الأصل لكي تنطبق على آخر نقطة تماس بين العنصر والسطر الذي ينتمي إليه، وذلك قبل أن يبدأ بالدوران والسقوط إلى أسفل، يعطي ذلك انطباعاً بأنّ العنصر يسقط بسبب وزنه. li.removed-item { animation: removed-item-animation 1s linear; transform-origin: 390px 100%; } @keyframes removed-item-animation { 0% { opacity: 1; transform: translateX(0) rotateZ(0); } 50% { opacity: 1; transform: translateX(-400px) rotateZ(0); } 75% { opacity: 1; transform: translateX(-420px) rotateZ(-30deg); } 100% { opacity: 0; transform: translateX(-800px) rotateZ(-60deg) translateY(400px); } } خاتمةفي الواقع، الإمكانيات المتاحة لا حدّ لها تقريباً، هناك الكثير من الطرق الأكثر الإبداعية لإضافة وإزالة عناصر قائمة، وأنا على ثقة بأنّك تستطيع ابتكار تأثيرات خاصة بك، وأرجو أن يكون هذا الدرس مثيراً وملهماً. لم أدخل في القسم المتعلّق بـ JavaScript لأنّ ذلك ليس من محور اهتمام الدرس. من الملاحظ وجود خطأ ضمن متصفح Firefox (ربما يُصحّح في النسخ اللاحقة) ,والذي يسبب وميضاً للصفحة كلّما تمّ وضع التركيز على العنصر أو حتى إزالة التركيز عنه (أي عندما تضغط زر edit/save). لا أدري إذا كانت توجد طريقة لتجاوز هذا الأمر، لذلك فمن فضلك أعلمني إذا استطعت تحديد سبب ذلك الوميض وإذا كانت هناك أي طريقة لمنعه. على أية حال جُرّبت الأمثلة السابقة بشكل جيّد على المتصفحات التي تدعم Webkit. شكراً لقراءتك هذا الدرس، وأرجو أن تكون قد استمتعت فيه. بإمكانك الاطّلاع على هذه الأمثلة من هنا، أما الشيفرة المصدرية فهي متُوفّرة على هذا المُستودع. ترجمة -وبتصرّف- للمقال Creative Add/Remove Effects For List Items with CSS3 Animations لصاحبته Sara Soueidan.
×
×
  • أضف...