الوحدة 2 · تخطيط يصمد
التحجيم الذاتي: min() وmax() وclamp()
17 دقراءة 3 دبيئة تجريب الكود
الدرس في لمحة
حدّد أحجام العناصر من محتواها باستخدام min-content وmax-content وfit-content، واستبدل أزواج الـ breakpoints بـ min() وmax() وclamp().
- 1دع المحتوى يقرّر: الكلمات المفتاحية الذاتية
- 2min() وmax() وclamp()
- 3وحدات تجعل الدوال الرياضية مفيدة
- 4دورك الآن
لا فيديو هنا، بل الشيء الحقيقي: درس مكتوب وأمثلة قابلة للتشغيل واختبار وتدريب.
كان لملخّصات الجلسات في Waypoint الزوج الكلاسيكي من القواعد: width: 100% مع max-width: 40ch، ثم media query لإضافة حشوة جانبية على الهواتف، وأخرى للشاشات الكبيرة. ثلاث قواعد ونقطتا تحوّل لقول شيء واحد: «كن بالعرض المريح للقراءة، لكن لا تتجاوز المساحة المتاحة لك أبدًا».
تستطيع CSS أن تقول ذلك مباشرةً الآن. يغطّي هذا الدرس أداتين: الكلمات المفتاحية للحجم الذاتي (intrinsic)، التي تترك للمحتوى أن يقرّر حجم العنصر، والدوال الرياضية min() وmax() وclamp()، التي تتيح لك وصف مدى بدل اختيار الـ breakpoints.
دع المحتوى يقرّر: الكلمات المفتاحية الذاتية
معظم الأحجام التي تكتبها خارجية (extrinsic): 300px و50% و1fr. لكن المتصفّح يستطيع أيضًا أن يحدّد حجم العنصر من محتواه، وثلاث كلمات مفتاحية تكشف ذلك:
min-content: أضيق ما يمكن أن يكونه العنصر دون أن يفيض، وهو عادةً عرض أطول كلمة فيه.max-content: العرض الذي سيأخذه المحتوى لو لم يلتفّ أبدًا.fit-content: هيmax-content، لكن لا تتجاوز المساحة المتاحة أبدًا. وحين تنفد المساحة تلتفّ كأيّ كتلة عادية.
fit-content هي التي ستستخدمها أكثر. الشارة أو الزر من نوع block يتمدّد عادةً ليملأ حاويته؛ أما width: fit-content فتجعله يحتضن تسميته كأنه عنصر inline مع بقائه block، فتظل الـ margins والتراصّ تعمل كما يجب. أضف margin-inline: auto فيتوسّط.
وفي tracks الشبكة تعطيك هذه الكلمات أعمدةً يقودها المحتوى. جدول أعمال Waypoint يستخدم grid-template-columns: max-content 1fr: عمود الوقت بعرض أطول وقت بالضبط («10:15–11:00»)، وعنوان الجلسة يأخذ الباقي.
min() وmax() وclamp()
تأخذ الدوال الرياضية قائمة من القيم، بأيّ خليط من الوحدات، وتُحسم إلى طول واحد وقت التخطيط:
.abstract {
width: min(100%, 40ch); /* ceiling: never wider than 40ch */
}
.page {
padding-inline: max(1rem, 4vw); /* floor: never less than 1rem */
}
.session-card {
padding: clamp(12px, 4%, 32px); /* between 12px and 32px, 4% in the middle */
}
.content {
width: min(100% - 2rem, 60rem); /* arithmetic works without calc() */
margin-inline: auto;
}min() تُرجع أصغر قيمة، وهذا يعني أنها تضع حدًّا أعلى. min(100%, 40ch) تساوي 40ch في البطاقة العريضة و100% في الضيّقة؛ فهي تستبدل زوج width وmax-width بتصريح واحد. و**max() تُرجع أكبر قيمة**، فتضع حدًّا أدنى: الهامش الجانبي للصفحة 4vw على الشاشات العريضة، لكنه لا يتقلّص أبدًا تحت 1rem على الهاتف.
clamp(MIN, PREFERRED, MAX) تجمع الاثنتين: تُرجع القيمة المفضّلة، لكن لا أقل من MIN ولا أكثر من MAX. وهي بالضبط max(MIN, min(PREFERRED, MAX)).
مع clamp(12px, 4%, 32px) تحصل البطاقة في عمود عرضه 300px على 12px من الـ padding، وفي عمود عرضه 500px على 20px، وكل ما هو أعرض من 800px يتوقّف عند 32px. النسب المئوية في الـ padding نسبةً إلى الحجم الأفقي للكتلة الحاوية، لذا تتبع مسافات البطاقة حاويتها لا الـ viewport.
وحدات تجعل الدوال الرياضية مفيدة
يجب أن تكون القيمة المفضّلة في clamp() شيئًا يتدرّج: نسبة مئوية، أو vw، أو وحدات الحاوية التي ستقابلها في درس الـ Container Queries. أما الحدود فيجب أن تكون وحدات مستقرّة مثل px أو rem. واستخدام rem للحدود له ميزة إضافية: إن رفع المستخدم حجم الخط الافتراضي لديه، تتدرّج الحدود معه.
وهذه أيضًا الحيلة وراء الحماية التي رأيتها في درس grid: minmax(min(180px, 100%), 1fr). داخل حاوية أضيق من 180px تختار min() القيمة 100%، فلا يفرض الـ track فيضانًا أبدًا.
دورك الآن
في التمرين بطاقة جلسة داخل غلاف تغيّر الفحوصات عرضه. حدّ الملخّص بـ 40ch دون أن يفيض في البطاقات الضيّقة، واجعل الشارة تحتضن نصّها، وأعطِ البطاقة padding يتدرّج بين 12px و32px. وبعدها ستجعل components كاملة تغيّر تخطيطها بحسب عرض حاويتها، باستخدام الـ container queries.
أهم النقاط
min-contentأضيق ما يمكن أن يكونه العنصر دون أن يفيض، وmax-contentعرضه دون أيّ التفاف، وfit-contentهي max-content محدودةً بالمساحة المتاحة.min()تختار أصغر قيمة، فتعمل كسقف:width: min(100%, 40ch)لا تتجاوز 40ch أبدًا ولا تفيض خارج حاويتها أبدًا.max()تعمل كأرضية، وclamp(MIN, PREFERRED, MAX)تُبقي القيمة المرنة بين حدّين.- الدوال الرياضية تقبل وحدات مختلطة وعمليات حسابية، لذا تعمل
min(100% - 2rem, 60rem)دونcalc()متداخلة.