FlowingDev

أساسيات CSS Box Shadow: الرسم بالضوء والعمق على الويب

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

جرّب الأداة: مولّد ظل الصندوق

في جملة واحدة

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

المشكلة التي تحلها

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

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

ثم انقضت CSS3 مثل بطل خارق (superhero). أعطت خاصية box-shadow للمطورين طريقة لإنشاء الظلال بالكود. فجأة، لم تعد الظلال قطعًا فنية ثقيلة من نوع bitmap؛ بل أصبحت أجزاء ديناميكية وقابلة للتطوير والتحريك من المستند نفسه.

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

كيف تعمل من الداخل

للوهلة الأولى، تبدو خاصية box-shadow بسيطة. ولكن مثل خدعة سحرية جيدة، تخفي أناقتها قدرًا مدهشًا من العمق (والتورية مقصودة).

تشريح الظل الواحد

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

الصيغة الأساسية هي box-shadow: offset-x offset-y blur-radius spread-radius color;. لنفصّلها.

المعلمة (Parameter) ماذا تفعل قيمة مثال
offset-x يحرك الظل أفقيًا. القيم الموجبة تحركه يمينًا، والقيم السالبة تحركه يسارًا. 10px
offset-y يحرك الظل عموديًا. القيم الموجبة تحركه لأسفل، والقيم السالبة تحركه لأعلى. 10px
blur-radius يتحكم في درجة التمويه (الضبابية). 0 تعني ظلًا حادًا وصلب الحواف. القيم الأكبر تخلق تمويهًا أنعم وأكثر انتشارًا. 20px
spread-radius يوسّع أو يقلّص شكل مصدر الظل. القيم الموجبة تجعل الظل أكبر من العنصر؛ والقيم السالبة تقلصه. 5px
color لون الظل. استخدام لون شبه شفاف مثل rgba(0, 0, 0, 0.1) هو مفتاح التأثيرات الواقعية. rgba(0,0,0,0.5)

فقط offset-x و offset-y مطلوبان بشكل صارم، لكن الظل بدون تمويه أو لون ليس ظلًا حقيقيًا.

/* ظل بسيط: 10 بكسل لأسفل، 10 بكسل لليمين، تمويه 20 بكسل، أسود بشفافية 50% */
.card {
  box-shadow: 10px 10px 20px rgba(0, 0, 0, 0.5);
}

الكلمة المفتاحية inset: إلى داخل الصندوق

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

.pressed-button {
  /* يتم رسم هذا الظل *داخل* صندوق الحشو (padding box) للعنصر */
  box-shadow: inset 5px 5px 10px rgba(0, 0, 0, 0.2);
}

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

تكويم الظلال: سر العمق الواقعي

هنا يأتي دور البراعة الفنية الحقيقية. يمكن لخاصية box-shadow أن تقبل قائمة من الظلال مفصولة بفواصل. هذا هو سر إنشاء ظلال تبدو طبيعية وليست كتأثير فوتوشوب أخرق من عام 2008.

الظلال في العالم الحقيقي ليست كتلة واحدة موحدة. فكر في أي شيء على مكتبك. عادة ما يكون هناك ظل صغير، داكن، وحاد تحته مباشرة (الظل التام أو umbra)، وظل أكبر، وأنعم، وأكثر شفافية ينتشر حوله (شبه الظل أو penumbra).

يمكننا محاكاة ذلك عن طريق تكويم تعريفات box-shadow متعددة. يقوم المتصفح بتكديسها، مع كون الظل الأول في القائمة هو الأعلى.

.super-card {
  box-shadow:
    /* الطبقة الأولى (العليا): ظل ضيق وداكن من أجل 'umbra' */
    0 4px 6px -1px rgba(0, 0, 0, 0.1),
    /* الطبقة الثانية (السفلى): ظل أوسع وأنعم من أجل 'penumbra' */
    0 2px 4px -1px rgba(0, 0, 0, 0.06);
}

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

قصص من الواقع

قضية زر الإجراء "العائم"

كانت شركة ناشئة تبني نسخة ويب من تطبيقها الشهير على الهاتف المحمول. كان عنصر الواجهة المميز هو زر الإجراء العائم (FAB) الذي يحوم في الزاوية اليمنى السفلية. المطور المبتدئ المكلف بالمهمة رمى عليه خاصية بسيطة box-shadow: 0 5px 10px black;. في مراجعة التصميم، عبست المصممة الرئيسية قائلة: "لا يبدو وكأنه يطفو، بل يبدو وكأن لديه لطخة داكنة وغريبة". بدا الزر ملتصقًا بالصفحة، وليس مرتفعًا فوقها.

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

الدرس المستفاد: العمق الواقعي يأتي من محاكاة الضوء الحقيقي. تكديس الظلال الخفية ذات الأحجام والتمويه والشفافية المختلفة هو مفتاح جعل العناصر "تطفو".

لغز الأداء المختفي

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

انغمس فريق الأداء في المشكلة. باستخدام أدوات المطور في المتصفح، رأوا بحرًا من اللون الأحمر في مخطط الأداء الزمني (timeline profiler) في كل مرة يقوم فيها المستخدم بالتمرير أو المرور فوق بطاقة. كان المتصفح يقضي وقتًا طويلاً في عملية "الرسم" (Paint). الجاني؟ كل بطاقة كان لها ظل واحد ضخم عند الـ hover: box-shadow: 0 50px 100px -20px rgba(0,0,0,0.5);. نصف قطر التمويه الضخم (100px) عنى أن المتصفح كان عليه إعادة رسم مساحة هائلة من الشاشة في كل إطار من إطارات الحركة.

كان الإصلاح ذا شقين. أولاً، استبدلوا الظل الواحد المكلف بظل متعدد الطبقات أكثر تحسينًا يحقق مظهرًا مشابهًا بأنصاف أقطار تمويه أصغر بكثير. ثانيًا، لتأثير الـ hover، قاموا بعمل transition لخاصية transform: scale(1.05) بدلاً من box-shadow نفسها. كان هذا أرخص بكثير على المتصفح لتحريكه. اختفى التقطيع (jank)، وسعد المستخدمون.

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

الزر "المضغوط للداخل" الذي لم يكن كذلك

أراد مصمم واجهة مستخدم مجموعة من فلاتر التبديل التي تبدو "مضغوطة للداخل" عند تفعيلها. المحاولة الأولى من قبل مطور استخدمت تغييرًا بسيطًا في الـ class: حصل الزر النشط على خلفية أغمق وحدود inset بسمك 1px. لقد نجح الأمر، لكنه لم يبدُ صحيحًا. بدا وكأنه زر مسطح مع خط مرسوم بداخله، وليس زرًا مضغوطًا في سطح.

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

الدرس المستفاد: عندما تريد إنشاء تأثيرات غائرة أو مضغوطة، لا تتصارع مع الحدود والخلفيات. الكلمة المفتاحية inset لـ box-shadow هي الأداة المناسبة للمهمة، وهي مصممة خصيصًا لإنشاء وهم الظل الداخلي هذا.

أخطاء وفخاخ شائعة

  • استخدام الأسود النقي: لا يوجد شيء في العالم الحقيقي يلقي بظل لونه #000000. الظلال الحقيقية تتأثر بالضوء المحيط وتكتسب لونًا من محيطها. خطوة كبيرة للأمام هي استخدام لون أسود شبه شفاف، مثل rgba(0, 0, 0, 0.1). وخطوة أفضل هي استخدام نسخة داكنة وغير مشبعة من اللون الأساسي أو لون الخلفية لتطبيقك.
  • الظل الواحد القاسي: الظل الواحد، الداكن، والحاد الحواف هو أسرع طريقة لجعل تصميمك يبدو قديمًا. كان هذا جيدًا في عام 2010، لكنه اليوم يصرخ "فن المطورين". التكديس هو الطريق إلى واجهات مستخدم حديثة واحترافية المظهر.
  • تحريك خاصية box-shadow: يمكن القيام بذلك، لكنه غالبًا ما يكون فخًا للأداء. تحريك خصائص مثل blur-radius أو spread-radius يجبر المتصفح على القيام بعمليات إعادة رسم (repaint) مكلفة في كل إطار، مما قد يؤدي إلى رسوم متحركة متقطعة (janky). غالبًا ما يكون من الأنعم تحريك transform أو opacity بدلاً من ذلك.
  • نسيان مصدر الضوء: خطأ شائع هو تطبيق نفس box-shadow تمامًا (على سبيل المثال، 10px 10px ...) على كل عنصر في الصفحة، بغض النظر عن موضعه. التصميم الجيد يفترض وجود مصدر ضوء افتراضي ثابت، عادةً من أعلى اليسار. هذا يعني أن الظلال يجب أن تسقط بشكل عام لأسفل وإلى اليمين (يكون offset-y موجبًا، و offset-x موجبًا أو صفرًا). الظلال غير المتسقة تجعل واجهة المستخدم تبدو فوضوية وغير طبيعية.
  • عدم وجود ظل أفضل من ظل سيء: إذا لم يكن لديك الوقت أو الأداة لإنشاء ظل جميل متعدد الطبقات، فمن الأفضل غالبًا استخدام تقنيات أخرى (مثل الحدود أو تغييرات طفيفة في لون الخلفية) لإنشاء فصل بين العناصر. الظل المنفذ بشكل سيء يمكن أن يبخس من قيمة التصميم أكثر من عدم وجود ظل على الإطلاق.

لماذا يجب أن تهتم به

فهم box-shadow أمر غير قابل للتفاوض لأي شخص يتعامل مع كود الواجهة الأمامية أو التصميم. إنها واحدة من أقوى الأدوات في ترسانة CSS لإنشاء واجهات حديثة وبديهية.

  • إنه يخلق تسلسلًا هرميًا: الظلال تخبر أدمغتنا ما هو المهم. العنصر الذي له ظل أبرز يبدو "أقرب" إلينا وبالتالي أكثر أهمية. هذا أساسي لتوجيه انتباه المستخدم عبر واجهة مستخدم معقدة، من مربع حوار يظهر فوق الصفحة إلى زر دعوة لاتخاذ إجراء أساسي.
  • يحدد الحدود بنعومة: قبل box-shadow، كنا نستخدم border: 1px solid grey; للفصل بين العناصر. تسمح لنا الظلال بإنشاء هذا الفصل نفسه بطريقة أكثر نعومة وعضوية. الظل الخفي بين الشريط الجانبي والمحتوى الرئيسي يبدو ألطف من خط صلب.
  • يبني واجهات ملموسة: الظلال المصممة جيدًا، سواء كانت خارجية (outset) أو داخلية (inset)، يمكن أن تجعل الواجهة الرقمية تبدو ملموسة. إنها تعطي الأزرار إحساسًا بأنها قابلة للنقر وحقول الإدخال إحساسًا بأنها قابلة للملء. هذا ليس مجرد زخرفة؛ إنه جزء وظيفي من قابلية الاستخدام.

إتقان box-shadow - خاصة فن التكديس والدقة - هو علامة فارقة تميز المطور الذي يجعل الأشياء تعمل فقط، عن ذلك الذي يجعلها تعمل بشكل جميل.

للتعمق أكثر

انتهينا من النظرية. حان وقت التطبيق — 100% في متصفحك.

جرّب الأداة: مولّد ظل الصندوق