المحتوى عن 'layout'.



مزيد من الخيارات

  • ابحث بالكلمات المفتاحية

    أضف وسومًا وافصل بينها بفواصل ","
  • ابحث باسم الكاتب

نوع المُحتوى


التصنيفات

  • التخطيط وسير العمل
  • التمويل
  • فريق العمل
  • دراسة حالات
  • نصائح وإرشادات
  • التعامل مع العملاء
  • التعهيد الخارجي
  • التجارة الإلكترونية
  • الإدارة والقيادة
  • مقالات ريادة أعمال عامة

التصنيفات

  • PHP
    • Laravel
    • ووردبريس
  • جافاسكريبت
    • Node.js
    • jQuery
    • AngularJS
    • Cordova
  • HTML
    • HTML5
  • CSS
  • SQL
  • سي شارب #C
    • منصة Xamarin
  • بايثون
    • Flask
    • Django
  • لغة روبي
    • Sass
    • إطار عمل Bootstrap
    • إطار العمل Ruby on Rails
  • لغة Go
  • لغة جافا
  • لغة Kotlin
  • برمجة أندرويد
  • لغة Swift
  • لغة R
  • لغة TypeScript
  • ASP.NET
    • ASP.NET Core
  • سير العمل
    • Git
  • صناعة الألعاب
    • Unity3D
  • مقالات برمجة عامة

التصنيفات

  • تجربة المستخدم
  • الرسوميات
    • إنكسكيب
    • أدوبي إليستريتور
    • كوريل درو
  • التصميم الجرافيكي
    • أدوبي فوتوشوب
    • أدوبي إن ديزاين
    • جيمب
  • التصميم ثلاثي الأبعاد
    • 3Ds Max
    • Blender
  • نصائح وإرشادات
  • مقالات تصميم عامة

التصنيفات

  • خواديم
    • الويب HTTP
    • قواعد البيانات
    • البريد الإلكتروني
    • DNS
    • Samba
  • الحوسبة السّحابية
    • Docker
  • إدارة الإعدادات والنّشر
    • Chef
    • Puppet
    • Ansible
  • لينكس
  • FreeBSD
  • حماية
    • الجدران النارية
    • VPN
    • SSH
  • مقالات DevOps عامة

التصنيفات

  • التسويق بالأداء
    • أدوات تحليل الزوار
  • تهيئة محركات البحث SEO
  • الشبكات الاجتماعية
  • التسويق بالبريد الالكتروني
  • التسويق الضمني
  • التسويق بالرسائل النصية القصيرة
  • استسراع النمو
  • المبيعات
  • تجارب ونصائح

التصنيفات

  • إدارة مالية
  • الإنتاجية
  • تجارب
  • مشاريع جانبية
  • التعامل مع العملاء
  • الحفاظ على الصحة
  • التسويق الذاتي
  • مقالات عمل حر عامة

التصنيفات

  • الإنتاجية وسير العمل
    • مايكروسوفت أوفيس
    • ليبر أوفيس
    • جوجل درايف
    • شيربوينت
    • Evernote
    • Trello
  • تطبيقات الويب
    • ووردبريس
    • ماجنتو
  • أندرويد
  • iOS
  • macOS
  • ويندوز

التصنيفات

  • شهادات سيسكو
    • CCNA
  • شهادات مايكروسوفت
  • شهادات Amazon Web Services
  • شهادات ريدهات
    • RHCSA
  • شهادات CompTIA
  • مقالات عامة

أسئلة وأجوبة

  • الأقسام
    • أسئلة ريادة الأعمال
    • أسئلة العمل الحر
    • أسئلة التسويق والمبيعات
    • أسئلة البرمجة
    • أسئلة التصميم
    • أسئلة DevOps
    • أسئلة البرامج والتطبيقات
    • أسئلة الشهادات المتخصصة

التصنيفات

  • ريادة الأعمال
  • العمل الحر
  • التسويق والمبيعات
  • البرمجة
  • التصميم
  • DevOps

تمّ العثور على 6 نتائج

  1. لقد أصبح التصميم الشبكي Grid Layout في CSS يتطابق تمامًا مع اسمه، حيث يمكن من خلال CSS بناء تصميم شبكة ببعدين عمودي وأفقي يمكن أن يتم توزيع التصماميم والأغراض الأخرى على العمود والسطر. سنستعرض في هذا الدرس العديد من الأمثلة على التصميم الشبكي، ولكن لنبدأ أولًا بحل المشاكل التي واجهتنا عندما حاولنا بناء flexbox بشكل شبكي. سنبدأ أولًا بتطبيق مثال نقوم فيه ببناء ثلاثة أعمدة ضمن الشبكة، من خلال بناء div يحمل اسم الصف example ونضيف فيه قائمة غير مرقمة ul اسم الصف الخاص بها cards ونضيف بداخلها عناصر من خلال الوسم li كل عنصر هو عبارة عن بطاقة card من البطاقات التي سننظم عرضها بمخطط شبكي grid layout على الشاشة (كود المثال على GitHub) لوضع البطاقات الخمسة ضمن الشبكة السابقة سنضيف مجموعة من تعليمات css للصف cards الذي يحوي البطاقات الخمسة: نضيف خاصية الشبكة لطريقة عرض الحاوية container من خلال التعليمة display:grid. لبناء ثلاثة أعمدة متساوية في العرض نضيف الخاصية grid-template-columns، وهنا سنستعرض وحدة جديدة يمكن استخدامها عند إنشاء الشبكة تسمى وحدة الطول المرن flexible-length unit ونشير إليها بـ fr حيث تمثل أجزاء الفراغ الموجود في الحاوية. في هذا المثال سنقسم الفراغ إلى ثلاثة أعمدة متساوية لذلك نضع 3 أجزاء fr قيمة كل واحد منها 1 والتي تعني تقسيم الفراغ إلى ثلاثة أجزاء متساوية. .cards { margin: 0 -10px; display: grid; grid-template-columns: 1fr 1fr 1fr; } (كود المثال على GitHub) وهذا كل مانحتاجه للحصول على ابن للحاوية يظهر بشكل شبكي، فعلى عكس طريقة بناء flexbox لانحتاج هنا إلى أي قواعد أخرى لإضافتها لخلايا الأبناء المكونة للشبكة حيث تقوم جميع الخلايا بوراثة كل خصائص الأب مباشرة. كما نرى فالعناصر ضمن الشبكة تشكل تصميم متماسك لايحتاج إلى أي تعديلات في عرضهم وبذلك نكون قد وجدنا حلًا لأحد المشاكل التي كانت تظهر لدينا في تصميم flexbox grid باستخدام الخصائص المعرفة للشبكة. الآن في حال أردنا إضافة فجوات بين العناصر المرنة داخل الشبكة في المثال السابق يمكن إضافة هوامش بين العناصر ولكن نحتاج أيضا لإضافة هوامش سلبية لحاوية الشبكة من أجل تصحيح الهوامش على اليمين واليسار غير المرغوب بها. في التصميم الشبكي لـ CSS يوجد خاصية تسمى grid-gap يمكن إضافتها من أجل إعطاء هوامش للعناصر داخل الشبكة. وهي تعبر عن خاصيتين في داخلها هما grid-columns-gap و grid-row-gap التي يمكن أيضًا إعطاؤهما قيم بشكل فردي في حال أردنا الهوامش بين الأعمدة والأسطر مختلفة. لنطبق هذه الخصائص عمليًا ونكتشف طريقة عملها معًا، سأقوم بحذف الهوامش المعطاة للعناصر وستحصل على نفس التصميم الذي أظهرناه في الأعلى، ولكن من دون الفوضى التي تحدثها الهوامش والهوامش السلبية .cards { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 20px; } ملاحظة: بمجرد طباعة الكتاب الذي تم اقتباس هذا المقال منه، قامت إحدى مجموعات العمل على CSS بتغيير اسم الخصائص المتعلقة بـ grid-gap حيث سيتم تغيير اسم خاصية grid-column-gap إلى column-gap وخاصية grid-row-gap إلى row-gap أما خاصية grid-gap التي تجمع بين الخاصيتين السابقتين ستتغير إلى gap. بالإضافة إلى أنه سيتم تغيير تعريف الخصائص التي تحدد أبعاد مخطط المربع الإظهار box alignment وبالتالي يمكن دعم وجود فجوات داخل flexbox كما في الشبكة. ولأن المتصفحات قد تم تحميلها بهذه الخصائص، لذلك سيتم تغيير اسم الخصائص ذات الشكل grid-* إلى الشكل الجديد بالمستقبل القريب. حتى وقت كتابة هذا الدرس لم يقدم أي متصفح دعم لأسماء الخصائص الجديدة، لذلك سأبقي على الأسماء القديمة في هذا المثال ولكن لامانع في حال أردت التأكد يمكن أن تكتب كلا الشكلين من الخاصية في مثالك .cards { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 20px; gap: 20px; } طريقة توضع العناصر حول الشبكة نستطيع الوصول إلى مستويات أكثر تطورًا في طريقة توزيع العناصر ضمن الشبكة مما كان مسموحًا في flexbox من خلال الاستفادة من ميزات الشبكة ثنائية الأبعاد وطريقة توضع العناصر داخلها. الطريقة الأكثر الأساسية هي استخدام أرقام الأسطر. حيث أنه تم ترقيم أسطر وأعمدة الشبكة ورقم البداية هو 1، حيث أن بداية الترقيم تكون حسب اتجاه الكتابة في المستند فعندما يكون العمل داخل الصفحة باللغة الانجلزية مثلًا أي توضع الكتابة من اليسار إلى اليمين LTR عندها العمود رقم 1 هو العمود الموجود في الجهة اليسرى والسطر رقم 1 هو السطر الموجود في الأعلى. أما عندما تكون الكتابة من اليمين إلى اليسار RTL كما في اللغة العربية عندها سيكون العمود رقم 1 هو العمود الموجود في يمين الشبكة. كما ستكون أقصى زاوية في الشبكة (الزاوية اليمينة في اللغات التي يكون اتجاه الكتابة فيها LTR والزاوية اليسارية في اللغات التي اتجاهها RTL) ممثلة بالرقم 1- . لتوضيح هذه الطريقة سنقوم إضافة اسم صف إلى كل عنصر li داخل مستند Html يمثل رقم البطاقة card1, card2… ثم داخل ملف css سنغير خصائص كل صف لتصبح بالشكل. .cards { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 20px; } .card1 { grid-column: 1 / 3; grid-row: 1; } .card2 { grid-column: 3; grid-row: 1; } .card3 { grid-column: 1; grid-row: 2 / 4; } .card4 { grid-column: 2 / 4; grid-row: 2; } .card5 { grid-column: 2 / 4; grid-row: 3; } (كود المثال على GitHub) نستطيع أن نشاهد قوة تنظيم المخطط الشبكي هنا، حيث يمكننا زيادة اتساع الأعمدة والأسطر وهو شيء كان صعبًا حدوثه في المنهج السابق المتبع في التصميم. بالنسبة للون الخلفية للبطاقات نلاحظ أنها مطبقة مباشرة حتى لو كان المحتوى قصير، كما أنه من السهولة تغيير مدى توسع كل كتلة كما يمكننا ترك كتل فارغة فمثلًا إذا قمت بتغيير البطاقة الثالثة card3 لتبدأ عند السطر 3 بدلًا من السطر الثاني عندها سنحصل على خلية فارغة ولايمكن لأي خلية أخرى ضمن الشبكة أن تنزاح إلى الأعلى لتملأ الفراغ وهنا يمكن الاختلاف عن floats التي تحاول أن تطفو إلى الأعلى لتملأ الفراغات المتاحة. كما يوجد طريقة أخرى لتغيير توضع العناصر ضمن الشبكة من خلال تسمية المناطق، حيث يُسمح لك بتوصيف مخططك كما تريد. سنشرح هذه الطريقة من خلال مثالنا، أولًا سنعطي كل بطاقة اسم من خلال الخاصية grid-area. .card1 { grid-area: a; } .card2 { grid-area: b; } .card3 { grid-area: c; } .card4 { grid-area: d; } .card5 { grid-area: e; } ثم نضيف الخاصية grid-template-areas إلى الحاوية للشبكة cards بحيث توصف القيمة المعطاة لهذه الخاصية كيفية توضع العناصر ضمن المخطط فمثلا في حال وصفنا التوضع بالشكل. .cards { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 20px; grid-template-areas: "a a b" "c d d" "c e e"; } (كود المثال على GitHub) سيظهر لدينا ترتيب البطاقات ضمن الشبكة بالشكل. ولكن هناك بعض الملاحظات من المهم تذكرها حول خاصية grid-template-areas وهي: في حال أردنا أن نمدد البطاقة على مساحة أكثر من خلية نقوم بتكرار اسم المنطقة، مثلًا تمتد البطاقة الأولى card1 على مساحة عمودين لذلك قمنا بتكرار المنطقة a مرتين حيث أن شكل المنطقة هو مستطيل (لا نستطيع إلى الآن بناء منطقة على شكل حرف L). لترك مساحات فارغة يتوجب علينا ترك مكان الخلية فارغًا، ويتم ذلك من خلال استخدام محرف النقطة "." مثلًا إذا استبدلنا أول c بنقطة عندها ستبقى خلية فارغة في المخطط. .cards { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 20px; grid-template-areas: "a a b" ". d d" "c e e"; } يمكنك تسمية المناطق بأكثر من محرف في حال كان عدد الأسطر كبير مثلًا كما أنه يمكن أن تمثل الخلية الفارغة بأكثر من نقطة ".." بشرط ألا يفصل بين المحارف أي فراغ. وأخيرًا وجدت أن هذه الطريقة للعمل على مخطط الصفحات تعتبر سهلة جدًا لتحريك العناصر والاستمتاع بوضع النماذج الأولية لصفحاتك أكثر من القلق هو طريقة تنفيذ التصاميم والحصول عليها حيث يمكنك اكتشاف أفضل طريقة لتمثيل شكل الواجهة ثم العودة لبناء محتويات الصفحة والترتيب المنطقي لعرضها. وبهذه الأمثلة التي طرحناها اليوم، تكون قد اكتسبت معرفة كافية تسمح لك باستخدام التصميم الشبكي grid layout لتقرر طريقة عرضك للمحتويات، ولكن تذكر هناك الكثير من الطريق لتخصيص العمل الذي تقوم به حيث يمكنك القيام بالكثير من خلال استخدام CSS. ترجمة للمقال The New CSS Layout, An Excerpt للكاتبة Rachel Andrew
  2. بعد أن أنشأنا أول مشروع في Android Studio وقمنا بتجربة التطبيق على المحاكي سنتعلم الآن أساسيات التعامل مع واجهة المستخدم وكيفية إنشاء العناصر المختلفة بداخلها. طرق إنشاء واجهة المستخدم لتطبيق أندرويد في نظام تشغيل أندرويد هناك طريقتان لإنشاء واجهة المستخدم الخاصة بالتطبيق: التعريف في الملف الخاص بها layout باستخدام لغة XML: وتتميز هذه الطريقة بأنها تقوم بفصل عناصر الواجهة عن الشيفرات البرمجية بلغة الجافا والتي تحدد وظيفة التطبيق الأصلية مما يُسهل عملية تطوير التطبيقات واكتشاف الأخطاء وتصحيحها وتجعل التطبيق أكثر مرونة لدعم أحجام الشاشات المختلفة واللغات المختلفة. تعريف عناصر واجهة المستخدم باستخدام الشيفرات البرمجية بلغة الجافا حيث تتكون الواجهة وقت تشغيل التطبيق وعمله لدى المستخدم. كما يمكنك استخدام هاتين الطريقتين معًا عن طريق تعريف العناصر في ملف layout وباستخدام الشيفرة البرمجية تقوم بتغيير خصائصها بناءً على تفاعل المستخدم مع هذه العناصر، وتلك هي الطريقة التي سنقوم باستخدامها. عناصر واجهة المستخدم تنقسم عناصر واجهة المستخدم إلى نوعين View و ViewGroup: View هو عنصر يقوم برسم شيء ما على الشاشة حيث يستطيع المستخدم التفاعل مع هذا الشيء. ViewGroup هو حاوية غير مرئية تستطيع أن تحمل بداخلها العناصر المكوَنة للواجهة. ويتميز كل نوع من ViewGroup بطريقة فريدة ومختلفة لعرض العناصر الأخرى بداخله وتُسمى العناصر المتواجدة داخل ViewGroup بالأبناء. يمكن أن يحتوي عنصر ViewGroup على عناصر من النوع ViewGroup أيضًا أو من النوع View وذلك للوصول إلى التصميم المنشود لواجهة المستخدم كما توضح الصورة التالية: يوفر أندرويد للمطورين مجموعة من Views و ViewGroup الجاهزة والتي تقوم بالوظائف الشائعة في التطبيقات. أمثلة على ViewGroup Linear Layout: ويتم ترتيب العناصر بداخله في اتجاه واحد إما بشكل أفقي أو رأسي. Relative Layout: ويتم ترتيب العناصر بداخله نسبة إلى عنصر أخر ويتم استخدامه عند صنع واجهة أكثر تعقيدا يصعُب معها استخدام Linear Layout. أمثلة على View Button TextView ImageView أساسيات تصميم الواجهات باستخدام XML توفر لغة XML طريقة سهلة وسريعة لصنع واجهة المستخدم وتتشابه مع طريقة صناعة صفحات الويب باستخدام HTML. كما ذكرنا سابقًا تتواجد الملفات الخاصة بالواجهة في مجلد res/layout بامتداد XML. يجب أن تحتوي ملفات XML على عنصر يسمى root ويعتبر هذا العنصر الحاوية الرئيسية لباقي العناصر ويكون هذا العنصر إما ViewGroup أوView، كما يجب أن يحتوي على XML namespace وهو من المعايير القياسية الخاصة بـ XML. تعريف الـ namespace بسيط وثابت لكل الـ root elements ويكون على النحو التالي xmlns:android="http://schemas.android.com/apk/res/android" وبعد تعريف الـ root element يمكنك بعدها إضافة عناصر أخرى لاستكمال واجهة المستخدم. وفي أغلب التطبيقات يكون الـ root من النوع ViewGroup لقدرته على إضافة أبناء له، على عكس View والذي لا يمكن أن يحتوي على أبناء. يتكون كل عنصر من عناصر XML من وسم الفتح <ElementName>، ووسم الغلق <ElementName/>. وبين وسم الفتح والغلق يتم وضع العناصر الأخرى والتي تعتبر أبناء ViewGroup، وبما أنه لا يوجد للعنصر View لأبناء فيمكن الاستغناء فيه عن وسم الغلق واستخدام وسم الغلق الذاتي </ElementName>. لتوضيح الأمر أكثر سنقوم بصنع واجهة مستخدم مشابهة لتطبيق أهلًا بالعالم Hello World. قم بفتح الملف content_main.xml المتواجد بداخل المجلد res/layout، ثم قم بمسح كافة الشيفرة المكتوبة. بعد عنصر root الخاص بالواجهة أضف عنصر ViewGroup من نوع LinearLayout كالتالي: <LinearLayout> قم بتحديد XML namespace الخاص بالعنصر LinearLayout: <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android > لكل عنصر من عناصر واجهة المستخدم سواء كان View أو ViewGroup العديد من الخصائص والتي يمكن التحكم بها وتخصيصها عن طريق XML أو عن طريق شيفرة الجافا وقد تكون هذه الخصائص خاصة بهذا العنصر فقط أو خصائص مشتركة لدى أكثر من عنصر. ومن الخصائص الهامة تحديد العرض والارتفاع الخاصين بالعنصر، ولتحديد العرض للعنصر نستخدم الخاصية layout_width: android:layout_width="Value" ونستبدل Value بقيمة العرض، وهناك عدة طرق لتحديد قيمة العرض، فيمكن تحديدها عن طريق قيم معرَفة مسبقًا للنظام مثل "match_parent" وتعني أن يكون عرض العنصر نفس عرض العنصر الأب، وإذا كان العنصر الأب هو root فالأب هنا المقصود به شاشة الهاتف. وباستخدام نفس الطريقة يتم تحديد الارتفاع الخاص بالعنصر عن طريق خاصية layout_height: android:layout_height ="Value" ليصبح الشكل النهائي للعنصر: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> </LinearLayout> لاحظ أنه يتم تحديد كافة الخصائص الخاصة بالعنصر داخل وسم الفتح ويتم أيضًا وضع XML namespace معهم. سنقوم بإضافة عنصر أخر للواجهة من نوع View وهو TextView والذي يستطيع أن يحمل بداخله نصًا ويمكن للمستخدم قراءته ولا يمكنه تغييره: <TextView /> سنقوم بتحديد الخصائص الخاصة بهذا العنصر وكما ذكرنا أن خاصتيَ العرض والارتفاع من الخصائص الهامة التي ينبغي تحديدها لكافة العناصر. <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" /> كان من الممكن استخدام قيمة "match_parent" ولكننا قمنا باستخدام "wrap_content" والتي تعني أن يكون العرض أو الارتفاع يشغل القدر المطلوب للنص فقط، أما إذا استخدمنا "match_parent" فسيشغل العنصر كل المساحة الخاصة بالأب والذي هو LinearLayout والذي يشغل مساحة الشاشة كلها كما حددنا ذلك سابقًا. لتحديد النص المطلوب كتابته داخل العنصر، نقوم بإضافة السطر التالي: android:text="Hello World!" هذا هو الشكل الكلي لملف XML: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /> </LinearLayout> الآن قم بتشغيل التطبيق على المحاكي وستجده يعمل بالشكل المطلوب. ملاحظات العنصر TextView متواجد بين وسميَ الفتح والغلق الخاصين بـ LinearLayout ويُعتبر TextView ابنًا لـ LinearLayout. يستخدم العنصر TextView وسم الغلق الذاتي. يتم تحديد الخصائص للعنصر داخل وسم الفتح الخاص به فقط. التطبيق الثاني سنقوم بتطوير المثال السابق واستخدام عناصر أخرى في التطبيق لصنع واجهة مثل الصورة التالية: الاختلاف هنا في إضافة عنصر جديد للواجهة وهو Button. لإضافة هذا العنصر يتم استخدام العنصر </ Button> وإضافته داخل LinearLayout. نقوم بتحديد الطول، الارتفاع والنص الخاص بالزر كالتالي: <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Click me"/> سيظهر الزر بجانب النص السابق: ولتغيير موضع الزر يجب تغيير اتجاه العناصر داخل عنصر LinearLayout، ولتغيير الاتجاه للرأسي بدلًا من الأفقي نستخدم الخاصية orientation: android:orientation="vertical" حيث أن الاتجاه يكون أفقيًا بشكل افتراضي. ليصبح ملف XML على النحو التالي: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Click me"/> </LinearLayout> ملاحظات أي عنصر من النوع View يستخدم وسم الغلق الذاتي لأنه لا يستطيع أن يحتوي على أبناء أو عناصر أخرى بداخله. إذا قمت بكتابة العنصر Button أولًا بداخل LinearLayout ثم العنصر TextView سيتم تغيير الترتيب في الواجهة أيضًا. التطبيق الثالث يحتوي هذا التطبيق على نص "Android Image" وصورة للأندرويد وزر يتم ترتيبها بشكل رأسي. لصنع واجهة المستخدم سنختار LinearLayout كعنصر root وتغيير الاتجاه الخاص به للرأسي. نقوم بعدها بإضافة عنصر TextView وكتابة النص الخاص به، ولكن يمكن ملاحظة أن حجم الخط الخاص بالنص أكبر من الأمثلة السابقة لذا يجب تغيير حجم الخط عن طريق الخاصية textSize: android:textSize="40sp" ويتم تحديد الخط بوحدة "sp" وهي وحدة خاصة في نظام أندرويد لتحديد حجم الخط دون الاعتماد على كثافة البكسل المكوَنة للشاشة ليظهر النص دائمًا بنفس الحجم باختلاف أحجام شاشات الهواتف. لتغيير موضع النص ليكون في منتصف الواجهة نقوم باستخدام خاصية الجاذبية layout_gravity: android:layout_gravity="center" نقوم بإضافة العنصر ImageView لعرض الصور وتحديد الطول والارتفاع كالسابق، ولتحديد الصورة المعروضة بداخله نقوم بوضع الصورة في الملف res/drawable وعرضها داخل العنصر باستخدام الخاصية src: android:src="@drawable/andimg" تستخدم @ للإشارة إلى عنصر داخل الملف وبعدها يتم كتابة اسم الملف وهو drawable ثم تحديد اسم الصورة المتواجدة بداخله. نضيف بعدها العنصر Button ونقوم بتحديد النص الخاص به مع ملاحظة أن العرض الخاص به يستغل كافة مساحة الشاشة وليس على قدر المحتوى فقط. ليصبح ملف XML على النحو التالي: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Android Image" android:textSize="40sp" android:layout_gravity="center" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/andimg"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Say Hi"/> </LinearLayout> التطبيق الرابع نريد في هذا التطبيق صُنع واجهة مركبة كما في الصورة التالية: سيكون الـ root مثل الأمثلة السابقة من النوع LinearLayout ولكن هل اتجاه العناصر بداخله أفقي أم رأسي؟ ستجد العناصر متواجدة في الاتجاهين. لصنع هذه الواجهة سنستخدم أكثر من ViewGroup من النوع LinearLayout ونغير اتجاهاتها لصنع الشكل المطلوب كما في الصورة التالية: سيكون العنصر root من النوع LinearLayout والاتجاه بداخله رأسي، ويحتوي على LinearLayout آخر الاتجاه بداخله أفقي ونضع بداخله العنصرين المتجاورين كما في الصورة السابقة. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> </LinearLayout> </LinearLayout> نضع العنصرين ImageView و EditText داخل العنصر LinearLayout الثاني. نقوم بتحديد العرض والارتفاع واختيار الصورة من ملف drawable للعنصر ImageView مثل ما فعلنا في التطبيق السابق، وبالنسبة للعنصر الآخر EditText والذي يٌستخدم لإدخال نص من المستخدم، نقوم بتحديد عرضه وارتفاعه، بالإضافة إلى عرض نص يعبر عن المحتوى الذي يجب على المستخدم إدخاله باستخدام الخاصية hint: android:hint="Write your name here" نُضيف العنصر الأخير من النوع Button داخل LinearLayout الأول ولوضعه جهة اليمين نستخدم الخاصية layout_gravity: android:layout_gravity="right" ليُصبح ملف XML على الشكل التالي: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher"/> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Write your name here"/> </LinearLayout> <Button android:layout_width="wrap_content" android:layout_height="70dp" android:text="Done" android:layout_gravity="right"/> </LinearLayout> ملاحظات تم تحديد الارتفاع الخاص بـ LinearLayout الثاني بـ "wrap_content" حتى يشغل الارتفاع الخاص بالعناصر فقط ولا يشغل مساحة الشاشة كلها. تم استخدام طريقة مختلفة لتحديد الارتفاع الخاص بـالعنصر Button، وتستخدم هذه الطريقة في حالة لم نرد استخدام القيم المعرَفة داخل النظام مثل "match_parent" أو "wrap_content" واستخدام قيم مختلفة. وتُستخدم الوحدة "dp" كوحدة لتحديد الأبعاد دون الاعتماد على كثافة البكسل المكوَنة للشاشة ليظهر العنصر بنفس الأبعاد دائمًا باختلاف أحجام شاشات الهواتف. التطبيق الخامس هناك طريقة أخرى لإنشاء واجهة المستخدم كما في التطبيق السابق، حيث نقوم باختيار root من النوع RelativeLayout للوصول لنفس الشكل أيضًا كما في الصورة السابقة. في RelativeLayout يتم وضع العناصر نسبة إلى عناصر أخرى متواجدة لذلك ينبغي تحديد لكل عنصر ID مميز له لأن عند وضع عنصرين من نفس النوع (Button مثلا) سيكون اسم كل منهما Button ولا نستطيع عندها التفريق بين الزر الأول أو الثاني وللتفرقة بينهم يتم استخدام خاصية id: android:id="@+id/btn1" ويتم كتابة ID الخاص بالعنصر بعد كلمة /id+@ ويكون هذا ID مميز لهذا العنصر فقط ولا يتشابه معه عنصر آخر. وهناك استخدام آخر لـ ID عند التحكم في العناصر باستخدام شيفرة الجافا. وبهذا يصبح ملف XML على الشكل التالي: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" android:id="@+id/img" /> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Write your name here" android:id="@+id/edttxt" android:layout_toRightOf="@+id/img" /> <Button android:layout_width="wrap_content" android:layout_height="70dp" android:text="Done" android:id="@+id/btn1" android:layout_below="@+id/edttxt" android:layout_alignParentRight="true"/> </RelativeLayout> عند تشغيل التطبيق على المحاكي سيقوم برسم نفس الشكل السابق. ملاحظات تم تحديد ID خاص لكل العناصر. هناك بعض الخصائص التي تحدد موضع كل عنصر بالنسبة لعنصر آخر. مثل الخاصية layout_toRightOf المستخدمة للعنصر EditText وذلك لوضعه بجانب العنصر ImageView جهة اليمين: android:layout_toRightOf="@+id/img" والخاصيتين layout_below و layout_alignParentRight المستخدمتين مع العنصر Button وذلك لوضعه أسفل العنصر EditText و بمحاذاة الشاشة من جهة اليمين: android:layout_below="@+id/edttxt" android:layout_alignParentRight="true" بهذا نكون قد وصلنا إلى نهاية ثاني دروسنا من سلسلة أندرويد للمبتدئين، في انتظار تجربتكم وآرائكم.
  3. إنّ HTML و CSS من أفضل وأسهل الطرق لتقديم المحتوى وأكثرها مرونة. فهي سهلة التعلم وقوية. لكن شيئا واحدا تعجَز فيه هذه اللغات هو الهيكلة المعقدة.، فإذا أردت إنشاء موقع بسيط بهيكلة واضحة فالأمر سهل جدا، ولكن انتقل إلى محتوى متعدد الأعمدة مثلا وشيئا آخر تماما، فهنا تقع نقطة ضعف لغات هيكلة الويب، فيستلزم بنا استخدام طرق ملتوية لإصلاح المشاكل، ناهيك عن توافق هذه الطرق مع مختلف المتصفحات وطريقة ظهورها في كل متصفح. لمجابهة هذه المشكلة يقدم لنا الإصدار الثالث من CSS مجموعة من الحلول البسيطة والسهلة لهذه المشاكل، وهي كالتالي: Multi-column layout Module. Grid layout Module. Flexbox layout Module. وسنتكلم نحن اليوم عن Flexbox (المعروف عموما بـFlex) وهو أكثرهم شيوعا وأكثرهم دعما من قبل المتصفحات (لدى كتابة هذا المقال كل المتصفحات تدعم flex إلى جانب الإصدار العاشر من IE)، وما يقوم به Flexbox هو التحكم بهيكلة مجموعة من العناصر التي تقع تحت حاوي واحد، ويسمح لنا بـ: صف هذه العناصر في سطر واحد بدون تحديد عرض كل واحد منها (واستخدام float) كما يقوم بإضافة العناصر إلى سطر جديد إن لم تكفي المساحة. صّف هذه العناصر على شكل عمود بسهولة كبيرة. محاذات العناصر إلى اليمين أو اليسار أو الوسط (بالنسبة للحاوي). تغيير الترتيب الذّي تظهر به العناصر بدون التعديل على HTML. تحديد المساحة التي يأخذها كل عنصر بدون القلق في حال تغيير حجم الحاوي. والآن لنتفقد المزيد من المميزات. مثال بسيط للعمل به حتى نبدأ باستخدام Flexbox، علينا استخدام مثال بسيط لنشرح به، ومن أجل ذلك اخترنا العمل على هيكلة ذيل صفحة يحتوي على 3 عناصر تجدها في أيّ ذيل صفحة وسنقوم بالتجربة عليها. ما نريد إنجازه هو أن نقوم بصف العناصر الثلاثة بشكل أفقي، وأن نقوم بمحاذاتها عموديا إلى المنتصف وأن يستغل العنصر الأخير ضعف مساحة بقية العناصر، لنقوم بالأمر بالطريقة التقليدية سيتوجب علينا صف العناصر باستخدام float مع تحديد مساحة كل واحدة وحسابها بشكل دقيق حتى يكون هناك ما يكفي من مكان. هذه هي النتيجة النهائية. البدء باستخدام Flexbox الشيء الذي يجب أن نفهمه هو أن Flexbox ليس خاصية واحدة بل مجموعة من الخواص المختلفة، ونستعمل Flexbox عبر تطبيق هذه الخواص على الحاوي والبعض الآخر على العناصر التي نريد التحكم بها. ولنبدأ باستخدام Flexbox نقوم بتطبيق الخاصية التالية على الحاوي: footer { display: flex; } تستطيع أيضا استخدام خاصية flex-flow التي تسمح لك بأن تحدد هل تريد أن تصف العناصر على شكل صف أفقي (row وهي القيمة الإفتراضية )أو على شكل عمود (column) وهل تريد أن تحشر كل العناصر في سطر واحد (nowrap وهي القيمة الافتراضية) أو أن تضيف سطرا جديدا (أو عمودا جديدا) في حال نفاذ المكان (wrap). footer { display: flex; flex-flow: row wrap; } ملاحظة: flex-flow تجمع ما بين الخاصيتين flex-direction (وقيمها هي row , column row-reverse column-reverse) و flex-wrap (قيمها هي wrap no-wrap wrap-reverse). المحور الرئيسي والمحور الجانبي Flexbox تعتمد على مبدأ المحاور في العمل، فهي لا تعمل على أساس محور أفقي ومحور عمودي (حيث ستنعكس الأمور إذا صفننا العناصر عموديا عبر flex-direction : column) بل تستخدم محورا رئيسيا أو Main Axis وهو يتبع الإتجاه الذي حددناه في flex-direction بمعنى أنه من بداية الصفحة إلى نهايتها إذا حددنا flex-direction : row أو من أسفل الصفحة إلى أعلاها إذا حددنا flex-direction : column-reverse أما المحور الجانبي فهو يعامد المحور الرئيسي ويجري في نفس اتجاهه، هذه صورة توضح الأمر. محاذات العناصر يتيح لنا Flexbox محاذات العناصر بأكثر من طريقة، وعبر المحور الرئيسي والجانبي. المحاذات في المحور الجانبي للمحاذات على المحور الجانبي نستخدم خاصية align-items وقيمه هي: flex-start/baseline: تقوم بمحاذات أعلى نقطة من كل عنصر عند بداية المحور الجانبي. flex-end: تقوم بمحاذات نهاية كل عنصر عند نهاية المحور الجانبي. center: تقوم بمحاذات منتصف كل العناصر مع منتصف المحور الجانبي. stretch: تقوم بجعل العناصر تتمدد حتى تملأ مساحة كامل المحور الجانبي. كل هذه القيم واضحة، ولكن إن احتجت فهمها أكثر، جرب التعديل على المثال التالي: See the Pen jPzGPR by Hsoub Academy (@HsoubAcademy) on CodePen. خلاصة أتمنى أن تكون هذه المقالة واضحة وبسيطة لتشرح مجموعة الخواص الرائعة هذه، Flexbox تسمح لنا بالكثير من "المرونة" في التطوير وتتيح لنا أشياء لم نكن قادريين على القيام بها سابقا. ترجمة -وبتصرّف- للمقال Flexbox — Fast Track to Layout Nirvana.
  4. لقد تعرّفنا في الدرس السابق على جداول وورد وتعلّمنا كيفية إنشائها وبعدة طرق، بالإضافة إلى طريقة تحويل النصوص إلى جداول وبالعكس. في هذا الدرس سنتعلّم كيفية تخصيص الجداول أكثر بتعديل تخطيطاتها وتنسيقاتها. تخطيط الجدول توجد جميع الأوامر الخاصة بتخطيط الجدول في تبويب تخطيط Layout الذي يظهر عند تحديد الجدول أو وضع مؤشر الكتابة داخل إحدى خلاياه: إدراج/حذف الصفوف أو الأعمدة لإضافة عمود إلى الجدول، ضع المؤشر داخل العمود الذي تريد إضافة عمود إضافي بجانبه، ثم انقر على Insert Left لإدراج عمود على يسار العمود المحدد، أو Insert Right لإدراج عمود على يمين العمود المحدد: أو، إذا كنت تستخدم إصدار 2013 فما فوق من البرنامج، مرّر مؤشر الفأرة فوق الحد على يمين أو يسار العمود الذي تريد إضافة عمود آخر بجانبه، ثم انقر على أيقونة + التي ستظهر: وبنفس الطريقة تقوم بإضافة الصفوف. ضع المؤشر داخل الصف الذي تريد إضافة صف فوقه أو تحته، ثم انقر على Insert Above لإدراج صف أعلى الصف المحدد، أو Insert Below لإدراج صف أسفل الصف المحدد: أو مرر مؤشر الفأرة فوق حد الصف الذي تريد إضافة صف أعلاه أو أسفله، ثم انقر على أيقونة + التي ستظهر: أما لحذف صف، ضع مؤشر الكتابة داخل إحدى خلايا ذلك الصف، ثم اذهب إلى تبويب: تخطيط Layout > حذف Delete > حذف صفوف Delete Rows ولحذف مجموعة من الصفوف، قم بتحديد خلايا داخل تلك الصفوف (لا يشترط تحديد الصف بالكامل وإنّما خلية واحدة من كل صف) ثم انقر على Delete Rows من قائمة Delete: والأمر نفسه ينطبق على الأعمدة. حدّد خلية داخل العمود (أو مجموعة الأعمدة)، ثم انقر على Delete Columns من قائمة Delete: يمكنك أيضًا الوصول إلى أوامر الإدراج والحذف بالنقر على إحدى خلايا الصف/العمود بزر الفأرة الأيمن: تعديل حجم الخلايا يمكنك التحكم بحجم الخلايا بواسطة الأوامر والخيارات الموجودة في مجموعة حجم الخلية Cell Size في تبويب تخطيط Layout: من قائمة الاحتواء التلقائي AutoFit حدّد الخيار AutoFit Contents لمطابقة حجم الخلايا مع حجم النصوص (أي يصبح عرض العمود وارتفاع الصف أصغر ما يمكن): أو حدّد الخيار AutoFit Window لجعل عرض الجدول ككل يتناسب مع عرض الصفحة (أي ما بين الهوامش) ومن ثم تعديل أبعاد الصفوف والأعمدة وفقًا لذلك: أو الخيار Fixed Column Width لجعل عرض العمود ثابتًا مهما كان حجم النصوص التي يتم إدخالها: لاحظ في الصورة أعلاه كيف يتم إضافة سطر جديد لاحتواء النص كلما قمنا بإضافة نص جديد، وذلك لأننا حدّدنا الخيار Fixed Column Width. إذا كنت ترغب في استخدام عرض محدد للصفوف أو ارتفاع محدد للأعمدة، قم بإدخال قيم الأبعاد في حقولها المخصصة، Height و Width (أو استخدم السهم العلوي لزيادة البعد أو السفلي لتقليله): كذلك يمكنك تغيير أحجام الخلايا يدويًا. ضع المؤشر على حد الصف أو العمود إلى أن يتحول شكله إلى متجهين صغيرين، انقر على الحد (ستلاحظ ظهور خط منقط عبر الصفحة) ثم اسحب إلى الأعلى أو الأسفل لتغيير ارتفاع الصف، أو إلى اليمين أو إلى اليسار لتغيير عرض العمود: لديك أيضًا خيار توزيع الحجم بالتساوي على الأعمدة أو الصفوف المحددة. وهذا الخيار مفيد في توفير الوقت، بدلًا من محاولة تعديل كل صف أو كل عمود على حدة ليصبح حجمها متساوِ. حدّد مجموعة الصفوف/الأعمدة، ثم انقر على Distribute Rows/Distribute Columns: دمج/تقسيم الخلايا في بعض الأحيان تحتاج إلى تحويل مجموعة من الخلايا إلى خلية واحدة، لإدخال عنوان رئيسي لمجموعة من الأعمدة الفرعية مثلًا. للقيام بذلك، حدد مجموعة الخلايا التي تريد دمجها ثم انقر على أمر دمج الخلايا Merge Cells في مجموعة Merge: وبذلك ستتحول مجموعة الخلايا إلى خلية واحدة: أما للقيام بالعملية المعكوسة، أي تحويل الخلية الواحدة إلى مجموعة خلايا، حدد الخلية، ثم انقر على أمر تقسيم الخلايا Split Cells في مجموعة Merge: في مربع الحوار Split Cells قم بتحديد عدد الصفوف وعدد الأعمدة التي تريد تقسيم الخلية إليها ثم انقر على OK: محاذاة النصوص في الخلايا يمكنك التحكم بمحاذاة النصوص بواسطة الأوامر الموجودة ضمن مجموعة Alignment. يمكنك أن تجعل النص يتوسط مركز الخلية، أعلاها، أو أسفلها. وكذلك محاذاته إلى أسفل/أعلى اليمين، أو أسفل/أعلى اليسار. مرر الفأرة فوق كل أمر لمعرفة وظيفته، ثم انقر عليه لتطبيقه (لا يُشترط تحديد النص قبل تطبيق الأمر، يكفي أن تضع المؤشر داخل الخلية التي تحتوي النص): من خيارات المحاذاة الأخرى هو تغيير اتجاه النص وجعله عموديًا. ضع المؤشر داخل الخلية التي تحتوي النص الذي تريد تغيير اتجاهه ثم انقر على أمر اتجاه النص Text Direction: تنسيق الجدول توجد جميع خيارات وأوامر تنسيق الجداول ضمن تبويب تصميم Design السياقي. تعديل نمط الجدول توجد في معرض أنماط الجدول Table Style مجموعة متنوعة من الأنماط الجاهزة التي يمكن الاختيار من بينها، وهي من الطرق السريعة لتغيير تنسيق الجدول. بعض الأنماط بسيطة وبألوان فاتحة، وبعضها تحتوي على تفاصيل أكثر وألوان أكثر. ضع المؤشر داخل إحدى خلايا الجدول، ثم قم بتمرير الفأرة فوق الأنماط في المعرض لمعاينتها على الصفحة بشكل مباشرة، وعندما تحدد النمط المناسب لك، انقر عليه لاختياره: قد تختلف الأنماط باختلاف هيكلية الجدول، إذ يقوم البرنامج بعرض الأنماط التي تتناسب مع تخطيط الجدول المحدد. لاحظ كيف تختلف الأنماط في الصورة أدناه عن الأنماط الموضحة في الصورة أعلاه، وذلك بسبب اختلاف تخطيط الجدول: في مجموعة خيارات أنماط الجدول Table Style Options، ستلاحظ وجود مجموعة من الخيارات، بعضها مؤشر بشكل افتراضي. تختلف الخيارات المؤشرة حسب النمط المطبّق. تستطيع تأشير/إلغاء تأشير هذه الخيارات حسب ما تراه ملائمًا لجدولك. يمكنك مثلًا تأشير الخيار Total Row إذا احتوى جدولك على صف أخير لعرض الإجمالي، أو الخيار Last Column إذا كان الإجمالي في آخر عمودي في الجدول. وسيكون خيار Bended Rows مفيدًا إذا كان عدد الصفوف في جدولك كبيرًا، مما يساعد على سهولة القراءة وتمييز البيانات بسبب تلوين الصفوف الفردية بلون مختلف عن الصفوف الزوجية: تطبيق حدود وتظليل للخلايا إذا لم تكن ترغب في استخدام الأنماط الجاهزة، وتريد أن يكون جدولك بمظهر مخصص أكثر، يمكنك استخدام أوامر الحدود والتظليل Borders & Shading. من مجموعة Borders يمكنك اختيار نمط، سمك ولون الحد، ومن ثم رسمها يدويًا: وكذلك لديك خيار إضافة حدود لجميع جوانب الخلية المحددة، أو لجانب واحد فقط من قائمة Borders: يمكنك استكشاف المزيد من الخيارات والتحكم بها بالنقر على Borders & Shading (أو على أيقونة مشغل Border & Shading الموجدة عند زاوية مجموعة Borders). وفي الحالتين سيُفتح نفس مربع الحوار: من قسم Custom، اختر نمط الحد من قائمة Style، لونه من قائمة Color وعرضه من قائمة Width، واستخدم الأزرار في حقل المعاينة Preview لتطبيق الحدود. ومن قائمة Apply To حدد فيما إذا كنت تريد تطبيق الحدود على الجدول Table، على الخلايا Cell، أو على الفقرة Paragraph. انقر على OK بعد تخصيص جميع خياراتك. ولإضافة لون تعبئة للخلايا استخدم أمر Shading. قم أولا بتحديد الخلية (أو مجموعة الخلايا) التي تريد تعبئتها ثم انقر على تظليل Shading لاختيار أحد الألوان في القائمة (أو غيرها من الألوان بالنقر على More Colors): استكشف خيارات الحدود والتظليل وخصص جداولك ونسّقها بالشكل الذي تريده: من الخيارات المفيدة عند العمل على المستندات بصورة عامة هو إنشاء الجداول بدون حدود. إذ تحتاج في بعض الأحيان إلى إدراج قائمة من النصوص بهيكلية جدول، لكنك لا تريد لها أن تبدو كالجدول. وهذا الأمر يمكن تحقيقه ببساطة بإزالة الحدود. ضع المؤشر داخل أحد خلايا الجدول، ثم انقر على مسح Clear من معرض الأنماط: ستختفي حدود الجدول، لكن ستبقى الخطوط المنقطة ظاهرة، وهذه هي خطوط الشبكة التي يمكنك جعلها مخفية أيضًا بإلغاء تفعيل أمر عرض خطوط الشبكة View Gridlines في تبويب تخطيط Layout: عند إخفاء الحدود وخطوط الشبكة، سيتحول الجدول ليبدو كالنصوص العادية. ولكنّنا قلنا "إخفاء" وليس "إزالة"، أي أنّه في النهاية سيبقى محافظًا على هيكلية وخصائص الجدول. وفي هذه الحالة ما زال بإمكانك تغيير تخطيطه وتغيير تنسيقه من تبويبي Design و Layout، وكما وضّحنا في الفقرات السابقة:
  5. css 101

    في هذا الدّرس من سلسلة تعلّم CSS، سنشرح بعض طرق تغيير طريقة رصف العناصر في المستند، ونتدرّب على ذلك. فهرس السلسلة: مدخل إلى أوراق الأنماط المتتالية (CSS). آلية عمل تعليمات CSS داخل المتصفحات. المحددات (Selectors) في CSS. كيفية كتابة تعليمات CSS يسهل قراءتها. تنسيق نصوص صفحات الويب باستخدام CSS. التعامل مع الألوان في CSS. إضافة محتوى إلى صفحة ويب باستخدام CSS. تنسيق القوائم (Lists) في CSS. تعرف على الصناديق (Boxes) في CSS. رصف العناصر (Layout) في CSS. (هذا الدرس) الجداول (Tables) في CSS. التعامل مع أجهزة العرض المختلفة والمطبوعات في CSS. رصف العناصر (Layout) بالإمكان استخدام CSS لتحديد التأثيرات المرئية المتنوعة الّتي قد تؤثر على ارتصاف العناصر في المستند، بعض هذه التقنيّات متقدّمة المستوى، وهي خارجة عن موضوع هذه السّلسلة. عندما ترغب برصف العناصر في المستند بطريقة متشابهة في جميع المتصفّحات، فإنّ ورقة الأنماط تتفاعل بطرقٍ قد تكون شديدة التّعقيد مع الأنماط المبدئيّة في المتصفّح ومحرّك رصف العناصر، وهذا أيضًا موضوع متقدّم لن نتطرّق له. سنقصر اهتمامنا على تقنيّات بسيطة يمكنك البدء بها. هيكل المستند إن أردت التحكّم بتخطيط المستند، فقد تحتاج إلى تغيير هيكله. ربّما تحوي لغة الرّماز الّتي تستخدمها وسومًا عامّة الأغراض تساعد في الوصول إلى بنية معيّنة، وفي HTML يمكن اللّجوء إلى الوسم <div> لهذا الغرض. مثال في مستندك الّذي تتدرّب عليه، لم يكن للفقرات المُرقّمة تحت العنوان الثّاني عنصر مستقلّ يحويها، ولذلك لم يكن بالإمكان إحاطتها بحدود مستقلّة، فلا يوجد عنصر يمكن استهدافه بمحدّد يحقّق هذه النّتيجة. ولحلّ هذه المشكلة، يمكن إضافة وسم <div> يحيط بالفقرات جميعها، ويكون هذا الوسم فريدًا بمعرّف id: <h3>Numbered paragraphs</h3> <div id="numbered"> <p>Lorem ipsum</p> <p>Dolor sit</p> <p>Amet consectetuer</p> <p>Magna aliquam</p> <p>Autem veleum</p> </div> يمكن الآن كتابة قاعدة تخلق حدودًا حول الفقرات والقائمة: ul, #numbered { border: 1em solid #69b; padding-right:1em; } هكذا تبدو النّتيجة: وحدات القياس استخدمنا وحدة البكسل (px) للقياسات في الدّروس السّابقة، وهي ملائمة لبعض الأغراض كشاشات العرض، ولكنّها قد تعطي نتيجة غير مرغوبة عندما يُغيّر المستخدم الخطّ في المتصفح. قد يكون من الأنسب في حالات عديدة استخدام وحدة مبنيّة على النّسب المئويّة أو em (قياس الخطّ الحالي، أو عرض حرف m في هذا الخطّ بصورة أدقّ)، عندما يغيّر المستخدم حجم الخط، فإنّ تخطيط الصّفحة يتغيّر تلقائيًّا. مثال الحدّ على الجانب الأيسر لهذا النّصّ مُعيّن بالبكسل. الخدّ على الجانب الأيمن مُعيّن بوحدة em. غيّر حجم الخطّ في المتصفّح لديك وشاهد كيف يتغيّر الحدّ الأيمن بينما يبقى الأيسر كما هو: كبّرني! تفاصيل أكثر هناك وحدات أخرى مناسبة للأجهزة المختلفة، سنطّلع على معلومات أكثر في الدّروس القادمة. رصف النصوص هناك خاصّيتان تؤثّران في كيفيّة رصف المحتوى النّصّيّ للعناصر: ‏text-align: ترصف محتوى العنصر، وتقبل إحدى القيم التّالية: left, right, center, justify. ‏text-indent: تدفع السّطر الأوّل من الفقرة بالمقدار المُحدّد. هذه الخواصّ تنطبق على أي محتوى مشابه للنّصوص في العناصر، وليس على النّصوص فقط. تذكّر أنّ القيم المُسندة لهذه الخواص يرثها الأبناء، ولذا قد تحتاج إلى إزالتها من الأبناء لتجنّب نتيجة غير مرغوبة. مثال رصف العناوين في المنتصف: h3 { border-top: 1px solid gray; text-align: center; } وهذه هي النّتيجة: لاحظ أنّ المحتوى المصنّف تحت عنوان ما في HTML لا يقع ضمن العنوان ذاته في بنية المستند، ممّا يعني أن تنصيف العناوين لن يؤدّي إلى تنصيف الفقرات المُدرجة تحت هذه العناوين بشكل مبدئيّ، لأنّها لا ترثها. طفو العناصر (Float) تجبر الخاصّة float العنصر على أن "يطفوَ" إلى اليمين أو إلى اليسار، وهذه طريقة بسيطة للتحكّم بالموضع والحجم. تنساب بقيّة المحتويات في المستند بصورة طبيعيّة حول العنصر الطافي، ويمكن التّحكّم بهذا الانسياب الخاصّة clear على العناصر الأخرى لإبعادها عن العناصر الطّافية. مثال في المستند الّذي تتدرّب عليه، تمتدّ القوائم على كامل عرض النّافذة (وإن كانت نصوص العناصر أقصر من عرضها)، يمكن منع ذلك بجعلها تطفو إلى اليسار. لإبقاء العناوين في مواضعها، يجب أيضًا تحديد الخاصّة clear عليها: ul, #numbered {float: left;} h3 {clear: left;} لتبدو النّتيجة هكذا: (يتطلّب الأمر بعض الحشوة على يمين الصّناديق، لأنّهما الحدود قريبة جدًّا من النّصّ) تحديد مواضع العناصر (Positioning) يمكن تعيين موضع العنصر بإحدى أربع طرق باستخدام الخاصّة position وقيمة من القيم التّالية (تعتبر هذه القيم متقدّمة المستوى، يمكن استخدامها بأساليب بسيطة نسبيًّا، ولهذا أوردناها هنا، ولكنّ استخدامها بطرق معقّدة أمر يتطلّب شيئًا من الخبرة): ‏relative: يُزاح العنصر إلى موضع جديدٍ بالنّسبة لموضع الطّبيعيّ، أي يمكن استخدام هذه الخاصّة لإزاحة العنصر بمقدار معيّن، ويمكن أيضًا استخدام حوافّ العنصر لتحقيق نتيجة مشابهة. ‏fixed: موضع العنصر ثابت، أي بالنّسبة لنافذة المستند، فحتّى عندما يمرّر المستخدم الصّفحة إلى أسفل أو إلى أعلى، يبقى العنصر ثابتًا بالنّسبة للنافذة. ‏absolute: موضع العنصر ثابت بالنسبة لعنصر أبٍ، يُشترط أن يكون العنصر الأب ذا موضع relative أو fixed أو absolute، ويمكن جعل موضع الأب relative بمقدار إزاحة مساوٍ للصفر إذا أردنا استخدام هذه الخاصّة على الابن دون إزاحة الأب. ‏static: القيمة المبدئيّة، استخدمها عند الحاجة للنصّ صراحة على تصفير الموضع. بعد تعيين هذه الخاصّة، استخدم إحدى الخواص التّالية لتعيين إزاحة العنصر (وحجمه): top و right و bottom و left و width و height. مثال لتعيين موضع عنصرين أحدهما فوق الآخر، أنشئ عنصرًا يحويهما في المستند: <div id="parent-div"> <p id="forward">/</p> <p id="back">\</p> </div> ثمّ اجعل موضع الأب relative دون إزاحة، واجعل الابنين absolute: #parent-div { position: relative; font: bold 200% sans-serif; } #forward, #back { position: absolute; margin:0px; /* no margin around the elements */ top: 0px; /* distance from top */ left: 0px; /* distance from left */ } #forward { color: blue; } #back { color: red; } هكذا تبدو النّتيجة: تفاصيل أكثر ضبط مواضع العناصر أمرٌ معقّد. إن كنت تصمّم ورقة أنماط لتعمل في عدّة متصفّحات، فعليك أيضًا أن تأخذ في الحٌسبان الاختلافات في كيفيّة تفسير المتصفّحات للمعيار القياسيّ، وربّما العلل المختلفة في إصدارات كلّ متصفّح. تمرين: رصف العناصر عدّل المستند doc2.html وورقة الأنماط style2.css باستخدام أمثلة من فقرتي "هيكل المستند" و"طفو العناصر" السابق ذكرهما. في مثال طفو العناصر، أضفّ بعض الحشوة لفصل النّصّ عن الحدود بمقدار 0.5em. تمرين عدّل المستند doc2.html مُضيفًا الوسم التّالي قرب نهايته، قبل ‎</body>‎: <img id="fixed-pin" src="Yellow-pin.png" alt="Yellow map pin"> إن لم تحفظ الصّورة التّالية من قبل لديك، فاحفظها الآن في المجلّد الّذي يحوي المستند السّابق: تأكّد من أن الصّورة تظهر في موضعها المُتوقّع بتحديث الصّفحة في المتصفّح. أضف قاعدة لورقة أنماطك تجعل الصّورة في الزاوية العلويّة اليُمنى لمستندك. حدّث الصّفحة في المُتصفّح واجعل نافذته صغيرة، تحقّق من كون الصّورة تبقى في الزّاوية العلويّة اليمنى حتّى عند تمرير الصّفحة للأسفل: (A) The oceans Arctic Atlantic Pacific Indian Southern (B) Numbered paragraphs 1: Lorem ipsum 2: Dolor sit 3: Amet consectetuer 4: Magna aliquam 5: Autem veleum شاهد الحل التّمرين الأوّل تظهر الصّورة في يمين القائمة الثّانية. التّمرين الثاني القاعدة التّالية تُحقّق النّتيجة المطلوبة: #fixed-pin { position:fixed; top: 3px; right: 3px; } ما التالي؟ لقد غطّينا معظم المواضيع الأساسيّة في CSS حتى هذا الدّرس، سنشرح في الدّرس المُقبل المُحدّدات المتقدّمة في قواعد CSS، وبعض التنسيقات الخاصّة بالجداول. ترجمة بتصرّف للدرس Layout من سلسلة Getting started with CSS على شبكة مطوّري Mozilla.
  6. كُنّا في درس سابق قد تحدثنا عن كيفية تخطيط صفحات الويب باستعمال CSS2 وكيف أنّ ذلك لم يكن بالأمر السهل، لذلك في هذا الدرس سوف نقوم بنفس التخطيط ولكن باستعمال تقنيات CSS3 الجديدة. تٌقدّم لنا CSS3 مجموعة من التقنيات والتحسينات لتساعدنا على تخطيط صفحات الويب بشكل أفضل وأسهل ودون الحاجة إلى الكثير من الأكواد كما كان الحال في CSS2. كما أنها مُصممة لتدعم السلوكات المتغيرة/الديناميكية وبالتالي يمكننا القول بأنها " لغة قابلة للبرمجة". دعونا إذًا نرى بعض الخصائص والتقنيات الجديدة التي توفرها هذه اللغة ونحاول استخدامها لدعم حالة الاستخدام التي كنّا قد بدأنا بها في الدرس السابق. دالة ()calc الخاصة بلغة CSS3تُستخدم دالة ()calc الجديدة لحساب القيم بشكل ديناميكي (ضع في الحسبان أن دعم هذه الدالة يختلف من متصفح لآخر). وفي داخل هذه الدالة يمكنك كتابة أي معادلة/تعبير (expression) باستخدام المعاملات الحسابية المعروفة (+، -، *، /). سوف يساعدنا استخدام هذه الدالة على التخلص من الكثير من الأكواد التي كان لا بد منها في CSS2، وفي حالتنا هذه فإنها سوف تساعدنا في تمدد العناصر بشكل أفضل (سوف يصبح استخدام تقنية CSS Expansion التي ذكرناها سابقًا أكثر سهولة). أنظر للكود الموجود في الأسفل: #nav, #subnan { position: fixed; height: calc(100% - 10em); /* replaces */ z-index: 20; }لاحظ أننا استخدمنا الدالة ()calc في الخاصية height وهذا سوف يساعدنا بالحصول على نفس النتيجة التي حصلنا عليها باستخدام CSS2 عندما استخدمنا الخاصيتين top: 6em و bottom: 4em، وبهذا يمكن للأمور أن تصبح أكثر مرونة وسوف نحتاج إلى خاصية واحدة (height مع ()calc) بدل اثنتين (top وbottom). استخدام CSS3 Flexbox في تخطيط الصفحاتتُعتبر Flexbox من الخصائص والتقنيات الجديدة التي ظهرت في CSS3 وهي تجعل من تخطيط الصفحات وترتيب عناصرها أمرًا سهلًا ومتشابهًا في مختلف أحجام الشاشات والأجهزة، وبالتالي فهي مفيدة جدًا عند القيام بتصميم مواقع متجاوبة. وهذه بعض الخصائص والميزات التي تتمع بها Flexbox: تمكننا من موضعة العناصر الأبناء (child elements) بشكل أسهل ويصبح تخطيط الصفحات المعقدة أبسط وأسهل ودون الحاجة إلى الكثير من الأكواد فيصبح لدينا كود أنظف وقابل للقراءة بشكل أفضل.يمكن وضع العناصر الأبناء بأي إتجاه نريده وتصبح أبعاد تلك العناصر مرنة أكثر بحيث يمكنها التجاوب مع مساحة العرض.تستطيع العناصر الأبناء أن تتمدد وتتقلص تلقائيًا لتشغل المساحة الفارغة.كما أنّ Flexbox يقدم مجموعة خاصة به من المفاهيم والمصطلحات، ونذكر بعض منها: Flex container: العنصر الذي يحتوي على الخاصية display بالقيمة flex أو inline-flex بحيث يصبح هذا العنصر هو العنصر الحاوي (الأب) للعناصر التي نريد التعامل معها.Flex item: هو أي عنصر موجود في الـFlex container. (ملاحظة: أي نص موجود بشكل مباشر داخل الـFlex container سيتم احتواؤه داخل anonymous flex item).Axes: أي flexbox يجب أن يحتوي على الخاصية flex-direction بحيث تُحدد هذه الخاصية المحور الرئيسي (main axis) الذي سوف تتموضع حوله الـflex items. ويوجد أيضًا المحور العرضي (cross axis) ويكون هذا المحور عموديًا على المحور الرئيسي.Lines: يمكن للـflex items أن تصطف/تتموضع في خط واحد أو خطوط متعددة وذلك ما تحدده الخاصية flex-wrap.Dimensions: يحتوي flexbox على main size و cross size كبديل عن height وwidth بحيث تُحدد هاتين القيمتين حجم المحور الرئيسي (main axis) والعرضي (cross axis) على التوالي.بعد هذه المقدمة القصيرة عن flexbox يمكننا الآن استخدامها في تخطيط الصفحات. <body class="layout-flexbox"> <header id="header"></header> <div class="content-area"> <nav id="nav"></nav> <aside id="subnav"></aside> <main id="main"></main> </div> <footer id="footer"></footer> </body>نريد في حالة الاستخدام التي نعمل عليها أن تكون العناصر الرئيسية (header ،content ،footer) مصفوفة بشكل عمودي، وبالتالي سوف نستخدم القيمة column في الخاصية flex-direction كما يلي: .layout-flexbox { display: flex; flex-direction: column; }ومع أنّ العناصر الرئيسية يجب أن تكون مصفوفة بشكل عمودي إلّا أنّ العناصر في منطقة المحتوى (nav ،subnav ،main) نريدها مصفوفة بشكل أفقي. وبما أنّ كل flex container يمكن أن يحتوي على خاصية flex-direction واحدة فقط فإننا سنقوم بتعريف العديد من flex containers داخل بعضها البعض حتى يمكننا التحكم في تخطيط الصفحة كما نشاء (أي حتى يصبح بإمكاننا أن نجعل العناصر تصطف كما نريد وألّا نصبح مقيدين باتجاه واحد فقط). ولهذا السبب قمنا بإضافة حاوي (container) آخر (<div class="content-area">) ليحتوي على عناصر nav ،#subnav# و main#. وبهذا يمكن للعناصر الرئيسية أن تصطف بشكل عمودي بينما تصطف عناصر منطقة المحتوى بشكل أفقي. نريد الآن أن نقوم بموضعة الـflex items لذلك سوف نستخدم الخاصية flex وهي اختصار(shorthand) للخصائص flex-grow ،flex-shrink وflex-basis. وهذه الخصائص تُحدد كيف تقوم الـflex items بتوزيع المساحة الفارغة المتبقية بينها، وهذا تعريف بسيط بهذه الخصائص: flex-grow: تُحدد كم يمكن للعنصر (flex item) أن ينمو/يتمدد نسبة للعناصر الأخرى في نفس الحاوي.flex-shrink: تُحدد كم يمكن للعنصر (flex item) أن يتقلص نسبة للعناصر الأخرى في نفس الحاوي.flex-basis: يُحدد الحجم الافتراضي للعنصر (أي حجمه قبل أن ينمو أو يتقلص). عندما نقوم بإعطاء الخاصيتين flex-grow وflex-shrink القيمة "صفر" فإننا نقوم بمنع العنصر من أن يتقلص أو ينمو حتى لو كان هناك مساحة فارغة (أي أنّ حجم العنصر يبقى ثابتًا). وهذا ما سوف نقوم به للترويسة (header) والتذييل (footer) لأننا نريد أن يبقى حجمهما ثابتًا: #header { flex: 0 0 5em; } #footer { flex: 0 0 3em; }وإذا أردنا لعنصر أن يستغل أي مساحة ثابتة فإننا نعطي الخاصيتين flex-grow وflex-shrink القيمة "1" ونعطي الخاصية flex-basis القيمة auto. وهذا ما نريده بالنسبة لمنطقة المحتوى (نريدها أن تستغل أي مساحة فارغة). وكما ذكرنا سابقًا فإننا نريد للعناصر الموجودة داخل <div class="content-area"> أن تصطف بشكل أفقي، لذلك سوف نعطيها الخاصية display: flex حتى يصبح هذا العنصر عبارة عن flex container وسوف نعطيها أيضًا الخاصية flex-direction: row حتى نجعل العناصر الموجودة في داخله (nav ،#subnav# و main#) تصطف بشكل أفقي، وبالتالي نحصل على تنسيقات CSS التالية: .content-area { display: flex; flex-direction: row; flex: 1 1 auto; margin: 1em 0; min-height: 0; }في منطقة المحتوى نريد أن يكون حجم كلا العنصرين nav# وsubnav# ثابت وبالتالي سوف نعطيها الخاصية flex بقيم مناسبة: #nav { flex: 0 0 5em; margin-right: 1em; overflow-y: auto; } #subnav { flex: 0 0 13em; overflow-y: auto; margin-right: 1em; }لاحظ أنني استعملت الخاصية overflow-y: auto وذلك حتى نتعامل مع المحتوى إذا ما تجاوز ارتفاع الحاوي. متصفح Firefox هو من يحتاج لهذه الخاصية. سوف يأخذ العنصر main# المساحة الفارغة المتبقية: #main { flex: 1 1 auto; overflow-y: auto; }كل شيء يبدو جيدًا إلى الآن، لذلك دعونا نقوم بإضافة السلوك المتغير/الديناميكي ونرى ما يحصل. سوف تكون أكواد الجافاسكربت مشابهة لما استخدمناه سابقًا باستثناء أن اسم الـclass للعنصر الحاوي سيكون layout-flexbox بدلًا من layout-classic: $('.layout-flexbox #nav’).on('click', 'li.nav-toggle', function() { $('#nav').toggleClass('expanded'); });سوف نضيف "class expanded" إلى تنسيقات CSS كما يلي: #nav { flex: 0 0 5em; /* collapsed size */ margin-right: 1em; overflow-y: auto; &.expanded { flex: 0 0 10em; /* expanded size */ } }لاحظ أننا هذه المرة لم نحتج إلى أن ندع العناصر الأخرى تعلم بشأن تغير العرض وذلك لأنّ flexbox تعالج الأمر دون تدخل منا. الشيء الوحيد المتبقي هو إخفاء القائمة الفرعية، ولكن احزر ماذا؟ لن نحتاج لكتابة أي أكواد إضافية لأن flexbox سيعلم بشأن المساحة الفارغة وسوف يتكفل بجعل كل شيء يعمل كما هو مطلوب. يوفر لنا flexbox أيضًا مجموعة من الطرق التي تمكننا من توسيط العناصر في الاتجاهين العمودي والأفقي. يمكننا الآن معرفة أهمية وجود مثل هذه التقنية في لغة CSS وكيف أنّها تساعد على جعل الكود أفضل وله القابلية للتطور والتوسع. ولكن على الناحية الأخرى فإنّ هذه التقنيات تحتاج إلى وقت أكثر لإتقانها مقارنة بخصائص CSS الأخرى. تخطيط الصفحات باستخدام CSS3 Gridإذا كنت تعتقد أن flexbox شيء جديد فأنت حتمًا لم تسمع عن CSS3 Grid، فهي ما زالت في مرحلة مبكرة (مرحلة draft) ودعم المتصفحات لها شبه معدوم (يمكنك تفعيلها في متصفح Google Chrome عن طريق الدخول إلى chrome://flags واختيار "experimental Web Platform features"). وفائدتها هي أنها تعمل في طبقة العرض (presentation layer) وبالتالي لن نحتاج إلى معرفة كيفية ظهور العناصر في التوصيف (markup) الخاص بملفات HTML (أي أنّ كل شيء سيتم باستخدام CSS بعض النظر عن ترتيب العناصر في HTML). الفكرة العامة هي أن يكون هناك شبكة تخطيط (grid) مرنة ومُعرّفة بشكل مسبق يمكن أن نستخدمها لموضعة العناصر بداخلها. وكما هو الحال في flexbox فإنها تعمل على مفهوم المساحات الفارغة وتسمح لنا بتعريف إتجاهين (عمودي وأفقي) في نفس العنصر مما يؤدي إلى تقليل حجم الكود وزيادة مرونته. يُقدّم لنا Grid Layout نوعين من الـgrids وهما explicit وimplicit، ولجعل الأمور بسيطة سوف نركز على explicit فقط. وكما هو الحال مع flexbox فإنّ Grid يقدم مجموعة خاصة به من المفاهيم والمصطلحات، ونذكر بعض منها: Grid container: هو أي عنصر يملك الخاصية display بالقيمة "grid" أو "inline-grid" بحيث تتموضع العناصر داخله ويتم محاذاتها بناءً على grid مُعرّف مسبقًا (explicit mode). والـgrid هو عبارة عن مجموعة من الخطوط العمودية والأفقية المتقاطعة والتي تفصل الـGrid container إلى مجموعة من الخلايا (cells). وهناك مجموعتين من الخطوط؛ الأولى لتعريف الأعمدة (columns) والثانية تكون عمودية على هذه الأعمدة لتعريف الصفوف (rows).Grid track: هي المسافة بين خطّين متجاورين، وكل Grid track يتم إعطاؤه دالة تحجيم (sizing function) للتحكم بكيفية نمو كل عمود أو صف وبالتالي التحكم في البعد بين الخطوط المحيطة بكل خط.Grid cell: هي المسافة بين صفّين متجاورين وعمودين متجاورين من خطوط الـgrid، وهو أصغر وحدة من الـgrid يمكن الرجوع والاستناد إليها عندما نقوم بموضعة عناصر الـgrid.Flexible length: هو بُعد يتم تحديده بوحدة fr وهو يُمثّل جزء من المساحة الفارغة في الـGrid container. إليك عناصر HTML التي سوف نستخدمها: <body class="layout-grid"> <header id="header"></header> <nav id="nav"></nav> <aside id="subnav"></aside> <main id="main"></main> <footer id="footer"></footer> </body>لاحظ بأننا في تخطيط الصفحة هذا لن نحتاج إلى عنصر إضافي يعمل كحاوٍ لمنطقة المحتوى كما كان الحال مع flexbox، وذلك لأنّ هذا النوع من تخطيط الصفحات (Grid layout) يسمح لنا بتعريف مساحة كل عنصر في كلا الإتجاهين وبنفس الـGrid container. لنبدأ الآن بإضافة تنسيقات CSS: .layout-grid { display: grid; grid-template-columns: auto 0 auto 1em 1fr; grid-template-rows: 5em 1em 1fr 1em 3em; }قمنا باستخدام الخاصية display: grid على الحاوي (Grid container)، وكذلك استخدمنا الخاصيتين grid-template-columns وgrid-template-rows وهما تمثلان المساحة بين الـGrid tracks. بمعنى آخر، فإنّ هاتين القيمتين لا تمثلان مكان تواجد خطوط الـgrid وإنّما تمثلان مقدار المساحة بين الـGrid tracks. ضع في الحسبان أنّ وحدات القياس يمكن أن تكون أي واحدة من التالية: وحدة طول (length).نسبة مئوية معينة من حجم الحاوي (Grid container).مساحة من المحتوى الذي يحتله العمود أو الصف.جزء من المساحة الفارغة في الـgrid.فعلى سبيل المثال، في الخاصية grid-template-column: auto 0 auto 1em 1fr سيكون لدينا التالي: track واحد لتعريف عمودين بعرض auto (مساحة القائمة الرئيسية nav#).gutter واحد بقيمة "صفر" (الـmargin الخاص بالعنصر subnav# موجود في مستوى العنصر، ويمكن أن يكون موجودًا أو لا وبهذه الطريقة نضمن أن لا يكون هناك gutter مزدوج).track واحد لتعريف عمودين بعرض auto (مساحة القائمة الفرعية subnav#).gutter واحد بقيمة 1em.track واحد بقيمة 1fr للعنصر main# (سوف يأخذ المساحة المتبقية).لاحظ أننا استخدمنا القيمة auto في الـtrack، وهذا يسمح لنا بالحصول على أعمدة ديناميكية بحيث يتم تعريف مكان وحجم خطوط الـgrid بناءً على المحتوى الخاص بها. (سوف نحتاج أيضًا إلى تعريف حجم العنصرين nav# وsubnav# وهذا ما سنفعله بعد قليل). وبطريقة مشابهة، سوف تملك الصفوف الخاصية grid-template-row: 5em 1em 1fr 1em 3em مما يجعل العنصرين header# و footer# ثابتين ويؤدي أيضًا إلى أنّ العناصر الموجودة بين هذين العنصرين سوف تستخدم المساحة الفارغة المتبقية في حين تكون قيمة الـgutters بقيمة 1em. لنرى الآن كيف سنقوم بموضعة العناصر داخل الـgrid الذي قمنا بتعريفه: #header { grid-column: 1 / 6; grid-row: 1 / 2; } #footer { grid-column: 1 / 6; grid-row: 5 / 6; } #main { grid-column: 5 / 6; grid-row: 3 / 4; overflow-y: auto; }إنّ تنسيقات CSS الخاصة بالعنصر header# تُخبرنا بأننا نريد أن تكون الترويسة موجودة بين الخطين 1 و6 (أي العرض كامل) بالنسبة للأعمدة وبين الخطين 1 و2 بالنسبة للصفوف. ونفس الشيء بالنسبة للعنصر footer# فنريده أن يكون موجودًا بين الخطين 1 و6 (أي العرض كامل) بالنسبة للأعمدة وبين الخطين 5 و6 بالنسبة للصفوف. أمّا بالنسبة لمنطقة المحتوى فقد تمّ إعطاؤها الخصائص المناسبة حتى تشغل المساحة التي يفترض بها أن تشغلها. لاحظ أنّ الخاصية grid-column هي اختصار (shorthand) للخاصيتين grid-column-start وgrid-column-end و أنّ الخاصية grid-row هي اختصار للخاصيتين grid-row-start وgrid-row-end. لنعد الآن إلى العنصرين nav# وsubnav#. بما أننا قمنا مسبقًا بوضع هذين العنصرين داخل الـtrack بقيم auto فسوف نحتاج إلى تحديد مساحتهما (نفس الشيء سيكون بالنسبة لـ"expanded" فسوف نقوم فقط بتغيير عرضها وسوف يتكفل Grid بالباقي). #nav { width: 5em; grid-column: 1 / 2; grid-row: 3 / 4; &.expanded { width: 10em; } } #subnav { grid-column: 3 / 4; grid-row: 3 / 4; width: 13em; margin-left: 1em; }يمكننا الآن أن نقوم بتغيير وضع القائمة الرئيسية nav# وإخفاء أو إظهار القائمة الفرعية subnav# وكل شيء سيعمل بشكل جيد وملائم. كما أنّ Grid Layout تسمح لنا باستعمال أسماء مستعارة لتسمية الخطوط حتى نستطيع أن نُغير في الـgrid كما نريد دون أن يؤدي ذلك إلى خلل في الأكواد لأنّها ستكون مربوطة باسم معين وليس بأحد خطوط الـgrid. خاتمةحتى باستخدام تقنيات CSS القديمة فإنّ هناك الكثير مما يستطيع مطورو الويب فعله واستغلاله. ومع ذلك فقد يكون ذلك مهمة ليست سهلة وتحتاج إلى الكثير من الأكواد والتي قد تكون مكررة في كثير من الأحيان. ولكن كما شاهدنا فإنّ CSS3 بدأت تقدم طرق وتقنيات أفضل لتخطيط صفحات الويب والتي بدورها تُسهّل العمل على مطوري الويب. لذلك أعتقد أنه يجب على أي مطور ويب أن يتقن ويتعلم هذه التقنيات حتى يُحسّن من تجربة المستخدم وحتى يقوم بكتابة كود أنظف وأفضل. وهذه المقالة قدمت جزءًا صغيرًا فقط مما يمكن فعله باستخدام تقنيات CSS3 وهناك الكثير مما يجب عليك تعلمه. ترجمة -وبتصرّف- للمقال CSS Layout Tutorial: From Classic Approaches to the Latest Techniques لصاحبه Laureano Martin Arcanio.