البحث في الموقع
المحتوى عن 'flexbox'.
-
تطرقنا في أكاديمية حسوب سابقًا إلى أساسيات الصندوق المرن Flexbox وكيف يُمكن للمطوّر استخدام هذه الخاصية الرائعة في CSS3، وفي هذا المقال سنكمل مع الأساسيات ولكن بتركيز على الأمثلة بعيدًا عن الكلام النظري، وللحصول على الفائدة المطلوبة من هذا الأمثلة من الضروري قراءة المقال الآنف الذكر، وتحديث المتصفح إلى آخر إصدار متوفّر لتطبيق وعرض الأمثلة بالشكل الصحيح. إنشاء حاوية مرنة Flex Containerإن الخطوة الأولى في هيكلة أجزاء الصفحة باستخدام الصندوق المرن flexbox هي إنشاء المستوعبة/الحاوية المرنة flex container، وذلك من خلال إسناد قيمة الخاصية display إلى flex، مع الانتباه إلى إضافة البادئة webkit- من أجل المتصفح ‹‹سفاري›› Safari. .flexcontainer { display: -webkit-flex; display: flex; }توضيع العناصر المرنة Flex Items ضمن صف Rowعناصر الصندوق المرن ما هي إلا أبناء (عناصر فرعية) من الحاوية المرنة flex container، وتتموضع على طول محور رئيسي main axis ومحور جانبي cross axis، المحور الرئيسي هو أفقي افتراضيًا، ولذلك العناصر تتموضع ضمن صف، ومن الممكن تغيير اتجاه المحور الرئيسي من خلال إسناد flex-direction إلى القيمة column، والتي هي افتراضيا row. .flexcontainer { display: -webkit-flex; display: flex; -webkit-flex-direction: row; flex-direction: row; } توضيع العناصر المرنة Flex Items ضمن عمود Column.flexcontainer { display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column; } نقل العناصر المرنة Flex Items إلى الجهة العلويةيَعتمد نقل العناصر المرنة إلى الأعلى على اتجاه المحور الرئيسي main axis، فإن كان عموديًا vertical، يُمكن استخدام الخاصية align-items، وإن كان أفقيًا horizontal، فيُمكن استخدام الخاصية justify-content. .flexcontainer { -webkit-flex-direction: column; flex-direction: column; -webkit-justify-content: flex-start; justify-content: flex-start; } .flexcontainer { display: -webkit-flex; display: flex; -webkit-flex-direction: row; flex-direction: row; -webkit-align-items: flex-start; align-items: flex-start; } نقل العناصر المرنة Flex Items إلى جهة اليمينيَعتمد نقل العناصر إلى جهة اليسار أو جهة اليمين على اتجاه المحور الرئيسي أيضًا، فإن كان flex-direction معينًا إلى row (صف)، عندها يجب استخدام justify-content، وإن كان مُعيّنًا إلى column (عمود)، عندها يجب استخدام align-items. .flexcontainer { display: -webkit-flex; display: flex; -webkit-flex-direction: row; flex-direction: row; -webkit-justify-content: flex-start; justify-content: flex-start; } .flexcontainer { display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column; -webkit-align-items: flex-start; align-items: flex-start; } نقل العناصر المرنة Flex Items إلى جهة اليسار .flexcontainer { display: -webkit-flex; display: flex; -webkit-flex-direction: row; flex-direction: row; -webkit-justify-content: flex-end; justify-content: flex-end; } .flexcontainer { display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column; -webkit-align-items: flex-end; align-items: flex-end; } توسيط كافة العناصر باستخدام Flexboxيُعتبر توسيط العناصر في المستوعبة سواء كان عموديًا أو أفقيًا سهلًا للغاية، كل ما يجب فعله هو إسناد justify-content و/أو align-items إلى القيمة center، ويعتمد الأمر دائمًا على اتجاه المحور الأساسي main axis وذلك فيما إذا كان قيمة الخاصية flex-direction مسندة إلى القيمة row أو column. .flexcontainer { display: -webkit-flex; display: flex; -webkit-flex-direction: row /* works with row or column */ flex-direction: row; -webkit-align-items: center; align-items: center; -webkit-justify-content: center; justify-content: center; } تكبير حجم عنصر مرن Flex Item نسبة إلى العناصر المرنة الأخرىيُمكن تحديد كيف لعنصر مرن أن يزداد أو بنقص بالحجم نسبة إلى باقي العناصر الأخرى في المستوعبة، ولتطبيق ذلك يمكن إسناد القيمة المطلوبة ولكل عنصر ومن خلال الخاصية flex، ففي المثال التّالي، تمّ زيادة حجم أحد العناصر إلى ضعف حجم العنصر الآخر. .bigitem { -webkit-flex: 2 0 0; flex: 2 0 0; } .smallitem { -webkit-flex: 1 0 0; flex: 1 0 0; } التفاف العناصر المرنة إلى صفوف Wrap flex items into rowsتأخرت بعض المتصفحات في دعم هذه الخاصية مثل متصفح Firefox، على العموم من المفترض أن تعمل هذه الخاصية في الوقت الحالي مع جميع المتصفحات بإصداراتها الأخيرة. .flexcontainer { display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; -webkit-justify-content: center; justify-content: center; /* You can set flex-wrap and flex-direction individually */ -webkit-flex-direction: row; flex-direction: row; -webkit-flex-wrap: wrap; flex-wrap: wrap; /* Or do it all in one line with flex flow */ -webkit-flex-flow: row wrap; flex-flow: row wrap; /* tweak the where items line up on the row */ /* valid values are: flex-start, flex-end, space-between, space-around, stretch */ -webkit-align-content: flex-end; align-content: flex-end; } التفاف العناصر المرنة إلى أعمدة Wrap flex items into columns .flexcontainer { display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; -webkit-justify-content: center; justify-content: center; -webkit-flex-flow: column wrap; flex-flow: column wrap; -webkit-align-content: stretch; align-content: stretch; } إزالة المساحة بين الأعمدة أو الصفوف الملتفةتُقدّم الخاصية align-content للمطوّر إمكانية توزيع المساحة حول الأعمدة والصفوف الملتفة wrapped، وذلك بتقديم الخيارات التالية: flex-startflex-endspace-betweenspace-aroundstretchولإزالة المساحة حول الأعمدة الملتفة، يمكن إسناد align-content إلى center. .flexcontainer { display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; -webkit-justify-content: center; justify-content: center; -webkit-flex-flow: column wrap; flex-flow: column wrap; -webkit-align-content: center; align-content: center; } تخصيص مكان العنصر في الحاويةيُمكن للمطوّر التحكم بقيمة align-items لكل عنصر على حِدة باستخدام align-self، وكما يمكن أيضًا استخدام margins لتحريك أي عنصر وفي أي اتجاه من الاتجاهات الأربعة، فمثلًا لتوزيع أعمدة الصّفحة يُمكن تحريك العنصر المرن إلى أقصى يسار مستوعبته من خلال إسناد margin-right إلى القيمة auto. .left { -webkit-align-self: flex-start; align-self: flex-start; } .right { margin-left: auto; } خاتمةخاصيّة الصندوق المرن خاصيّة رائعة ومن الضروري على مطوّر الويب إضافتها إلى أدواته في التطوير خاصة وأنها أصبحت مدعومة بشكل جيّد مع المتصفحات. ترجمة وبتصرّف للمقال The Ultimate Flexbox Cheat Sheet.
-
كُنّا في درس سابق قد تحدثنا عن كيفية تخطيط صفحات الويب باستعمال 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.
-
إنّ 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.
-
سنستعرض في هذا الدرس أمثلةً عن مختلف حالات استعمال flexbox في CSS3، سنجعل الشرح مختصرًا قدر الإمكان وستُوضَّح الفكرة عبر قراءة الشيفرة؛ لذا تمعّن فيها كثيرًا، وانظر إلى ناتجها (لا تغفل أهميّة تجربتها عندك). لمزيدٍ من المعلومات حول flexbox، فانظر درس «تعرف على CSS Flexbox وأساسيات استعماله لهيكلة صفحات الويب». إنشاء حاوية flex أول خطوة لإنشاء تخطيط صفحة يعتمد على flexbox هو إنشاء حاوية flex، وذلك بضبط الخاصية display إلى flex؛ يجدر بالذكر أنَّك ما زلت تحتاج إلى استخدام السابقة -webkit في متصفح Safari: .flexcontainer { display: -webkit-flex; display: flex; } ترتيب عناصر flex في صف عناصر flex هي العناصر الأبناء لحاوية flex، والتي يمكن وضعها على المحور الرئيسي والمحور العمودي عليه. افتراضيًا، المحور الرئيسي هو المحور الأفقي، لذا ستوضع العناصر في صف (row)، يمكنك قلب المحور الرئيسي بضبط الخاصية flex-direction إلى column، حيث أنها مضبوطةٌ افتراضيًا إلى row: /* ضبط الحاوية */ .flexcontainer { display: -webkit-flex; display: flex; -webkit-flex-direction: row; flex-direction: row; } ترتيب عناصر flex على شكل عمود يمكننا ترتيب عناصر flex على شكل عمود بضبط الخاصية flex-dirextion إلى column. .flexcontainer { display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column; } تحريك عناصر flex إلى الأعلى كيفية نقل لعناصر flex إلى الأعلى (top) يعتمد على اتجاه المحور الرئيسي. فإن كان رأسيًا (vertical) فيمكنك ضبط justify-content وإذا كان أفقيًا فاضبط align-items. .flexcontainer { -webkit-flex-direction: column; flex-direction: column; -webkit-justify-content: flex-start; justify-content: flex-start; } أما الشيفرة الآتية: .flexcontainer { display: -webkit-flex; display: flex; -webkit-flex-direction: row; flex-direction: row; -webkit-align-items: flex-start; align-items: flex-start; } فتُنتِج: تحريك عناصر flex إلى بداية الحاوية تحريك العناصر إلى يمين أو يسار الحاوية يعتمد على أمرين، أولهما هو المحور الرئيسي، فلو كانت الخاصية flex-direction مضبوطةً إلى row فاستعمل حينها الخاصية justify-content، وإن كانت مضبوطةٌ إلى column فاستعمل align-items؛ وثانيهما هو اتجاه الصفحة، فلو استعملتَ القيمة flex-start (كما في أمثلتنا) وكان اتجاه صفحتك من اليسار إلى اليمين فستتحرك العناصر إلى اليسار، أما لو كان اتجاه صفحتك من اليمين إلى اليسار فستتحرك العناصر إلى اليمين. .flexcontainer { display: -webkit-flex; display: flex; -webkit-flex-direction: row; flex-direction: row; -webkit-justify-content: flex-start; justify-content: flex-start; } أما الشيفرة: .flexcontainer { display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column; -webkit-align-items: flex-start; align-items: flex-start; } فتنتج: تحريك عناصر flex إلى نهاية الحاوية وكما ذكرنا في القسم السابق، ستتحرك العناصر إلى اليمين عند استخدام القيمة flex-end في حال كانت الصفحة من اليسار إلى اليمين، وستتحرك إلى اليسار عندما تكون الصفحة من اليمين إلى اليسار. .flexcontainer { display: -webkit-flex; display: flex; -webkit-flex-direction: row; flex-direction: row; -webkit-justify-content: flex-end; justify-content: flex-end; } أما الشيفرة: .flexcontainer { display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column; -webkit-align-items: flex-end; align-items: flex-end; } فتنتج: توسيط العناصر التوسيط الأفقي والرأسي للعناصر الموجودة في حاوية flex هو أمرٌ هيّن، فكل ما علينا فعله هو ضبط القيمة center إلى الخاصية justify-content و align-items. لا اختلاف فيما لو كانت الخاصية flex-direction مضبوطةً إلى row أو column. .flexcontainer { display: -webkit-flex; display: flex; -webkit-flex-direction: row /* works with row or column */ flex-direction: row; -webkit-align-items: center; align-items: center; -webkit-justify-content: center; justify-content: center; } والعناصر المرتبة عموديًا: تكبير عنصر flex عددًا معيّنًا من المرات يمكنك أن تُحدِّد كيف يكبر أو يصغر حجم عنصر flex نسبةً إلى عناصر flex الأخرى الموجودة في الحاوية. يمكنك فعل ذلك بضبط الخاصية flex لكل عنصر تريد تكبيره أو تصغيره: .bigitem { /* This will be twice as big as the small item. */ -webkit-flex: 2 0 0; flex: 2 0 0; } .smallitem { -webkit-flex: 1 0 0; flex: 1 0 0; } التفاف عناصر flex لتصبح عدِّة أسطر دعم المتصفحات لالتفاف (wrapping) عناصر flex ما يزال محدودًا إلى متصفحات webkit و IE11، فللأسف لا يدعم firefox هذه الميزة بعد. /* On the flex container */ .flexcontainer { display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; -webkit-justify-content: center; justify-content: center; /* You can set flex-wrap and flex-direction individually */ -webkit-flex-direction: row; flex-direction: row; -webkit-flex-wrap: wrap; flex-wrap: wrap; /* Or do it all in one line with flex flow */ -webkit-flex-flow: row wrap; flex-flow: row wrap; /* tweak the where items line up on the row */ /* valid values are: flex-start, flex-end, space-between, space-around, stretch */ -webkit-align-content: flex-end; align-content: flex-end; } التفاف عناصر flex لتُشكِّل عدة أعمدة لاحظ إسناد القيمة column wrap إلى الخاصية flex-flow في الشيفرة الآتية: .flexcontainer { display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; -webkit-justify-content: center; justify-content: center; -webkit-flex-flow: column wrap; flex-flow: column wrap; -webkit-align-content: stretch; align-content: stretch; } إزالة المسافة بين عناصر flex التي تشكل أسطرًا وأعمدةً تسمَح لك الخاصية align-content بضبط قيم للتحكم بكيفية توزيع المسافة بين الأسطر أو الأعمدة. الخيارات المتاحة لك هي flex-start و flex-end و space-between و space-around و stretch. فلإزالة المسافة بين الأعمدة الملتفة اضبط الخاصية align-content إلى center: .flexcontainer { display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; -webkit-justify-content: center; justify-content: center; -webkit-flex-flow: column wrap; flex-flow: column wrap; -webkit-align-content: center; align-content: center; } تثبيت أحد العناصر إلى أحد أطراف حاوية flex يمكنك التحكم بقيمة align-items لمختلف العناصر الموجودة في حاوية flex عبر الخاصية align-self. يمكنك أيضًا ضبط هوامش (margins) بقيم معيّنة لتحريك العناصر إلى الأعلى أو الأسفل أو إلى اليمين أو اليسار؛ فلو كانت عندك حاوية تُرتَّب فيها العناصر على شكل عمود، وأردتَ نقل أحد العناصر إلى يسار الحاوية، فاضبط الخاصية margin-right إلى auto: /* On the flex item to pin */ .left { -webkit-align-self: flex-start; align-self: flex-start; } .right { margin-left: auto; } ترجمة -وبتصرّف- للمقال The Ultimate Flexbox Cheat Sheet لصاحبه Sean Fioritto