دروس تخطيط CSS: من الأساليب الكلاسيكية إلى أحدث التقنيات

نشرت: 2022-03-11

يعد إتقان تخطيط الويب دون إتقان CSS أمرًا ممكنًا مثل تعلم السباحة على الأرض الجافة. ولكن على عكس السباحة - التي تظل مهارة تبقى معك مدى الحياة بمجرد إتقانها - فإن إتقان CSS هو عملية لا تنتهي أبدًا لأن CSS نفسها تتطور باستمرار.

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

ولكن مهما كان الأمر ، فإن إتقان CSS هو ضرورة مطلقة لأي مصمم أو مطور ويب قوي. ستوجهك هذه المقالة إلى بعض مبادئ تخطيط CSS الأساسية ، من تقنيات CSS2 الكلاسيكية إلى أحدث أساليب التخطيط في CSS3.

ملاحظة: تستخدم جميع نماذج التعليمات البرمجية في هذه المقالة عناصر HTML5 وبناء جملة Sass. يمكن استنساخ كود العمل الكامل من https://github.com/laureanoarcanio/css-layout-examples.

حالة الاستخدام

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

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

  • التخطيط الأساسي
    • يظل رأس الصفحة وتذييل الصفحة وقائمة التنقل والتنقل الفرعي جميعها ثابتة عند التمرير
    • تحتل عناصر التنقل والملاحة الفرعية كل المساحة الرأسية الخالية
    • يستخدم قسم المحتوى كل المساحة الفارغة المتبقية على الصفحة ويحتوي على منطقة قابلة للتمرير
  • السلوك الديناميكي
    • تعرض قائمة التنقل الرموز بشكل افتراضي فقط ، ولكن يمكن توسيعها لعرض النص أيضًا (ويمكن بعد ذلك طيها لعرض الرموز فقط مرة أخرى)
  • تنويعات التخطيط
    • بعض الصفحات بها تنقل فرعي بجوار قائمة التنقل والبعض الآخر لا

دروس CSS باستخدام تقنيات CSS2 الكلاسيكية

دروس CSS

بالنسبة للمبتدئين ، إليك ترميز HTML5 الذي سنستخدمه مع نموذج التنفيذ الخاص بنا باستخدام CSS الكلاسيكي:

 <body class="layout-classic"> <header></header> <nav></nav> <aside></aside> <main></main> <footer></footer> </body>

تحديد المواقع الثابتة

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

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

أيضًا ، سنقوم بتعيين خاصية width إلى 100٪ والتي توجه المتصفح لاستخدام كل المساحة المتاحة أفقيًا للعنصر.

 #header, #footer { position: fixed; width: 100%; z-index: 20; } #header { top: 0; height: 5em; } #footer { bottom: 0; height: 3em; }

حسنًا ، هذا هو الرأس والتذييل. ولكن ماذا عن #nav و #subnav ؟

توسيع CSS

بالنسبة إلى #nav و #subnav ، سنستخدم أسلوبًا أكثر تعقيدًا بعض الشيء يُعرف باسم توسيع CSS ، والذي يمكن استخدامه عند وضع العناصر على أنها ثابتة (على سبيل المثال ، في موضع ثابت على الصفحة) أو على أنها مطلقة (على سبيل المثال ، عند الموضع المحدد بالنسبة إلى أقرب سلف لها موضعًا أو إلى الكتلة المحتوية).

يتم تحقيق التمدد الرأسي عن طريق تعيين كل من الخصائص top bottom لعنصر ما على قيمة ثابتة ، لذلك سيتم توسيع العنصر رأسياً لاستخدام المساحة الرأسية المتبقية وفقًا لذلك. ما تفعله أساسًا هو ربط الجزء العلوي من العنصر بمسافة محددة من أعلى الصفحة وأسفل العنصر بمسافة محددة من أسفل الصفحة ، بحيث يتمدد العنصر لملء المساحة الرأسية بالكامل بين هاتين النقطتين.

وبالمثل ، يتم تحقيق التوسع الأفقي عن طريق تعيين كل من الخصائص right left ما على قيمة ثابتة ، وبالتالي فإن العنصر سيتوسع أفقيًا لاستخدام المساحة الأفقية المتبقية وفقًا لذلك.

بالنسبة لحالة الاستخدام الخاصة بنا ، نحتاج إلى استخدام التوسع الرأسي.

 #nav, #subnav { position: fixed; top: 6em; /* leave 1em margin below header */ bottom: 4em; /* leave 1em margin above footer */ z-index: 20; } #nav { left: 0; width: 5em; } #subnav { left: 6em; /* leave 1em margin to right of nav */ width: 13em; }

الوضع الافتراضي (ثابت)

يمكن أن تعتمد منطقة المحتوى الرئيسية القابلة للتمرير ببساطة على الوضع الافتراضي (الثابت) ، حيث يتم عرض العناصر بالترتيب كما تظهر في تدفق المستند. نظرًا لأن كل شيء آخر على صفحتنا في موضع ثابت ، فإن هذا العنصر هو العنصر الوحيد الموجود في تدفق المستندات. نتيجة لذلك ، كل ما نحتاج إلى القيام به لوضعه بشكل صحيح هو تحديد خاصية margin لتجنب أي تداخل مع الرأس والتذييل و nav / subnav الثابت:

 #main { margin: 6em 0 4em 20em; }

وبهذا نكون قد استوفينا متطلبات التخطيط الأساسية لحالة الاستخدام الخاصة بنا باستخدام CSS2 ، لكننا ما زلنا بحاجة إلى تلبية المتطلبات الإضافية للوظائف الديناميكية.

السلوك الديناميكي باستخدام تقنيات CSS2 الكلاسيكية

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

دروس CSS2 و CSS3

لنبدأ ببساطة بإضافة 5em إلى عرض قائمة التنقل عندما يتم توسيعها. سنفعل ذلك عن طريق إنشاء فئة CSS "موسعة" يمكننا إضافتها أو إزالتها ديناميكيًا من عنصر قائمة التنقل:

 #nav { left: 0; width: 5em; &.expanded { /* Sass notation */ width: 10em; } }

في ما يلي مثال على رمز JavaScript (في هذا المثال ، نستخدم jQuery) التي يمكن استخدامها للتبديل الديناميكي لقائمة التنقل بين الوضع الموسع والمطوي ، بناءً على قيام المستخدم بالنقر فوق رمز تبديل التنقل:

 $('.layout-classic #nav').on('click', 'li.nav-toggle', function() { $('#nav'').toggleClass('expanded'); });

وبهذا ، يمكن الآن توسيع قائمة التنقل الخاصة بنا أو طيها ديناميكيًا. رائعة.

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

هذا يكشف عن أحد القيود الرئيسية لـ CSS2 ؛ أي أن هناك الكثير من الطرق التي يجب ترميزها بقيم مركزية ثابتة. نتيجة لذلك ، بالنسبة للعناصر الأخرى في الصفحة التي تحتاج إلى إعادة ضبط موضعها لتلائم قائمة التنقل الموسعة ، نحتاج إلى تحديد فئات CSS "موسعة" إضافية بقيم موضع ثابتة أكثر .

 #subnav { left: 6em; width: 13em; &.expanded { left: 11em; /* move it on over */ } } #main { margin: 6em 0 4em 20; z-index: 10; &.expanded { margin-left: 25em; /* move it on over */ } }

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

 $('.layout-classic #nav').on('click', 'li.nav-toggle', function() { $('#nav, #subnav, #main').toggleClass('expanded'); });

حسنًا ، هذا يعمل بشكل أفضل.

تنويعات التخطيط باستخدام تقنيات CSS2 الكلاسيكية

الآن دعنا نتناول متطلبات وجود بعض الصفحات التي تخفي قائمة التنقل الفرعية. على وجه التحديد ، نريد إخفاء قائمة التنقل الفرعية عندما ينقر المستخدم على أيقونة "المستخدمين" في منطقة التنقل الرئيسية.

CSS Layour التعليمي

لذلك أولاً ، سننشئ فئة جديدة "مخفية" تطبق display: none :

 .hidden { display: none; }

ومرة أخرى ، سنستخدم JavaScript (jQuery) لتطبيق فئة CSS "المخفية" على عنصر #subnav عندما ينقر المستخدم على أيقونة المستخدمين:

 $('#nav.fa-user').on('click', function() { $('#subnav').toggleClass('hidden'); });

مع هذه الإضافة ، يتم إخفاء عنصر #subnav بشكل صحيح عندما ينقر المستخدم على أيقونة "المستخدمين" ، لكن المساحة التي شغلها تظل غير مستخدمة ، بدلاً من توسيع العناصر الأخرى لاستخدام المساحة التي #subnav العنصر #subnav.

من أجل الحصول على السلوك المطلوب عندما نخفي عنصر #subnav ، سنستخدم أحد محددات CSS الأقل شهرة ، ولكنها مفيدة للغاية ، والمعروفة باسم محدد الأشقاء المجاور .

مُحدِّد CSS للأشقاء المجاور

يسمح لك محدد الأخوة المجاور بتحديد عنصرين ، وتحديد مثيلات العنصر الثاني التي تتبع مباشرة العنصر الأول المحدد.

على سبيل المثال ، سيحدد ما يلي فقط تلك العناصر ذات المعرف main والتي تتبع مباشرة عنصرًا مع ID subnav :

 #subnav + #main { margin-left: 20em; }

يعيّن مقتطف CSS أعلاه الهامش الأيسر لـ #main إلى 20em إذا وفقط إذا كان يتبع مباشرةً #subnav معروضًا.

ومع ذلك ، إذا تم توسيع #nav (مما يؤدي إلى إضافة الفئة expanded إلى #main أيضًا ، بناءً على الكود السابق) ، فإننا ننقل الهامش الأيسر لـ #main إلى 25em.

 #subnav + #main.expanded { margin-left: 25em; }

وإذا كان #subnav مخفيًا ، فإننا ننقل الهامش الأيسر لـ #main على طول الطريق إلى 6em ليكون بجوار #nav مباشرة:

 #subnav.hidden + #main { margin-left: 6em; }

(ملاحظة: من عيوب استخدام محدد الأشقاء المجاور أنه يجبرنا دائمًا على وجود #subnav في DOM ، بغض النظر عما إذا كان معروضًا أم لا.)

أخيرًا ، إذا كان #subnav مخفيًا وتم توسيع #nav ، فسنقوم بتعيين الهامش الأيسر لـ #main في 11em :

 #subnav.hidden + #main.expanded { margin-left: 11em; }

يتيح لنا ذلك ربط الأشياء معًا دون أي كود JavaScript ثقيل ، ولكن يمكننا أيضًا أن نرى مدى تعقيد هذه الشفرة إذا أضفنا المزيد من العناصر إلى الصفحة. نرى مرة أخرى أنه مع CSS2 ، هناك حاجة إلى الكثير من الترميز الثابت لقيم الموضع من أجل جعل الأشياء تعمل بشكل صحيح.

الاستفادة من CSS3

يوفر CSS3 وظائف محسّنة وتقنيات تخطيط تجعله أسهل في الاستخدام وأقل اعتمادًا على القيم المشفرة. تم تصميم CSS3 بطبيعته لدعم سلوك أكثر ديناميكية وهو ، بهذا المعنى ، "أكثر قابلية للبرمجة". دعونا نفحص بعض هذه القدرات الجديدة من حيث صلتها بحالة الاستخدام الخاصة بنا.

وظيفة CSS3 calc()

يمكن استخدام وظيفة CSS3 calc() الجديدة لحساب قيم خصائص CSS ديناميكيًا (لاحظ ، مع ذلك ، أن هذا الدعم يختلف عبر المتصفحات). يمكن أن يكون التعبير المقدم لوظيفة calc() أي تعبير بسيط يجمع بين العوامل الحسابية الأساسية ( + ، - ، * ، / ) باستخدام قواعد أسبقية عامل التشغيل القياسية.

يمكن أن يساعد استخدام الوظيفة calc() في تجنب الكثير من الترميز الثابت للقيم المطلوبة بواسطة CSS2. في حالتنا ، يمكننا هذا من تحقيق توسع CSS بشكل أكثر ديناميكية. علي سبيل المثال:

 #nav, #subnav { position: fixed; height: calc(100% - 10em); /* replaces */ z-index: 20; }

مع مواصفات height أعلاه باستخدام وظيفة calc() ، نحقق نفس النتيجة كما فعلنا في CSS2 مع top:6em bottom:4em ، ولكن بطريقة أكثر مرونة وتكيفًا ، ودون الحاجة إلى ترميز ثابت top bottom الموضع القيم.

تنسيق CSS3 Flexbox

Flexbox هو تخطيط جديد تم تقديمه في CSS3 (يختلف الدعم عبر المتصفحات). يجعل تخطيط Flexbox من الأسهل ترتيب العناصر على الصفحة بطريقة تتصرف بشكل متوقع عبر أحجام الشاشات ودرجات الدقة والأجهزة المختلفة. لذلك فهي مفيدة بشكل خاص في سياق تصميم الويب سريع الاستجابة.

تشمل الميزات الرئيسية ما يلي:

  • يعد تحديد موضع العناصر الفرعية أسهل بكثير ويمكن تحقيق التخطيطات المعقدة بشكل أكثر بساطة وبتعليمات برمجية أكثر وضوحًا.
  • يمكن وضع العناصر الفرعية في أي اتجاه ويمكن أن يكون لها أبعاد مرنة للتكيف مع مساحة العرض.
  • تقوم العناصر الفرعية تلقائيًا بتوسيع العقد للتكيف مع المساحة الخالية المتوفرة.

تقدم Flexbox مجموعتها الفريدة من المصطلحات والمفاهيم. عدد قليل من هذه تشمل:

  • حاوية مرنة. عنصر مع خاصية display الخاصة به مضبوطة على flex أو inline-flex والتي تعمل كعنصر حاوية للعناصر المرنة.
  • البند المرن. أي عنصر داخل حاوية مرنة. (ملاحظة: يتم تغليف النص الموجود مباشرة في حاوية مرنة في عنصر مرن مجهول.)
  • المحاور . يحتوي كل تخطيط من وحدات Flexbox على flex-directio يحدد المحور الرئيسي الذي يتم على طوله وضع العناصر المرنة. ثم يكون المحور المتقاطع هو المحور العمودي على المحور الرئيسي.
  • خطوط. يمكن وضع العناصر المرنة إما على سطر واحد أو على عدة أسطر وفقًا لخاصية flex-wrap .
  • أبعاد. مكافئ flexbox للارتفاع والعرض هي main size cross size ، والتي تحدد أحجام المحور الرئيسي والمحور المتقاطع للحاوية المرنة ، على التوالي.

حسنًا ، مع هذه المقدمة الموجزة ، إليك الترميز البديل الذي يمكننا استخدامه إذا كنا نستخدم تخطيط Flexbox:

 <body class="layout-flexbox"> <header></header> <div class="content-area"> <nav></nav> <aside></aside> <main></main> </div> <footer></footer> </body>

بالنسبة لحالة الاستخدام الخاصة بنا ، يكون التخطيط الرئيسي (رأس الصفحة ، المحتوى ، التذييل) عموديًا ، لذلك سنقوم بإعداد flexbox الخاص بنا لاستخدام تخطيط العمود:

 .layout-flexbox { display: flex; flex-direction: column; }

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

لهذا السبب أضفنا حاوية إضافية (أطلق عليها اسم منطقة content-area ) #subnav #nav #main و # main. بهذه الطريقة ، يمكن أن يكون التخطيط العام عموديًا ، بينما يمكن تخطيط محتويات منطقة المحتوى أفقيًا.

الآن من أجل وضع العناصر المرنة الخاصة بنا ، سنستخدم الخاصية flex التي تعد اختصارًا لـ flex: <flex-grow> <flex-shrink> <flex-basis>; . هذه الخصائص المرنة الثلاث هي تلك التي تحدد كيفية قيام العناصر المرنة بتوزيع أي مساحة خالية متبقية بينها في اتجاه التدفق ، على النحو التالي:

  • الزيادة المرنة: تحدد المقدار الذي يمكن أن ينمو فيه عنصر ما بالنسبة لبقية العناصر المرنة داخل نفس الحاوية
  • Flex-shrink: يحدد كيف يمكن أن يتقلص العنصر بالنسبة لبقية العناصر المرنة داخل نفس الحاوية
  • الأساس المرن: يحدد الحجم الأولي للعنصر (أي قبل أن يتقلص أو ينمو)

حاويات CSS المرنة: Cross vs main

يعني تعيين flex-grow flex-shrink إلى الصفر أن حجم العنصر ثابت ولن ينمو أو يتقلص لاستيعاب وجود مساحة خالية أكثر أو أقل. هذا ما نقوم به لرأس الصفحة وتذييلها نظرًا لأن حجمهما ثابتًا:

 #header { flex: 0 0 5em; } #footer { flex: 0 0 3em; }

للحصول على عنصر ما يشغل كل المساحة الحرة المتاحة ، قم بتعيين قيمتي flex-grow flex-shrink إلى 1 وضبط قيمة flex-basis على auto . هذا ما نقوم به لمجال المحتوى لأننا نريده أن يشغل كل المساحة الخالية المتاحة.

وكما ذكرنا من قبل ، نريد أن يتم تخطيط العناصر الموجودة داخل content-area في اتجاه الصف ، لذلك سنضيف display: flex ؛ flex-direction: row; . هذا يجعل منطقة المحتوى حاوية مرنة جديدة لـ #nav و #subnav و `# main.

إذن ، هذا ما ننتهي إليه في CSS لمنطقة content-area :

 .content-area { display: flex; flex-direction: row; flex: 1 1 auto; /* take up all available space */ margin: 1em 0; min-height: 0; /* fixes FF issue with minimum height */ }

في منطقة المحتوى ، يحتوي كل من #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: hidden إلى مواصفات CSS هذه للتغلب على تجاوز المحتوى وتجاوز ارتفاع الحاوية. لا يحتاج Chrome في الواقع إلى ذلك ولكن FireFox يحتاج إليه.)

#main المتبقية:

 #main { flex: 1 1 auto; overflow-y: auto; }

يبدو كل هذا جيدًا ، لذا دعنا الآن نضيف سلوكنا الديناميكي إلى هذا ونرى كيف ستسير الأمور.

جافا سكريبت مطابق لما كان لدينا من قبل (باستثناء هنا ، فئة حاوية عنصر CSS التي نحددها هي layout-flexbox بينما كانت في السابق layout-classic ):

 $('.layout-flexbox #nav').on('click', 'li.nav-toggle', function() { $('#nav').toggleClass('expanded'); });

نضيف الفئة expanded إلى CSS على النحو التالي:

 #nav { flex: 0 0 5em; /* collapsed size */ margin-right: 1em; overflow-y: auto; &.expanded { flex: 0 0 10em; /* expanded size */ } }

وفويلا!

لاحظ أنه في هذه المرة لا نحتاج إلى السماح للعناصر الأخرى بمعرفة تغيير العرض ، نظرًا لأن تخطيط flexbox يعالج كل ذلك من أجلنا.

الشيء الوحيد المتبقي إذن هو إخفاء التنقل الفرعي. وتخيل ماذا؟ هذا "يعمل فقط" أيضًا ، دون أي تغييرات إضافية ، باستخدام نفس كود JavaScript كما كان من قبل. يعرف Flexbox المساحة الحرة ويعمل تلقائيًا على جعل تخطيطنا يعمل بدون رمز إضافي. لطيف جدا.

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

تخطيط شبكة CSS3

إذا كان Flexbox Layout في طليعة CSS3 ، فقد يُقال أن تخطيط الشبكة في حافة النزيف. لا تزال مواصفات W3C في حالة مسودة ولا تزال تتمتع بدعم محدود إلى حد ما للمتصفح. (يتم تمكينه في Chrome من خلال علامة "ميزات Web Platform التجريبية" في chrome: // flags).

بعد قولي هذا ، أنا شخصياً لا أعتبر هذا المشروع ثوريًا. بدلاً من ذلك ، كما تنص مبادئ تصميم HTML5: "عندما تكون الممارسة منتشرة بالفعل بين المؤلفين ، ففكر في تبنيها بدلاً من منعها أو ابتكار شيء جديد."

وفقًا لذلك ، تم استخدام الشبكات القائمة على الترميز لفترة طويلة ، لذا فإن CSS Grid Layout الآن يتبع نفس النموذج ، ويقدم جميع مزاياه وأكثر من ذلك بكثير في طبقة العرض بدون متطلبات ترميز.

الفكرة العامة هي أن يكون لديك تخطيط شبكة محدد مسبقًا أو ثابت أو مرن حيث يمكننا وضع عناصرنا. مثل Flexbox ، يعمل أيضًا على مبدأ المساحة الحرة ويسمح لنا بتحديد "الاتجاهات" الرأسية والأفقية في نفس العنصر ، مما يوفر مزايا في حجم الكود والمرونة.

يقدم تخطيط الشبكة نوعين من الشبكات ؛ وهي صريحة وضمنية . للتبسيط ، سنركز على الشبكات الصريحة في هذا.

مثل flexbox ، يقدم تخطيط الشبكة مجموعة فريدة خاصة به من المصطلحات والمفاهيم. عدد قليل من هذه تشمل:

  • حاوية الشبكة. عنصر مع خاصية display الخاصة به مضبوطة على "شبكة" أو "شبكة مضمنة" حيث يتم وضع العناصر المضمنة من خلال تحديد موضعها ومحاذاة شبكة محددة مسبقًا (الوضع الصريح). الشبكة عبارة عن مجموعة متقاطعة من خطوط الشبكة الأفقية والعمودية التي تقسم مساحة حاوية الشبكة إلى خلايا شبكية. هناك مجموعتان من خطوط الشبكة ؛ واحد لتعريف الأعمدة وواحد متعامد لتحديد الصفوف.
  • مسار الشبكة. المسافة بين خطي شبكة متجاورين. يتم تعيين وظيفة تغيير الحجم لكل مسار شبكة ، والتي تتحكم في مدى عرض العمود أو الصف أو ارتفاعه ، وبالتالي مدى تباعد خطوط الشبكة المحيطة.
  • خلية الشبكة. المسافة بين صفين متجاورين وخطي شبكة عمود متجاورين. إنها أصغر وحدة في الشبكة يمكن الرجوع إليها عند وضع عناصر الشبكة.
  • طول مرن. بُعد محدد بوحدة fr ، والذي يمثل جزءًا من المساحة الخالية في حاوية الشبكة.

رسم تخطيطي لشبكة CSS

إليك الترميز البديل الذي يمكننا استخدامه إذا كنا نستخدم تخطيط الشبكة:

 <body class="layout-grid"> <header></header> <nav></nav> <aside></aside> <main></main> <footer></footer> </body>

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

دعنا نتعمق في CSS الآن:

 .layout-grid { display: grid; grid-template-columns: auto 0 auto 1em 1fr; grid-template-rows: 5em 1em 1fr 1em 3em; }

لقد حددنا display: grid; على حاويتنا. يتم تحديد كل من خصائص grid-template-columns grid-template-rows كقائمة من المسافات بين مسارات الشبكة. بمعنى آخر ، هذه القيم ليست موضع خطوط الشبكة ؛ بدلا من ذلك ، فإنها تمثل مقدار المسافة بين مسارين.

لاحظ أنه يمكن تحديد وحدات القياس على النحو التالي:

  • طول
  • نسبة من حجم حاوية الشبكة
  • قياس المحتويات التي تشغل العمود أو الصف ، أو
  • جزء من المساحة الخالية في الشبكة

لذلك مع grid-template-columns: auto 0 auto 1em 1fr; سيكون لدينا:

  • مسار واحد يحدد عمودين للعرض auto (# مساحة #nav )
  • هامش 1 من 0 (يكون هامش #subnav على مستوى العنصر ، حيث يمكن أن يكون موجودًا أم لا ، وبهذه الطريقة نتجنب وجود هامش مزدوج)
  • مسار واحد يحدد عمودين للعرض auto ( #subnav مساحة فرعية)
  • 1 مزراب 1em
  • مسار واحد باستخدام 1fr لـ #main (سيشغل المساحة المتبقية)

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

وبالمثل ، بالنسبة لخطوط الصفوف لدينا grid-template-rows: 5em 1em 1fr 1em 3em; هذا يضبط #header و #footer ليتم إصلاحهما وجميع العناصر بينهما لاستخدام المساحة الخالية المتبقية أثناء استخدام مزاريب 1em .

الآن دعنا نرى كيف نضع العناصر الفعلية التي سيتم وضعها في شبكتنا المحددة:

 #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; }

يحدد هذا أننا نريد أن يكون رأسنا بين خط الشبكة 1 و 6 (العرض الكامل) ، وبين خطوط الشبكة 1 و 2 لصفوفنا. نفس الشيء بالنسبة للتذييل ، ولكن بين آخر سطرين (بدلاً من أول سطرين). والمنطقة الرئيسية معدة بشكل مناسب للمساحة التي من المفترض أن تشغلها.

لاحظ أن خصائص grid-column grid-row هي اختصار لتحديد grid-column-start / grid-column-end grid-row-start / grid-row-end ، على التوالي.

حسنًا ، ارجع إلى #nav و #subnav . نظرًا لأننا سبق أن وضعنا #nav و #subnav في المسار باستخدام القيم التلقائية ، فنحن بحاجة إلى تحديد مدى عرض هذه العناصر (نفس الشيء بالنسبة للوضع الموسع ، نقوم فقط بتغيير عرضه ويتولى تخطيط الشبكة باقي العناصر).

 #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; /* track has gutter of 0, so add margin here */ margin-left: 1em; }

لذا يمكننا الآن تبديل #nav وإخفاء / إزالة #subnav وكلها تعمل بشكل مثالي! يتيح لنا تخطيط الشبكة أيضًا استخدام الأسماء المستعارة لأسطرنا ، لذلك لن يؤدي تغيير الشبكات في النهاية إلى كسر الكود نظرًا لأنه يتم تعيينه على اسم وليس خط شبكة. بالتأكيد أتطلع إلى أن يتم دعم هذا على نطاق واسع من قبل المزيد من المتصفحات.

خاتمة

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

بدأ CSS3 في تقديم تقنيات تخطيط أكثر تعقيدًا ومرونة والتي يسهل برمجتها بشكل كبير وتتجنب الكثير من الملل الذي تسببه مواصفات CSS السابقة.

يعد إتقان هذه التقنيات والنماذج - لكل من CSS2 و CSS3 - أمرًا ضروريًا للاستفادة من كل ما تقدمه CSS من أجل تحسين تجربة المستخدم وجودة التعليمات البرمجية الخاصة بك. تمثل هذه المقالة حقًا مجرد قمة جبل الجليد لكل ما يمكن تعلمه وكل ما يمكن تحقيقه بقوة ومرونة CSS. هل لديك في ذلك!

الموضوعات ذات الصلة: * استكشاف SMACSS: الهندسة المعمارية القابلة للتطوير والوحدات لـ CSS *