تموضع العناصر في CSS

الخاصية Float في CSS

الخاصية ذات النتائج غير المتوقعة والأطوار المتقلبة في CSS

تقديم

كتب هذا المقال أشرف عبدالدايم مطور واجهة المستخدم في TieLabs سابقاً، 95% من كود CSS الموجود في قالب جنة من كتابة أشرف :)

في الجزء السابق من هذة السلسلة، قمنا بشرح خصائص الـ box model الخاصة بالعناصر، كيفية تحديد خلفية العناصر، الحدود، الهوامش الداخلية والخارجية للعناصر، والتحكم في أبعاد العناصر. وفي الدرس السابق في هذا الجزء تعرفنا على كيفية تدفق العناصر في صفحة الويب، وأن العناصر ذات النوع Block تدفق رأسياً بشكل إفتراضي، حيث أنها تتمد في كل المساحة الأفقية المتاحة لها في الصفحة، وتحدثنا عن عدم كفاية هذا النوع الإفتراضي من التدفق للعناصر في صفحة الويب، حيث تحتاج تصميمات/تخطيطات الويب المختلفة إلى ظهرو العناصر بجانب بعضها البعض لإستغلال أكثر للمساحة في صفحة الويب.

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

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

بإختصار، بعد استخدام الخاصية float نكون قد بدأنا للتو في بناء صفحات ويب حقيقة.

مثال تطبيقي

دعنا نقوم بإنشاء مثال نوضح عليه التطبيقات المختلفة للخاصية float على مدار هذا الدرس، بل هو عبارة عن مشروع بسيط، في الأمثلة السابقة كنا نقوم بتطبيق بعض خصائص CSS على عناصر المحتوى في HTML لكن الآن ولأننا نريد توضيح كيفية بناء تخطيط صفحة الويب بإستخدام الخاصية float سنقوم بتطبيق الخصائص على عناصر <div> فارغة، في النهاية نريد الحصول على تخطيط لصفحة الويب مثل الشكل التالي،

هذا التخطيط يختلف تماماً عن كل الأمثلة السابقة.

في البداية قم بإنشاء مجلد جديد على جهاز الحاسب لديك، وليكن بالإسم floats وقم بإنشاء ملف HTML جديد بالإسم floats.html:

قم بتطبيق المثال التالي:

See the Pen CSS Float | example #1 by Ashraf Reda (@ashrafreda) on CodePen.

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

بعد فتح الملف floats.html كانت النتيجة كما ترى بالأعلى، لا شيئ! نعم لأن العناصر الفارغة يكون ارتفاعها صفر.

دعنا الآن نقوم بإضافة قاعدة مهمة لملف Style.css ، إعادة ضبط العناصر حتى تظهر بنفس الشكل على جميع المتصفحات:

المحدد * (النجمة) يعني اختيار جميع العناصر في صفحة الويب، ونقوم بالتأكيد على أن جميع العناصر ليس ديها هوامش داخليه وخارجية بإستخدام الخواص padding و margin والإعلان الثالث في القاعدة السابقة هو أهم الإعلانات العامة في ملف التنسيق على الإطلاق box-sizing: border-box; الخاصية box-sizing كما تم شرحه سابقاً تقوم بتغير طريقة تحجيم أبعاد العناصر في CSS وهنا قمنا بتطبيق القيمة border-box أي أن الهوامش الداخلية padding والحدود border ستكون ضمن الأبعاد التي سيتم تحديدها للعناصر.

دعنا نقوم بإضافة بعض التنسيقات styles (خلفيات، أبعاد) للعناصر الذي قمنا بإضفاتها، كي تظهر بشكل مميز في صفحة الويب:

See the Pen CSS Float | example #2 by Ashraf Reda (@ashrafreda) on CodePen.

هذا هو الشكل الإفتراضي لظهور العناصر في صفحة الويب، بدون استخدام أي خاصية من خواص تموضع العناصر.

لاحظ أن العناصر قامت بالتمديد في كل المساحة الأفقية المتاحة لها 100% وبالتالي ظهرت العناصر بشكل رأسي أسفل بعضها البعض.

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

دعنا الآن نلقي نظرة عماذا سيحدث عندما نقوم بتقليص عرض العناصر، الآن سنقوم بتحديد عرض القائمة الجانبية كالتالي:

بذلك سيتقلص عرض القائمة الجانبية من ١٠٠٪ إلى 200px في حين أن العناصر الأخرى ستظل متمددة بالعرض الكامل:

See the Pen CSS Float | example #3 by Ashraf Reda (@ashrafreda) on CodePen.


الخاصية float في CSS تمكننا من التحكم في كيفية تموضع/ محاذاة العناصر أفقياً بجانب بعضها البعض.

دعنا نقوم بتطبيق الخاصية float على القائمة الجانبية لمحاذاتها جهة اليسار هكذا float:left

See the Pen CSS Float | example #4 by Ashraf Reda (@ashrafreda) on CodePen.

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

أيضاً يمكنك محاذاة عنصر القائمة الجانبية ناحية اليمين، أو إذا كنت تريد تجاوز قيمة float التي تم تعينها للعنصر من قبل وإعادة العنصر للتدفق الإفتراضي في صفحة الويب بإستخدام القيمة none.
إذا هناك ثلاثة قيمة للخاصية Float:

أما في حالة محاذات العنصر في المنتصف، نستخدم طريقة Auto Margins الهوامش التلقائية على جانبي العنصر هكذا:

إذاً الآن لدينا الآدوات اللازمة لمحاذاة العناصر ذات النوع block، إستخدام الخاصية float للمحاذاة جهة اليسار واليمين، واستخدام الهوامش التلقائية margin: 0 auto; للمحاذاة في المنتصف:

 لاحظ أن الخاصية float تستخدم لمحاذات العناصر ذات النوع block فقط، أما بالنسبة للعناصر inline نستخدم الخاصية text-algin كما تم شرحه من قبل.

محاذاة العناصر داخل العنصر الأب parent

تقوم الخاصية float بمحاذاة العناصر لليمين أو للييسار داخل العنصر الأب. في المثال التطبيقي الذي بدأناه في بداية المقال،، جميع العناصر موجودة داخل عنصر أب <div class=”site-wrapper”> وهذا العنصر يتمدد بكامل عرض نافذة المتصفح، والقائمة الجانبية موجودة داخل العنصر الأب هذا، لذلك عندما قمنا بمحاذاتها جهة اليسار كانت على أقصى يسار نافذة المتصفح.

ماذا لو أن العنصر الأب لديه أبعاد محدودة، إلى ماذا سيتم محاذاة العناصر الأبناء؟ دعنا نلقي نظرة على المثال التالي:

 هنا قمنا بتقليص عرض العنصر الأب <div class=”site-wrapper”> لـ 900px ومحاذاته في منتصف الصفحة بإستخدام الهوامش التلقائية ;margin: 0 auto ، وبذلك تمت محاذاة جميع العناصر الأبناء في منتصف صفحة الويب.

هل لاحظت أن القائمة الجانبية انتقلت من أقصى يسار نافذة المتصفح لأقصى يسار العنصر الأب؟ وهكذا، فإن العناصر الأبناء يتم محاذاتها بالنسبة للعنصر الأب.

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

تطبيق الخاصية float على عناصر متعددة في صفحة الويب

في الخطوة السابقة، تظهر القائمة الجانبية .sidebar ويكأنها داخل العنصر المجاور لها .content الآن دعنا نقوم بتقليص عرض مساحة المحتوى أيضاً:

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

تظهر بجانب القائمة الجانبية.sidebar لحل هذة المشكلة يجب أن نقوم بمحاذاة مساحة المتحوى جهة اليسار أيضاً float:left

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

يمكنك الأن تجربة القيم المختلفة للخاصية float على القائمة الجانبية ومساحة المحتوى لتحصل على تخطيطات مختلفة لصفحة الويب.

هذا جيد، أليس كذلك؟ :) مممممم
الأ تلاحظ شيئ في الصورة السابقة؟ أين العنصر <footer> ؟ أليس هو الذي يظهر أسفل عنصر القائمة العلوية مباشرةً؟! نعم إنه هو.

لو تذكر أننا ذكرنا في بداية الحديث عن الخاصية float أنها تقوم بحذف العنصر من التدفق الإفتراضي لصفحة الويب، لذلك ظهر العنصر <footer> أسفل عنصر القائمة العلوية مباشرةً، لأن العناصر.sidebar و.content خارج تدفق العناصر في الصفحة.

لتتضح هذة المشكلة جيداً قم برسم حدود باللون الأحمر حول العنصر الأب.site-wrapper

هل تلاحظ ما حدث، على الرغم من أن العنصر .site-wrapper هو الحاوي لجميع العناصر في الصفحة إلا أن الحد تم رسمه حول العنصرين (القائمةالعلوية.menu، وحاشية الموقع .footer ) وكان من المتوقع أن يتم رسم الحد حول جميع العناصر، لكن هذا لم يحدث، تذكر دوماً العناصر المُطبق عليها خاصية float تكون خارج التدفق، تقوم بإخلاء المكان الإفتراضي لها في الصفحة وتذهب حيث تريدها أن تذهب على جهة اليمين أو اليسار. لذلك فإن العنصر الأب .site-wrapper لا يحتوي الإ على عنصرين فقط في الأماكن الأساسية لهم في صفحة الويب (التدفق الإفتراضي) عنصري القائمة العلوية وحاشية الموقع.

هناك حلين لهذة المشكلة:

  1. استخدام الخاصية clear مع القيمةboth للعنصر.footer .
  2. استخدام الخاصيةoverflow مع القيمة hidden للعنصر الأب .site-wrapper .

الحل الأول : الخاصية Clear

تحدد الخاصية clear ما إذا كان العنصر سيعيش بجوار العناصر العائمة (المُطبق عليها الخاصية float ) أو أنه سيتحرك أسفل منها متجاهلاً جميع العناصر العائمة قبله، وتطبق الخاصية clear على العناصر ذات النوع block سواء كانت عائمة ( floated ) أو غير عائمة.

الآن بإمكاننا تطبيق الخاصية Clear على عنصر الـ footer كي يظهر في مكانة الإفتراضي أسفل العناصر العائمة:

لاننا نريد ظهور العنصر <footer> أسفل العناصر العائمة على كلتا الجهتين اليمين واليسار، قمنا بتطبيق القيمة both ، لكنه بإمكانك في أمثلة أخرى استخدام القيم left أو right للظهرو أسفل العناصر العائمة على جهة اليسار أو اليمين.

مشكلة وحلها بإستخدام الخاصية Clear

دعنا نقوم بإنشاء مثال جديد لنحل مشكلة من أشهر المشاكل التي تسببها الخاصية float وكيف تقوم الخاصية clear بحلها، في الفترة الأخيرة انتشر تخطيط الشبكة في مواقع كثيرة على شبكة الإنترنت، أي تراص العناصر بجانب بعضها البعض لتكون في النهاية شبكة، كل عنصر يحتوي على أنواع مختلفة من المحتوى.

في الصور السابقة تتراص المربعات بجانب بعضها البعض بإستخدام الخاصيةfloat: left; كل مربع يوجد بداخله محتوى مختلف عن المربعات الأخرى، ماذا لو أن المربع الثاني لديه محتوى أكثر من المربعات التي بجواره؟


كانت النتيجة غير متوقعة بالمرة، حيث تم إزاحة المربعات ٥ , ٦ بعيداً إلى الأسفل.

وبعد تطبيق الخاصية clear ستقوم بإظهار المربعات بشكل أفضل، تذكر أن جميع المربعات/العناصر عائمة جهة اليسار ( float: left; ) لذلك إذا أخبرنا المربع رقم ٤ بالظهور أسفل العناصر العائمة ستظهر جميع العناصر بشكل أكثر تنسيقاً:

نعود للمثال الأساسي في هذا المقال:

توقفنا عند مشكلة ظهور العنصر <footer> أسفل عنصر القائمة العلوية مباشرةً، متاجهلاً العناصر العائمة،


كي يظهر العنصر <footer> أسفل العناصر العائمة، نقوم بتطبيق الخاصية clear:both; على العنصر <footer> ستكون النتيجة كالتالي:

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

 

الحل الثاني : الخاصية overflow

ماذا لو قمنا بإخراج العناصر (القائمة العلوية Menu ،حاشية الموقع Footer) من حاوي العناصر .site-wrapper كالتالي:

حيث أن العناصر .footer و .menu خارج حاوي العناصر .site-wrapper ذات العرض الثابت، فإنهما مثل أي عنصر من النوع block سيقوموا بملئ كافة المساحة المتاحة في نافذة المتصفح أفقياً. لاحظ أيضاً إرتفاع الحاوي .site-wrapper على الرغم من أن الخاصية clear مازالت تعمل مع العنصر <footer> وتجلعه يظهر أسفل حاوي العناصر.site-wrapper الذي يحتوي على العناصر العائمة إلا أن ارتفاع الحاوي.site-wrapper سيكون صفر:

هذا بالطبع كما قلنا، أن العناصر داخل الحاوي .site-wrapper عناصر عائمة ( Floated ) لذلك لن يتم حسابها في إرتفاع العنصر الحاوي، كما أن إزاحة العنصر <footer> خارج الحاوي .site-wrapper قام بإلغاء حل الخاصيةclear

 

إقتصاص المحتوى (Hiding Overflow)

إزاحة العناصر العائمة بإستخدام الخاصية clear تقوم بإصلاح مشكلة إرتفاع العنصر الحاوي فقط إذا كان العنصر المُضاف إليه الخاصية Clear داخل العنصر الحاوي. لكن في المثال السابق العنصر <footer> خارج الحاوي .site-wrapper لذلك يلزمنا طريقة أخرى لحل مشكلة إرتفاع الحاوي، تمكننا من حساب ارتفاع العناصر العائمة ضمن ارتفاع الحاوي.

الحل هو الخاصيةoverflow

بإضافة الإعلان overflow:hidde; للعنصر الحاوي .site-wrapper تقوم بإخباره بإضافة إرتفاع العناصر العائمة داخلة، وبذلك يمكننا إضافة خلفية للعنصر الحاوي:

الآن يجب أن يظهر لون الخلفية (رمادي فاتح) بدلاً من اللون الإفتراضي للخلفية (الأبيض).

لاحظ أنه بدون استخدام الإعلانoverflow:hidde; لن تظهر خلفية العنصر الحاوي حيث أن ارتفاع العنصر سيكون صفر.

إختصاراً لما سبق، عندما عندما يكون لديك عنصر غير عائمة Unfloated أسفل العنصر الحاوي، قم بإستخدام حل الخاصية clear ، وفي الحالات الأخرى قم بإضافة الإعلان overflow:hidde; للعنصر الحاوي.

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

أشرف عبدالدايم

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