اذهب إلى المحتوى

ضبط تموضع العناصر في صفحات ويب باستخدام CSS


ابراهيم الخضور

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

ملاحظة: يمكنك أن تنجز تمارين المقال على حاسوبك الشخصي، لهذا حاول أن تحضر نسخة من الملف 0_basic-flow.html من مستودع جيت-هاب (حمّل الشيفرة المصدرية أيضًا) واستخدامه كنقطة انطلاق.

مدخل إلى تموضع العناصر

يسمح لك تحديد مواضع العناصر في صفحة الويب في الحصول على نتائج مثيرة بتجاوز تنسيق الانسياب الاعتيادي. فماذا لو أردت أن تغيّر قليلًا موقع بعض الصناديق عن موقعها الافتراضي في الانسياب الاعتيادي لتمنح المستخدم تجربة خاصة مثلًا؟ سيكون تموضع العناصر الأداة المثالية لك في هذه الحالة.

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

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

التموضع الساكن Static

وهو التموضع الافتراضي لأي عنصر، ويعني "ضع العنصر في موقعه الطبيعي ضمن الانسياب الاعتيادي". ولكي ترى ذلك (وتحضّر الملف الذي ستتمرن عليه في الأقسام اللاحقة). أضف أولًا الصنف positioned إلى الفقرة النصية <p> الثانية:

<p class="positioned"></p>

أضف الآن القاعدة التالية في نهاية شيفرة CSS:

.positioned {
  position: static;
  background: yellow;
}

لن تجد عندما تحفظ التغيّرات وتعيد تحميل الصفحة أي اختلاف سوى لون الخلفية الجديد للفقرة النصية الثانية. وهذا بالفعل ما سيحدث فالتموضع الساكن هو التموضع الافتراضي للعنصر.

التموضع النسبي Relative

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

position: relative;

لن تجد أي شيئ قد تغيّر أيضًا في هذه المرحلة إن حفظت التغيّرات وأعدت تحميل الصفحة، لكن كيف سنغير الموقع النهائي للعنصر؟ سنحتاج إلى استخدام الخاصيات top و bottom و left و right والتي سنشرحها تاليًا.

الخاصيات top و bottom و left و right

تستخدم هذه الخاصيات مع الخاصية position لتحديد المكان الذي تريد وضع العنصر فيه بدقة. لتجريب الأمر أضف إلى التصريح positioned. الشيفرة التالية:

top: 30px;
left: 30px;

ملاحظة: يمكن أن تأخذ هذه الخاصيات قيمًا بأية واحدات مثل البكسل و mm و rem و %.

إن حفظت لتغيرات الآن وأعدت تحميل الصفحة ستكون النتيجة كالتالي:

لقد توضح الأمر قليلًا، أليس كذلك؟ لكن لا أعتقد أنك توقعت النتيجة. لماذا تحرّكت الفقرة نحو الأسفل واليمين مع أننا حددنا قيم الخاصيتين top و left. عليك أن تتخيل الموضوع كما لو كانت هناك قوة تدفع الفقرة من الجانبين السابقين (أعلى ويسار) وبالتالي ستنقل الفقرة نحو اليمين والأسفل. فلو كان ;top: 30px فيبدو الأمر كقوة تدفع صندوق الفقرة النصية من الأعلى نحو الأسفل وتحركه مقدار 30 بكسل.

التموضع المطلق Absolute

يأتي التموضع المطلق بنتائج مختلفة جدًا.

ضبط الوضع المطلق

غيّر قيمة الخاصية position كالتالي:

position: absolute;

لو حاولت حفظ التغيير وإعادة تحميل الصفحة ستجد النتيجة التالية:

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

ونلاحظ ثانيًا أن موضع العنصر قد تغيّر، لأن سلوك الخاصيات top و bottom و left و right قد تغيّر مع التموضع المطلق. فبدلًا من توضيع العنصر بناء على موقعه بالنسبة إلى تخطيط الانسياب الاعتيادي، ستحدد تلك الخاصيات بعد صندوق العنصر عن حواف العنصر الحاوي. أي كأننا نقول في مثالنا أن صندوق الفقرة النصية ذات التموضع المطلق ستبتعد 30 بكسل عن الحافة العليا للعنصر الحاوي و 30 بكسل عن الحافة اليسرى له (إن العنصر الحاوي في حالتنا هي الكتلة الحاوية الأساسية initial containing block).

ملاحظة: يمكنك استخدام top و bottom و left و right لإعادة تحديد أبعاد العناصر. جرّب مثلًا القيم التالية:
;top: 0 و ;bottom: 0 و;left: 0 و ; right: 0 و ;margin: 0  على العنصر الذي تحدد موضعه وراقب ما الذي سيحدث! أعد كل شيء إلى حاله عندما تنتهي.

ملاحظة: تؤثر الهوامش على نوع العنصر، لكن لا تؤثر به خاصيات الهوامش المنقبضة Margin collapsing.

سياق تموضع العناصر

من هو العنصر الحاوي لعنصر ذو توضّع مطلق؟ يعتمد هذا الأمر كثيرًا على قيمة الخاصية position للعنصر الأب للعنصر المطلق. فإن لم يكن للعنصر عنصر أب قد حُددت قيمة الخاصية position له صراحةً فسيأخذ العنصر الأب التموضع الساكن. وتكون النتيجة أن يُحتوى العنصر المطلق ضمن الكتلة الحاوية الأساسية. للحاوية الأساسية أبعاد نافذة العرض وهي أيضًا الكتلة التي تحتوي العنصر <html> . وبعبارة أخرى، سيُعرض العنصر المطلق خارج حدود العنصر الأب ويتوضع بالنسبة إلى نافذة العرض.

يقع العنصر المطلق ضمن العنصر <body> في شيفرة HTML المصدرية، لكن ستجده في التخطيط النهائي بعيدًا مسافة 30 بكسل عن الحد الأعلى للصفحة. بإمكاننا تغيير سياق توضع العنصر بمعنى كيفية توضعه المطلق وبالنسبة لأية عناصر. ننجز ذلك بضبط قيمة الخاصية position لأحد العناصر الآباء، أي العناصر التي يقع ضمنها العنصر ذو التموضع المطلق (إذ لا يمكن ضبط موقع عنصر بالنسبة إلى عنصر آخر إذا لم يكن ضمن هذا الأخير). لترى التأثير الذي نتحدث عنه، أضف التصريح التالي إلى القاعدة body:

position: relative;

من المفترض أن تحصل على النتيجة التالية:

ضُبط موقع العنصر الآن بالنسبة إلى العنصر <body>.

الخاصية z-index

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

أضف شيفرة CSS التالية لتوضّع الفقرة النصية الأولى توضّعًا مطلقًا أيضًا:

p:nth-of-type(1) {
  position: absolute;
  background: lime;
  top: 10px;
  right: 30px;
}

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

لكن هل يمكن تغيير الأمر؟ نعم باستخدام الخاصية z-index والتي تُعرف باسم "مؤشر العلو". وهي قيمة مرجعية للمحور الثالث Z الذي نفترض أنه يتجه نحو المستخدم عموديًا على الشاشة. وقد تتذكر من مقالات سابقة كيف استخدمنا المحور الأفقي (المحور X) والمحور العمودي (المحور Y) لتحديد إحداثيات أشياء مثل موقع صور الخلفية وتأثيرات الظل. فمن أجل اللغات التي تكتب من اليسار إلى اليمين، يمثل الإحداثي (0,0) الزاوية العليا اليسرى للصفحة أو العنصر ضمن حاويته. ويتحرك منها الإحداثي X نحو اليمين والإحداثي Y نحو الأسفل.

للصفحات أيضًا محور ثالث هو المحور Z وهو كما ذكرنا محور تخيلي ينطلق من سطح الشاشة نحو المستخدم. وتؤثر قيمة محور العلو z-index على موقع العنصر الموّضع على هذا المحور، وكلما كانت قيمة هذه الخاصية أعلى لعنصر ظهر فوق العنصر ذو القيمة الأقل. ولكل العناصر القيمة الافتراضية للخاصية z-index وهي عمليًا القيمة 0. يسمح باستخدام القيم السالبة والتي تجعل العنصر ينزل نحو الأسفل.

ولكي تغير ترتيب العناصر المتراكبة، أضف التصريح التالي إلى القاعدة p:nth-of-type(1) :

z-index: 1;

سترى الآن الفقرة ذات اللون الأخضر الفاتح في الأعلى:

يجدر الانتباه إلى أن الخاصية z-index تقبل فقط قيمًا بلا وحدات، فلا يمكنك تخصيص قيمة مثل 23px. ودائمًا تأتي القيم الأكبر فوق القيم الأصغر، ولك حرية تخصيص هذه القيم بأي قيم تريدها، فاستخدام قيمتين مثل 2 و 3 يماثل استخدام القيمتين 300 و400.

التموضع الثابت Fixed

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

لنعمل سوية على المثال التالي كي تتوضح الصورة. احذف بداية القاعدتين (p:nth-of-type(1 و positioned. من شيفرة CSS. عدّل بعد ذلك القاعدة body واحذف التصريح ;position: relative ثم اجعل الارتفاع ثابتًا كالتالي:

body {
  width: 500px;
  height: 1400px;
  margin: 0 auto;
}

سيُمنح الآن العنصر <h1> موضعًا ثابتًا ;position: fixed ونضبط هذا الموقع ليكون أعلى نافذة العرض بإضافة الشيفرة التالية:

h1 {
  position: fixed;
  top: 0;
  width: 500px;
  margin-top: 0;
  background: white;
  padding: 10px;
}

لا بد من استخدام التصريح ;top: 0 ليبقى العنصر أعلى الشاشة، كما منحنا العنوان اتساعًا يماثل اتساع محتوى العمود وخلفية بيضاء وبعض الهوامش والحشوات كي يظهر المحتوى تحته.

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

p:nth-of-type(1) {
  margin-top: 60px;
}

 سترى النتيجة كالتالي:

التموضع اللاصق Sticky

هنالك قيمة أخرى للخاصية position هي position: sticky، وهي أحدث من القيم الأخرى نوعًا ما. وهي في الواقع خيار هجين بين الوضعين النسبي والثابت. تسمح هذه القيمة للعنصر بالتصرف وكأنه موضّع نسبيًا حتى تُمرر الصفحة إلى حد معين (مثل 10 بكسل عن أعلى نافذة العرض) ليصبح بعدها ثابتًا.

مثال بسيط على Sticky

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

.positioned {
  position: sticky;
  top: 30px;
  left: 30px;
}

فهرس قابل للتمرير

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

<h1>Sticky positioning</h1>

<dl>
  <dt>A</dt>
  <dd>Apple</dd>
  <dd>Ant</dd>
  <dd>Altimeter</dd>
  <dd>Airplane</dd>
  <dt>B</dt>
  <dd>Bird</dd>
  <dd>Buzzard</dd>
  <dd>Bee</dd>
  <dd>Banana</dd>
  <dd>Beanstalk</dd>
  <dt>C</dt>
  <dd>Calculator</dd>
  <dd>Cane</dd>
  <dd>Camera</dd>
  <dd>Camel</dd>
  <dt>D</dt>
  <dd>Duck</dd>
  <dd>Dime</dd>
  <dd>Dipstick</dd>
  <dd>Drone</dd>
  <dt>E</dt>
  <dd>Egg</dd>
  <dd>Elephant</dd>
  <dd>Egret</dd>
</dl>

تبدو شيفرة CSS قريبة من التالي: تتحرك العناصر <dt> في الانسياب الاعتيادي مع المحتوى عند تمريره، لكن بإضافة الخاصية position: sticky إلى هذه العناصر بالإضافة إلى الخاصية top ستعمل المتصفحات الحديثة على إبقاء العناوين في أعلى نافذة العرض عندما تبلغ هذا الموقع. سيستبدل كل عنوان لاحق العنوان السابق عندما يصل إليه وهكذا.

dt {
  background-color: black;
  color: white;
  padding: 10px;
  position: sticky;
  top: 0;
  left: 0;
  margin: 1em 0;
}

لاحظ كيف تبقى العناصر اللاصقة لاصقةً بالنسبة إلى أقرب عنصر يمتلك آلية تحدد طريقة تمرير محتواه أي بعبارة أخرى له قيمة مخصصة للخاصية position.

الخلاصة

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

ترجمة -وبتصرف- للمقال: Positioning

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...