تخطَّ إلى المحتوى

الوحدات والحساب في CSS: em و rem و calc و clamp

الدرس 10 من 19 · CSS

استخدمت في الدروس السابقة وحدات مثل px و rem و % دون أن نتوقف عندها طويلاً. الآن حان وقت فهمها جيداً، لأن اختيار الوحدة المناسبة هو الفرق بين صفحة تتكيف مع كل شاشة وصفحة تنكسر عند أول تغيير. وستتعلم في هذا الدرس أيضاً أن CSS تستطيع أن تحسب بنفسها.

  • وحدات مطلقة: قيمتها ثابتة لا تتأثر بشيء. أهمها px.
  • وحدات نسبية: قيمتها تُحسب نسبةً إلى شيء آخر: حجم الخط، أو العنصر الأب، أو الشاشة.

تخيّل وصفة طعام: «200 جرام أرز» مقدار مطلق، و«كوب ماء لكل كوب أرز» مقدار نسبي. الوصفة النسبية تصلح لشخصين ولعشرة، والمطلقة تصلح لعدد واحد فقط.

الوحدة نسبةً إلى ماذا؟
px لا شيء. قيمة ثابتة
rem حجم خط العنصر الجذر html، وهو 16px افتراضياً
em حجم خط العنصر نفسه
% العنصر الأب
vw و vh عرض الشاشة وارتفاعها. كل 1vw يساوي 1% من العرض
ch عرض الرقم صفر في الخط الحالي

هذا أكثر ما يحيّر المبتدئين. rem ترجع دائماً إلى مكان واحد هو حجم خط الصفحة، فقيمتها ثابتة في كل مكان: 2rem تساوي 32px أينما كتبتها.

أما em فترجع إلى حجم خط العنصر الذي كُتبت فيه. وهذا مفيد عندما تريد أن تكبر المسافات مع الخط:

.btn {
font-size: 1rem;
padding: 0.5em 1em;
}
.btn.large {
font-size: 1.5rem;
}

الزر الكبير لم نغيّر حشوه، لكنه كبر تلقائياً، لأن 1em فيه صارت تساوي 24px بدلاً من 16px.

.hero {
min-height: 100vh;
}
.title {
font-size: 5vw;
}

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

لكن 5vw وحدها خطرة: العنوان يصير صغيراً جداً على الموبايل وعملاقاً على شاشة عريضة. وسترى حل هذه المشكلة بعد قليل.

الدالة calc تجري عملية حسابية، وميزتها الكبرى أنها تخلط بين الوحدات:

.content {
width: calc(100% - 250px);
}
.section {
padding: calc(1rem + 2vw);
}

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

  • min(أ, ب): تختار الأصغر من القيمتين.
  • max(أ, ب): تختار الأكبر.
.card {
width: min(100%, 600px);
}

معناها: العرض كامل على الشاشة الصغيرة، ولا يتجاوز 600px على الكبيرة. وهذا السطر الواحد يساوي كتابة width: 100% مع max-width: 600px.

clamp تأخذ ثلاث قيم: الحد الأدنى، ثم القيمة المفضلة، ثم الحد الأقصى.

h1 {
font-size: clamp(1.5rem, 5vw, 3rem);
}

العنوان يتبع عرض الشاشة بالقيمة 5vw، لكنه لا ينزل تحت 1.5rem ولا يزيد على 3rem. وهكذا تُحل مشكلة العنوان الذي رأيناه، بلا أي استعلام وسائط.

لماذا؟ الوحدة المناسبة
حجم الخط rem
الحشو والهوامش rem، أو em إذا أردتها تتبع حجم خط العنصر
عرض الحاويات % مع max-width، أو min()
عرض فقرة مريح للقراءة ch، مثل max-width: 65ch
سمك الإطار والظلال الدقيقة px
قسم بارتفاع الشاشة vh

اسحب الزاوية السفلية لصندوق النتيجة لتغيّر عرضه، وراقب كيف يتغير حجم العنوان ثم يتوقف عند حدّيه. بعدها غيّر font-size للكلاس large وشاهد حشو الزر:

جرّب بنفسكCSS
أو اضغط Ctrl + Enter

الناتج

  • نسيان المسافات في calc: calc(100% -20px) لا تعمل. المسافة مطلوبة على جانبي العلامة.
  • استخدام px لكل شيء: الصفحة لا تستجيب لمن كبّر الخط من إعدادات متصفحه. اجعل الخطوط بـ rem.
  • الاعتماد على vw وحدها للخطوط: النص يصغر حتى لا يُقرأ على الموبايل. قيّده دائماً بـ clamp.
  • 100vw للعرض الكامل: تسبب أحياناً تمريراً أفقياً، لأنها تحسب مساحة شريط التمرير. استخدم 100%.

سؤال

حجم خط الصفحة الأساسي 16px. كم تساوي 2rem داخل عنصر حجم خطه 30px؟

سؤال

ماذا تعني font-size: clamp(1rem, 4vw, 2rem)؟

  • px ثابتة، وباقي الوحدات نسبية تتكيف مع ما حولها.
  • rem نسبة إلى خط الصفحة، و em نسبة إلى خط العنصر نفسه.
  • vw و vh نسبة إلى أبعاد الشاشة.
  • calc تحسب وتخلط الوحدات، بشرط المسافات حول + و -.
  • clamp(أدنى, مفضلة, أقصى) تعطيك قيمة مرنة بحدود آمنة.