px مقابل rem مقابل em: الدليل الكامل لوحدات CSS
إليك الجواب المختصر عن px مقابل rem مقابل em قبل أي شرح. استخدم rem في معظم القياسات تقريبًا: أحجام الخطوط، والحشو (padding)، والهوامش، والفجوات، واستدارة الحواف، ونقاط التوقّف، لأنها تتغيّر مع إعداد حجم الخط في متصفّح القارئ. استخدم px للأشياء القليلة التي يجب ألّا تتغيّر أبدًا، مثل حدّ بسماكة 1px أو إزاحة ظلّ دقيقة. استخدم em للحالة المحلية النادرة التي يُفترض فيها أن تنمو القيمة مع حجم خط العنصر نفسه، مثل حشو الزر الذي يتبع نصّ الزر.
تغطّي هذه القاعدة 90% من القرارات. أما الـ 10% الباقية فهنا تكمن المتاعب: حساب تراكم em الذي يفاجئ الجميع في أول مرة، وعلّة استعلام الوسائط (media query) التي تكسر التخطيطات عند التكبير، والحالات التي تكون فيها px هي الخيار الأكثر إتاحة فعلًا. يمرّ هذا الدليل على هذه الحالات، مع CSS قابل للتشغيل لكلٍّ منها، إضافةً إلى جدول مرجعي لكل خاصية يمكنك إبقاؤه مفتوحًا أثناء كتابة الأنماط.
ماذا تعني px وrem وem فعلًا
ثلاث وحدات، وثلاث نقاط مرجعية مختلفة. الفرق بينها كله يعود إلى هذه النقطة.
px وحدة مطلقة. الـ px الواحد هو بكسل CSS واحد، ويبقى بهذا الحجم مهما كان ما يحيط به. فـ border: 1px solid هو بكسل واحد، نقطة. لكن المأخذ أنّ “المطلق” يعني أيضًا أنها تتجاهل تفضيلات المستخدم، وسنرى لاحقًا لماذا يهمّ ذلك.
rem نسبية إلى حجم خط العنصر الجذر. الجذر هو <html>، وتضبط المتصفّحات حجم خطه على 16px افتراضيًا. لذا يساوي 1rem مقدار 16px في الإعداد القياسي، في كل مكان من الصفحة، بغضّ النظر عن التداخل. هذا الثبات هو كامل جاذبيتها: قيمة مرجعية واحدة، بلا مفاجآت.
em نسبية إلى حجم خط العنصر الحالي (أو أصله، في الخصائص غير font-size). ولأن هذه النقطة المرجعية تتغيّر مع تداخل العناصر، فإن قيم em تتبدّل بحسب السياق. فالـ 1.5em ذاتها قد تساوي 24px في موضع و30px في موضع آخر.
القيمة المرجعية التي يجب حفظها هي 16px = 1rem. إن لم تستوعب شيئًا آخر، فاستوعب هذه. وحين تحتاج إلى تحويل قيمة محدّدة، يُجري محوّل px إلى rem عملية القسمة على أي أساس تختاره.
px مقابل rem مقابل em في لمحة
| الوحدة | نسبية إلى | هل تتغيّر مع حجم خط المستخدم؟ | الاستخدام المعتاد | السلوك عند التداخل |
|---|---|---|---|---|
px | لا شيء (مطلقة) | لا | الحدود، إزاحات الظلال، الخطوط الرفيعة | الحجم نفسه دائمًا |
rem | حجم خط الجذر <html> | نعم | حجم الخط، التباعد، نقاط التوقّف | الحجم نفسه دائمًا |
em | حجم خط العنصر الحالي | نعم | قيم محلية مرتبطة بمكوّن | تتراكم وقد تنحرف |
العمودان اللذان يحسمان أغلب النقاشات هما “هل تتغيّر مع حجم خط المستخدم” و”السلوك عند التداخل”. وتتفوّق rem في الاثنين: تحترم تفضيل القارئ وتبقى قابلة للتوقّع. وتشارك em الميزة الأولى لكنها تتنازل عن الثانية.
كيف تُحسب كل وحدة
الحساب مجرّد عمليات حسابية بسيطة. ما يربك الناس هو على أي رقم تقسم أو تضرب.
تستخدم rem حجم خط الجذر:
rem = px ÷ root-font-size
عند جذر 16px الافتراضي، يكون 24px ÷ 16 = 1.5rem. وللعودة، اضرب: 1.5rem × 16 = 24px. وكل rem في الصفحة يستخدم الرقم 16 نفسه (أو أيًّا كان ما ضبطت عليه الجذر)، وهذا بالضبط سبب قابلية rem للتوقّع.
تستخدم em حجم خط العنصر الحالي نفسه:
em = px ÷ current-element-font-size
إذا كان font-size العنصرِ هو 20px، فإن 1em على ذلك العنصر هو 20px، و0.5em هو 10px، وحشو 1.5em هو 30px. غيّر حجم خط العنصر فتتغيّر معه كل قيمة em مرتبطة به. هذا الاقتران المحلي هو الغاية من em، وهو فخّها أيضًا.
فخّ تراكم em
هذه هي النقطة التي تُربك أكثر من غيرها. عندما تُداخل عناصر تستخدم جميعها em لحجم الخط، تتضاعف القيم نزولًا في الشجرة. فكل مستوى يرث حجم الخط المحسوب لأصله، ثم يطبّق عامل em الخاص به فوقه.
.menu { font-size: 1.2em; } /* الأصل 16px ← 19.2px */
.menu .item { font-size: 1.2em; } /* الأصل 19.2px ← 23.04px */
.menu .item .sub { font-size: 1.2em; } /* الأصل 23.04px ← 27.648px */
كل مستوى هو “120% من أصله”، وهذا يبدو غير مؤذٍ. لكن لأن الأصل قد نما أصلًا، يصبح المستوى الثالث 1.2 × 1.2 × 1.2 = 1.728em نسبةً إلى الـ 16px الأصلية، أي نحو 27.6px، وليس الـ 19.2px التي قد تقرأها من القاعدة بمعزل. داخِل قائمةً ضمن قائمة ضمن مكوّن فينتفخ النص بطريقة يصعب تتبّعها.
تتجنّب rem هذا تمامًا. فالـ 1.2rem هي 19.2px سواء أكانت في أعلى المستند أم على عمق اثني عشر مستوى، لأنها تقيس دائمًا مقابل الجذر، لا مقابل الأصل. وحين تؤول قيمة إلى حجم لم تتوقّعه، فأول سؤال تطرحه هو هل هي em (نسبية للأصل، تتراكم) أم rem (نسبية للجذر، ثابتة). وإن كنت تنقّح rem شاردة وتريد رؤية حجمها بالبكسل سريعًا، فإن محوّل rem إلى px يحلّها فورًا.
متى تستخدم rem
اجعل rem خيارك الافتراضي. فهي الوحدة الصحيحة لأحجام الخطوط، والحشو، والهوامش، والفجوات، واستدارة الحواف، ونقاط توقّف استعلامات الوسائط، أي كل شيء يُفترض أن يتغيّر حين يضبط القارئ حجم نصّه.
تلك الجملة الأخيرة هي حجّة إمكانية الوصول، وهي ليست افتراضية. فمسوحات WebAIM لقارئات الشاشة وضعاف البصر تجد باستمرار أن شريحة كبيرة من المستخدمين يضبطون حجم الخط الافتراضي في متصفّحهم أو نظامهم، وكثير منهم يرفعونه فوق 16px القياسية بكثير. التخطيط المُقاس بـ rem يحترم هذا التغيير: ارفع الافتراضي إلى 20px فتنمو كل قيمة قائمة على rem تناسبيًا. أما التخطيط المُقاس بـ px فيتجاهله تمامًا، إذ يبقى النص مثبّتًا على حجمه المُرمّز يدويًا، مهما احتاج القارئ إلى تكبيره.
:root {
font-size: 16px; /* 1rem = 16px */
}
h1 { font-size: 2rem; } /* 32px، يتغيّر مع تفضيل المستخدم */
p { font-size: 1rem; } /* 16px */
.card { padding: 1.5rem; } /* 24px */
.card { border-radius: 0.5rem; } /* 8px */
ولأن كل قيمة هنا مرتبطة بالجذر نفسه، فإن تغييرًا واحدًا في حجم خط الجذر يعيد قياس الواجهة كلها بالتناسب. وهذا أيضًا ما يُبقي نظام التصميم متماسكًا، فالتباعد والخطوط يتحرّكان معًا بدل أن ينحرف أحدهما عن الآخر.
حيلة الـ 62.5%
ثمة اختصار شائع يجعل حساب rem سهلًا للغاية. اضبط حجم خط الجذر على 62.5%، أي 62.5% × 16px = 10px:
html {
font-size: 62.5%; /* الآن 1rem = 10px */
}
body {
font-size: 1.6rem; /* استعادة حجم نص جسم مقروء 16px */
}
h1 { font-size: 2.4rem; } /* 24px */
p { font-size: 1.6rem; } /* 16px */
مع جذر 10px، ينهار الحساب الذهني إلى “اقسم قيمة البكسل على 10”: 24px → 2.4rem، 12px → 1.2rem. والعقبة الوحيدة هي استعادة حجم جسم مقروء عبر body { font-size: 1.6rem }، إذ يترك أساس 10px الخامُ النصَّ الافتراضي صغيرًا جدًا. واستخدام 62.5% كنسبة مئوية بدل 10px يُبقيها نسبية، فيظلّ القارئ الذي يكبّر الافتراضي في متصفّحه يحصل على نموّ تناسبي. وإن اعتمدت هذا الأساس، فاضبط حجم خط الجذر في المحوّل على 10 ليطابق ورقة أنماطك.
متى تستخدم em
استخدم em حين تريد لقيمة أن تتغيّر مع حجم خط العنصر نفسه، لا مع الجذر. والحالة الكلاسيكية هي الزر:
.btn {
font-size: 1rem; /* مقاس مقابل الجذر */
padding: 0.75em 1.5em; /* الحشو يتبع نصّ الزر */
}
.btn--large {
font-size: 1.25rem; /* تغيير واحد يعيد قياس كل شيء */
}
ولأن الحشو بوحدة em، فإن المُحوّر .btn--large يعيد قياس النص وحشوه معًا من تصريح واحد، فيبقى الزر متناسبًا عند أي حجم. وينطبق المنطق نفسه على أيقونة مقاسة بـ em لتطابق سطر النص الذي تجلس فيه، أو تباعد الأحرف الذي يُفترض أن ينمو مع الخط.
الاستراتيجية الناجحة عمليًا هي rem للهيكل العام، وem للتناسبات المحلية. اضبط حجم الخط بـ rem ليستجيب للجذر ولتفضيل المستخدم؛ واضبط القيم القليلة التي يُفترض أن تتبع ذلك العنصر بـ em. فقط أبقِ em بعيدةً عن أي شيء يتداخل بعمق، وإلّا تسلّل فخّ التراكم السابق من جديد.
متى تستخدم px
بعض القيم يجب فعلًا ألّا تتغيّر، وpx هي الصحيحة لها: حدّ رفيع بسماكة 1px، وإزاحة box-shadow دقيقة، وحلقة تركيز بسماكة 2px. فهذه تفاصيل تصيير (rendering)، لا محتوى. والحدّ الذي “يتغيّر” إلى 1.25px حين يكبّر المستخدم نصّه لا يكسب شيئًا، وقد يُصيَّر كخطّ ضبابي، بينما تُبقيه px حادًّا.
.divider { border-bottom: 1px solid; } /* ينبغي أن يبقى 1px */
.card { box-shadow: 0 2px 4px rgba(0,0,0,0.1); } /* إزاحة ثابتة */
.input:focus { outline: 2px solid; } /* حلقة تركيز حادّة */
الفارق المُفاجئ: حين تكون px أكثر إتاحة
هنا الجزء غير البديهي الذي تغفله نصيحة “استخدم rem دائمًا”. الخيار المتاح ليس “rem في كل مكان”، بل “كبّر ما يجب أن يكبر، وثبّت ما لا يجب”.
حدّ 1px تفصيل ثابت. وإجباره على rem ليكبر حين يكبّر المستخدم النص لا يساعد في القراءة، بل يجعل الخطّ الرفيع ضبابيًا فحسب. ولهذه الخصائص، تكون px الخيار الأكثر إتاحة تحديدًا لأنها تبقى ثابتة.
الخطأ الذي يقع فيه الناس فعلًا هو العكس: استخدام px للأشياء التي يُفترض أن تستجيب، مثل أحجام الخطوط ونقاط التوقّف. وهنا تضرّ px بإمكانية الوصول. فالقاعدة إذًا ليست عن الوحدة، بل عن الخاصية. اسأل: هل القيمة محتوى يتفاعل معه القارئ (فكبّرها بـ rem) أم تفصيل تصيير ثابت (فثبّتها بـ px)؟ تتبع الوحدةُ الجوابَ.
فخّ استعلام الوسائط
هذا الفخّ يكسر تخطيطات حقيقية، وقلّما يُنتبه إليه. فنقاط توقّف استعلام الوسائط المكتوبة بـ px لا تستجيب لتكبير حجم الخط في المتصفّح كما قد تأمل.
تخيّل نقطة توقّف عند width: 600px ينطوي عندها شريط جانبي. مستخدم ضعيف البصر يضبط الافتراضي في متصفّحه على 24px ليقرأ بارتياح. صار محتواك الآن يحتاج إلى مساحة أفقية أكبر، فالنص الأكبر يريد أن يعيد التدفّق أبكر. لكن نقطة توقّف px لا تعرف أن النص قد نما؛ فما تزال تنقلب عند 600px بالضبط من عرض إطار العرض، فيتبدّل التخطيط في اللحظة الخاطئة ويصير المحتوى مزدحمًا أو متراكبًا.
قارن بين النهجين:
/* نقطة توقّف px — تتجاهل تفضيل حجم خط المستخدم */
@media (min-width: 600px) {
.sidebar { display: block; }
}
/* نقطة توقّف em/rem — تستجيب لحجم خط المستخدم */
@media (min-width: 37.5em) {
.sidebar { display: block; }
}
الـ 37.5em هي 600px عند الافتراضي 16px (600 ÷ 16 = 37.5). والفارق سلوكي: حين يضاعف المستخدم حجم خطه الافتراضي، تتضاعف نقطة توقّف em فعليًا أيضًا، فيتبدّل التخطيط عند عرض إطار عرض متناسب مع النص، أي تحديدًا حين يحتاج إليه المحتوى. أما نقطة توقّف px فتبقى مجمّدة.
وثمة تفصيل يستحق المعرفة: في شروط استعلام الوسائط، تُحسب كلٌّ من em وrem مقابل حجم خط المتصفّح الافتراضي، لا أي تجاوز في html، فتتصرّفان بصورة متطابقة هناك. وأيّ من الوحدتين يصلح الخلل، بينما px هي ما يسبّبه.
جدول القرار حسب الخاصية
حين تكون مترددًا، يجيبك هذا الجدول دون أن تعيد اشتقاق المنطق في كل مرة.
| الخاصية | الوحدة المُوصى بها | لماذا |
|---|---|---|
font-size | rem | تتغيّر مع تفضيل حجم خط المستخدم |
padding / margin | rem | يتغيّر التباعد معًا مع النص |
border | px | الخطوط الرفيعة ينبغي أن تبقى حادّة وثابتة |
إزاحة box-shadow | px | تفصيل تصيير دقيق، لا محتوى |
border-radius | rem | يُبقي استدارة الزوايا متناسبة مع القياس |
| استعلام الوسائط | em / rem | نقاط التوقّف يجب أن تستجيب لتكبير حجم الخط |
width / max-width | rem (غالبًا ch للنص) | عروض تخطيط قابلة للقياس؛ ch يحدّ طول السطر |
line-height | بلا وحدة | المُضاعِف بلا وحدة يُورَّث بصورة صحيحة |
يستحق صفّ line-height ملاحظة لأنه علّة شائعة. اكتب دائمًا line-height: 1.5 بلا وحدة. فالقيمة بلا وحدة مُضاعِف يحسبه كل عنصر مقابل حجم خطه هو، فتبقى العناصر المتداخلة مقروءة. اكتب line-height: 1.5em أو 24px بدلًا من ذلك فيُورَّث الطول المحسوب، ما يعني أن العنصر الابن ذا الخط الأكبر يحتفظ بارتفاع سطر أصله فيبدأ نصّه بالتصادم. القيمة بلا وحدة تتجنّب المشكلة برمّتها.
التحويل بين px وrem
الحساب صغير بما يكفي لتُجريه ذهنيًا متى أمسكت بالقيمة المرجعية: 16px = 1rem. اقسم على 16 للذهاب إلى rem، واضرب في 16 للعودة إلى px.
| px | rem (أساس 16px) |
|---|---|
| 8px | 0.5rem |
| 12px | 0.75rem |
| 16px | 1rem |
| 24px | 1.5rem |
| 32px | 2rem |
إن استخدمت حيلة الـ 62.5%، يصبح الأساس 10px والحساب أبسط بعد، إذ يكفي أن تقسم أو تضرب في 10، فيكون 24px = 2.4rem. والقاعدة الوحيدة هي أن تحوّل دائمًا مقابل الأساس الذي تضبطه ورقةُ أنماطك فعلًا.
ولكل ما عدا ذلك، أي القيم الغريبة، أو جذر مخصّص، أو تحويل دفعة من تصدير Figma، تجاوز الحساب الذهني واستخدم محوّل px إلى rem أو محوّل rem إلى px. كلاهما يتيح ضبط أي حجم خط جذري والتحويل في أي اتجاه في الوقت الفعلي. وإن كنت تُرتّب لاحقًا ورقة أنماط مليئة بوحدات مختلطة، فإن منسّق CSS سيوحّد التباعد والإزاحة نيابةً عنك.
أخطاء شائعة
تتسبّب بضعة أنماط في معظم المتاعب المرتبطة بالوحدات:
ضبط حجم خط الجذر بـ px. كتابة html { font-size: 16px } (بدل ترك الافتراضي أو استخدام 100% / نسبة مئوية) يتجاوز تفضيل حجم خط متصفّح المستخدم كليًا. تبقى قيم rem تُحسب مقابله، لكن لم يعد بإمكان القارئ تكبير الصفحة كلها. اترك الجذر على الافتراضي، أو استخدم نسبة مئوية.
خلط px وrem بلا نظام. بعض أحجام الخطوط بـ px وبعضها بـ rem، والتباعد موزّع بينهما، فتكون النتيجة تخطيطًا يتغيّر بصورة غير متّسقة حين يضبط المستخدم نصّه. اختر rem افتراضيًا، واحفظ px للاستثناءات المقصودة في جدول القرار.
استخدام em للتباعد العام. em على الحاويات المتداخلة بكثرة يعيد إدخال فخّ التراكم، فيؤول padding عميق في الشجرة إلى شيء لم يقصده أحد. أبقِ التباعد العام بـ rem؛ واحفظ em للقيم المحلية المحدودة بنطاق المكوّن.
إعطاء line-height وحدةً. كما مرّ أعلاه، يُورَّث line-height: 24px أو 1.5em كطولٍ محسوب فيتعطّل على العناصر ذات أحجام الخطوط المختلفة. استخدم دائمًا مُضاعِفًا بلا وحدة.
الأسئلة الشائعة
هل rem أفضل من px؟
لمعظم القياسات نعم، فـ rem أفضل من px لأنها تتغيّر مع تفضيل حجم خط متصفّح المستخدم، وهو ما تتجاهله px. لكن “الأفضل” يتوقّف على الخاصية: فـ px هي الخيار الصحيح للتفاصيل الثابتة مثل حدود 1px وإزاحات الظلال التي ينبغي أن تبقى حادّة. استخدم rem لقياس المحتوى، وpx لتفاصيل التصيير.
كم يساوي 1rem بالبكسل؟
يساوي 1rem حجمَ خط الجذر بالبكسل، وهو 16px افتراضيًا في كل المتصفّحات تقريبًا. فـ 1rem = 16px، و1.5rem = 24px، و2rem = 32px في الإعداد القياسي. وإذا تجاوزت ورقة أنماط html { font-size } (مثلًا إلى 10px عبر حيلة الـ 62.5%) فإن 1rem يساوي تلك القيمة بدلًا من ذلك.
هل أستخدم rem أم em لحجم الخط؟
استخدم rem لحجم الخط في كل حالة تقريبًا. تقيس rem مقابل الجذر، فتبقى قابلة للتوقّع مهما تداخل العنصر بعمق. أما em فتقيس مقابل حجم خط الأصل، وهو ما يتراكم نزولًا في الشجرة فينتفخ النص المتداخل على نحو غير متوقّع. احفظ em للقيم المحلية المرتبطة بمكوّن واحد.
متى أستخدم px بدل rem؟
استخدم px للقيم التي يُفترض ألّا تتغيّر مع حجم خط المستخدم: حدود 1px، وإزاحات box-shadow الدقيقة، وحلقات التركيز، وغيرها من تفاصيل التصيير الثابتة. فهذه تفاصيل تصميم حادّة لا محتوى، لذا تثبيتها بـ px هو الخيار الأكثر إتاحة. وكل ما يتعلّق بالمحتوى ينبغي أن يبقى بـ rem.
لماذا تتعطّل استعلامات الوسائط حين أستخدم px؟
نقاط توقّف استعلام الوسائط بـ px لا تستجيب لتكبير حجم الخط في المتصفّح. فحين يكبّر المستخدم خطه الافتراضي، يحتاج محتواه إلى مساحة أكبر، لكن نقطة توقّف px ما تزال تنقلب عند العرض نفسه لإطار العرض، فيتبدّل التخطيط في اللحظة الخاطئة. استخدم نقاط توقّف em أو rem التي تتغيّر مع حجم خط المستخدم.
ما حيلة حجم الخط 62.5%؟
تضبط حيلة الـ 62.5% الخاصيةَ html { font-size: 62.5% }، فيصير حجم خط الجذر 10px (62.5% من 16). ومع أساس 10px، يصبح حساب rem “اقسم على 10”: 24px = 2.4rem، و12px = 1.2rem. ثم يضبط المطوّرون body { font-size: 1.6rem } لاستعادة نص جسم مقروء بحجم 16px.
هل لا بأس بخلط px وrem وem؟
نعم، خلط px وrem وem صحيح حين تتبع كل وحدة الخاصيةَ التي تناسبها: rem للخطوط والتباعد، وpx للتفاصيل الثابتة، وem للقيم المحلية المحدودة بنطاق المكوّن. وما يسبّب المتاعب هو خلطها بلا نظام، كأن تكون بعض أحجام الخطوط بـ px وبعضها بـ rem. اختر rem افتراضيًا، وعامِل px وem كاستثناءات مقصودة.
أي وحدة أستخدم للحشو والهامش؟
استخدم rem للحشو والهامش ليتغيّر التباعد معًا مع النص حين يضبط المستخدم حجم خطه. هذا يُبقي التخطيط متناسبًا ومتاحًا. واحفظ em للحشو الذي يُفترض أن يتبع حجم خط العنصر نفسه، مثل زر ينمو حشوه مع نصّه، وتجنّب em على الحاويات المتداخلة بعمق حيث تتراكم.