دروس Flexbox و Sass Grid: كيفية تبسيط التصميم سريع الاستجابة

نشرت: 2022-03-11

مؤخرًا ، واجهت تحديًا في إنشاء نظام شبكي خاص بي ، وبما أن إعادة اختراع العجلة مفيدة دائمًا كتجربة تعليمية ، فقد قررت ذلك. كنت أعلم أنه سيكون تحديًا مثيرًا للاهتمام ، لكنني فوجئت بمدى سهولة ذلك!

دروس Sass و Flexbox Grid

في هذه التجربة ، سننظر في تخطيطات Flexbox وكيف تسمح بالتطبيقات الرشيقة للتخطيطات دون القيام بأي اختراقات مجنونة. أيضًا ، إذا لم تكن معتادًا على Sass ، فسنرى كيف يعمل ونستخدم بعض أدوات Sass المفيدة. قد تتعلم شيئًا جديدًا عن شبكات CSS مثل تلك الموجودة في Bootstrap.

مقدمة قصيرة جدًا عن Sass و Flexbox

Sass هي في الأساس أداة تسمح لك بتجنب بعض أوجه القصور في CSS ، إنها لغة برمجة نصية تُترجم إلى CSS. يبدو بناء الجملة مألوفًا جدًا إذا كنت تكتب بالفعل أنماط CSS ولكن صندوق الأدوات الخاص به يتضمن متغيرات ومزيجًا لإعادة الاستخدام وتوجيهات if ، for ، each and while وغيرها. أحد أكثر الأشياء فائدة في Sass هو أن أي كود CSS صالح هو Sass صالح ، لذا يمكنك تحويل قاعدة الكود بشكل تدريجي.

مثال بسيط على حلقة for:

 @for $i from 1 through 3 { .a-numbered-class-#{$i} { width: (20 * $i) * 1px; } }

تتكرر هذه الحلقة البسيطة من 1 إلى 3 وتقوم بإنشاء فئات. سيتم تخزين فهرس التكرار بسهولة في $i . يمكننا أيضًا إجراء العمليات الحسابية وطباعة .a-numbered-class-X ثلاث مرات بعرض مختلف في كل مرة. نواتج هذا الرمز:

 .a-numbered-class-1 { width: 20px; } .a-numbered-class-2 { width: 40px; } .a-numbered-class-3 { width: 60px; }

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

يشير Flexbox إلى Flexible Box ، وهو نظام تخطيط CSS3 يضع العناصر ويوزعها ديناميكيًا. إنها أداة قوية للغاية تسمح بتخطيطات مرنة بأقل جهد. لمزيد من التفاصيل حول كيفية تعلم Flexbox ، راجع دليل Chris Coyier الكامل إلى Flexbox.

الشبكة

بالانتقال إلى الشبكة نفسها ، لنبدأ بعناصرها الأساسية. ستكون مستوحاة من عناصر شبكة Bootstrap: الحاويات والصفوف والأعمدة ، كل منها موجود في السابق.

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

  • الكتل ، التي "تغلف كيانًا قائمًا بذاته يكون ذا مغزى من تلقاء نفسه": .block .
  • العناصر ، التي هي "أجزاء من كتلة وليس لها معنى مستقل" والتي يُشار إليها باسم الكتلة وشرطتين تحت السطر والعنصر: .block__elem
  • المُعدِّلات ، مثل "الإشارات على الكتل أو العناصر" ، والتي يتم تمثيلها بشرطتين: .block .block--mod .

الحاويات والصفوف والأعمدة

حاويات

هذا هو العنصر الخارجي للشبكة ، وسوف يحتوي على عناصر الصف الخاصة بنا. هناك نوعان من الحاويات: .container و .container--fluid .

يتم تعريف سلوك .container من خلال كونه 100٪ من العرض أسفل نقطة معينة ، مع وجود أقصى عرض ثابت فوقه وله هوامش متساوية يسارًا ويمينًا:

 $grid__bp-md: 768; .container { max-width: $grid__bp-md * 1px; margin: 0 auto; }

العب معها هنا من خلال توسيع وتقليص نافذة "الإخراج"

بالنسبة إلى حاوية السوائل ، التي يكون عرضها دائمًا بنسبة 100٪ ، فإننا نتجاوز هذه الخصائص بمعدِّل:

 &--fluid { margin: 0; max-width: 100%; }

العب معها هنا.

كان ذلك سهلا! لدينا الآن كلتا الحاويات منفذة. دعنا ننتقل إلى العنصر التالي.

صفوف

ستكون الصفوف هي المنظم الأفقي للمحتوى الخاص بنا.

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

 &__row { display: flex; flex-wrap: wrap; width: 100%; }

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

عناصر الصف

العب معها هنا من خلال توسيع وتقليص نافذة "الإخراج".

بدأت الأمور في التبلور ، لكن هذه ليست شبكة CSS حتى الآن. انها في عداد المفقودين…

الأعمدة

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

لنبدأ ببعض الرياضيات الأساسية. عندما نريد أن يكون لدينا عمود واحد ، يجب أن يكون عرضه 100٪. إذا كنا نريد اثني عشر عمودًا. ثم يجب أن يحتل كل منهما 8.333 ...٪ أو 100/12 من العرض.

باستخدام Flexbox ، لتوزيع المحتوى بهذه الطريقة ، يمكننا استخدام flex-basis .

للتقسيم إلى أربعة أعمدة ، نضيف الآن شيئًا مثل:

 flex-basis: (100 / 4 ) * 1%;

بهذه الطريقة ، يمكننا جعل كل عنصر يشغل 25٪ من العرض - أو أي نسبة نريدها.

العب معها هنا.

لنجعل ذلك أكثر ديناميكية. نظرًا لأننا نريد أن يعكس هذا فئاتنا المحتملة ، .col-1 ، فئة لعمود div سيكون عرضه 8.333٪ نظرًا لأن اثني عشر منها يجب أن تتسع قبل أن تضطر إلى الالتفاف إلى سطر جديد. ستزداد النسبة المئوية طوال الوقت حتى .col-12 ، والتي ستشغل 100٪.

 $grid__cols: 12; @for $i from 1 through $grid__cols { .col-#{$i} { flex-basis: (100 / ($grid__cols / $i) ) * 1%; } }

لتوضيح ما يحدث ، لنفترض أننا نريد تقسيم العرض إلى أربعة أجزاء متساوية. سنحتاج إلى .col-3 لأنه يناسب 4 مرات في 12 ، وهذا يعني أن .col-3 يجب أن يحتوي على 25٪ أساس مرن:

 100 / ($grid__cols / $i) 100 / (12 / 3) = 25

هذا بالفعل بدأ يبدو وكأنه شبكة!

تبدو وكأنها شبكة!

العب معها هنا.

أعمدة عرض الشاشة

نريد الآن أن نكون قادرين على الحصول على عنصر بعرض معين على الهاتف المحمول ولكنه مختلف على الأجهزة اللوحية وما إلى ذلك. سنستخدم نقاط توقف معينة تعتمد على عرض النافذة. ستتفاعل واجهة المستخدم الخاصة بنا مع نقاط التوقف هذه وتتكيف مع التخطيط المثالي الذي يلبي أحجام شاشات الأجهزة المختلفة. سنقوم بتسمية نقاط التوقف حسب الحجم: صغير (sm) ، متوسط ​​(md) وما إلى ذلك ، .col-sm-12 عنصرًا يشغل 12 عمودًا على الأقل حتى نقطة التوقف sm .

دعونا نعيد تسمية .col-* class .col-sm-* . نظرًا لأن شبكتنا ستكون متنقلة أولاً ، فسنطبق خصائصها على جميع أحجام الشاشات. بالنسبة إلى تلك التي نحتاج إلى التصرف بشكل مختلف مع الشاشات الأكبر حجمًا ، فسنضيف الفئة: .col-md-* .

تخيل عنصرًا به .col-sm-12 و .col-md-4 . سيكون السلوك المتوقع أنه أسفل نقطة التوقف "md" (متوسط) سيكون عرضه 100٪ وفوقه سيكون 33.333٪ - وهو أمر شائع جدًا ، حيث قد تحتاج على الهاتف المحمول إلى تكديس العناصر في الأعلى بدلاً من التالي بعضها البعض عندما يكون عرضك محدودًا بدرجة أكبر.

تكديس الأعمدة بعد الوصول إلى نقطة توقف

لهذا ، سنحتاج إلى إضافة استعلام وسائط (تعبير يحتوي على رمز يتم تنفيذه فقط أعلى أو أسفل عرض معين أو على جهاز معين) عند نقطة التوقف وإنشاء أعمدة md كما فعلنا من قبل لـ sm :

 @media screen and (min-width: $grid__bp-md * 1px) { @for $i from 1 through $grid__cols { &__col-md-#{$i} { flex-basis: (100 / ($grid__cols / $i) ) * 1%; } } }

العب معها هنا.

هذا يقترب من شيء مفيد بالفعل. هذا قليل جدًا (احصل عليه؟ إنه ليس جافًا ...) ، لذلك دعونا نجعله أكثر تجريدًا.

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

 @mixin create-mq($breakpoint) { @if($breakpoint == 0) { @content; } @else { @media screen and (min-width: $breakpoint *1px) { @content; } } }

الآن ، دعنا نختتم فقط ما كان لدينا لإنشاء فئات __col في mixin يسمى create-col-classes class واستخدام create-mq mixin.

 @mixin create-col-classes($modifier, $grid__cols, $breakpoint) { @include create-mq($breakpoint) { @for $i from 1 through $grid__cols { &__col#{$modifier}-#{$i} { flex-basis: (100 / ($grid__cols / $i) ) * 1%; } } } }

وهذا كل شيء. لاستخدامه ، نحدد الآن نقاط التوقف الخاصة بنا في خريطة Sass ، ونكررها.

 $map-grid-props: ('-sm': 0, '-md': $grid__bp-md, '-lg': $grid__bp-lg); @each $modifier , $breakpoint in $map-grid-props { @include create-col-classes($modifier, $grid__cols, $breakpoint); }

تم الانتهاء من نظام الشبكة لدينا بشكل أساسي! لقد حددنا فئة .container__col-sm-* التي ستكون هي الفئة الافتراضية ويمكننا تعديل سلوكها على الشاشات الأكبر باستخدام container__col-md-* و container__col-lg-* .

يمكننا حتى أعشاش الصفوف! العب معها هنا.

الشيء الجميل في هذا هو أننا إذا أردنا الآن أن يكون لديه نفس نقاط التوقف مثل Bootstrap v4 ، فسنحتاج فقط إلى القيام به:

 $grid__bp-sm: 576; $grid__bp-md: 768; $grid__bp-lg: 992; $grid__bp-xl: 1200; $map-grid-props: ( '': 0, '-sm': $grid__bp-sm, '-md': $grid__bp-md, '-lg': $grid__bp-lg, '-xl': $grid__bp-xl );

وهذا كل شيء! العب معها هنا.

لاحظ كيف يتخذ Bootstrap منهجًا أكثر اكتمالًا يعتمد على الهاتف المحمول أولاً مما ناقشناه في البداية. أصغر أحجام النوافذ ليس لها لاحقة مثل sm أو md ، والسبب هو أن الفئة المكافئة لـ .container__col-X لن يتم تطبيقها فقط من عرض نافذة من 0 إلى 576 بكسل ؛ إذا لم نكتبه بشكل صريح ، فسيكون هذا العدد من الأعمدة في كل حجم نافذة. خلافًا لذلك ، يمكننا إضافة الفئة .container__col-sm-Y لجعلها عرضًا لأعمدة Y بين نقاط التوقف sm .

إزاحة

ستضيف الإزاحات هامشًا إلى اليسار فيما يتعلق بالعمود السابق. .container__col-offset-4 margin-left: 33.333% على جميع أحجام الشاشات. .container__col-md-offset-4 سيفعل الشيء نفسه لكن فوق نقطة التوقف md .

التنفيذ الآن تافه. نضيف خاصية -offset في الحلقة نفسها ، وننشئ الفئات ، ولكن بدلاً من flex-bases ، نكتب الخاصية margin-left . يتعين علينا إجراء واحد إضافي لـ -offset-0 أيضًا ، حيث قد نرغب في مسح الهامش على الشاشات الأكبر حجمًا:

 @mixin create-col-classes($modifier, $grid-cols, $breakpoint) { @include create-mq($breakpoint) { &__col#{$modifier}-offset-0 { margin-left: 0; } @for $i from 1 through $grid-cols { &__col#{$modifier}-#{$i} { flex-basis: (100 / ($grid-cols / $i) ) * 1%; } &__col#{$modifier}-offset-#{$i} { margin-left: (100 / ($grid-cols / $i) ) * 1%; } } } }

لدينا الآن تعويضات تعمل بكامل طاقتها! العب معها هنا.

قابلية العرض

نريد أحيانًا إظهار / إخفاء عنصر أسفل أو أعلى نقطة معينة. لهذا ، يمكننا إتاحة الفصول الدراسية مثل تلك الموجودة في Bootstrap v4.

على سبيل المثال ، الفئة .hidden-md-up ستخفي أي عنصر بهذه الفئة من نقطة التوقف md إلى الأعلى ؛ على العكس من ذلك ، .hidden-md-down من نقطة التوقف إلى أسفل.

رمز هذا بسيط مرة أخرى: نحن فقط نكرر نقاط التوقف الخاصة بنا وننشئ فئة .hidden-* مع for each نقطة توقف. قمنا بتعديل فئة create-mq لتكون مجردة أكثر ، على الرغم من:

 @each $modifier , $breakpoint in $map-grid-props { @if($modifier == '') { $modifier: '-xs'; } @include create-mq($breakpoint - 1, 'max') { .hidden#{$modifier}-down { display: none !important; } } @include create-mq($breakpoint, 'min') { .hidden#{$modifier}-up { display: none !important; } } }

كملاحظة جانبية ، أليس هذا أحد الاستخدامات القليلة الجيدة لـ !important ؟ لاحظ أن العنصر قد يكون له خصوصية أكبر بشكل تعسفي مع display: block ، لكننا ما زلنا نرغب في إخفائه أسفل نقطة الإيقاف أو أعلاها. إذا كنت لا توافق على هذا النهج ، فأعلمني في التعليقات!

هذا كل شيء: لدينا نظام عرض الآن.

العب معها هنا.

خاتمة

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

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

لقد قمت بإنشاء مستودع GitHub حيث يمكنك إرسال المشكلات أو سحب الطلبات.

ما هي الميزات التي ترغب في رؤيتها مطبقة؟ هل يمكن أن يكون التنفيذ مبسطًا أم أكثر أناقة؟

لا تتردد في إخباري برأيك في التعليقات أدناه.