أسطر نصية متساوية العرض

ميزات الويب: text-fit text-wrap: balance text-box

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

بالنسبة إلى سطر واحد يملأ الحاوية (مثل عنوان أو اقتباس بارز)، يمكنك تطبيق text-fit على هذا العنصر مباشرةً. يتناول هذا الدليل مجموعات النصوص المتعددة الأسطر.

التنفيذ الأساسي

بالنسبة إلى الخطوط الإلزامية:

  • يجب تضمين كل سطر في <span> مع display: block.
  • تطبيق white-space: nowrap على كل سطر مفروض <span>

إرشادات التنفيذ:

  • استخدِم text-fit: grow per-line-all <percentage> في العنوان نفسه.
  • استخدِم per-line-all، وليس per-line. يتخطّى per-line السطر الأخير وأي سطر ينتهي بفاصل إجباري، لذا لا يتم تغيير حجم أي شيء في حال استخدام كتلة واحدة لكل سطر.
  • لا يمكن الجمع بين "grow" و"shrink". يمكنك ضبط السمة الأساسية font-size على الحد الأقصى أو الحد الأدنى حسب ما يكون أفضل كقيمة احتياطية أو أسهل في الاحتساب، وضبط السمة text-fit على shrink أو grow وفقًا لذلك. إذا لم يكن لديك سبب لاستخدام shrink، ننصحك باستخدام grow وضبط font-size على الحد الأدنى، لأنّ ذلك أكثر أمانًا في معظم الحالات.
  • يجب دائمًا وضع حدّ أقصى للزيادة أو النقصان باستخدام النسبة المئوية (مثلاً 300%) كإجراء وقائي.
  • يجب أن يكون للحاوية حجم مضمّن محدّد. لا يغيّر text-fit الحجم الجوهري أبدًا، لذا لا يؤثر في عرض fit-content/max-content أو عناصر flex/grid التي يتناسب حجمها مع المحتوى.
  • اقتطاع المسافة أعلى السطر الأول وأسفل السطر الأخير: راجع محاذاة النص الدقيقة.
  • يجب أن تكون قيمة line-height صغيرة، أي 1 أو أقل، وإلا ستصبح الفجوات بين الأسطر ذات أحجام الخطوط المختلفة غير ملائمة.
  • ملاحظة مُهمّة: يُرجى العِلم أنّ قيمة font-size المحسوبة لا تتغيّر، لذا لا يتم تغيير حجم تباعد em.
  • لتجنُّب التركيز الزائد على الأسطر المعزولة عن طريق الخطأ، يمكنك تطبيق text-wrap: balance أو text-wrap: pretty إذا كانت هناك أسطر فارغة.

المسافات

إذا تم فرض جميع الأسطر، سيؤدي ذلك إلى مزيد من التحكّم في التباعد:

  • طبِّق السمة text-box: trim-both cap alphabetic على كل مجموعة أسطر لكي يلتف المربع حول الرموز الخاصة به. ويتم الاقتصاص باستخدام المقاييس التي تم تغيير حجمها. لمزيد من التفاصيل، يُرجى الاطّلاع على محاذاة النص بدقة.
  • يجب استخدام Flexbox أو Grid + gap في العنوان لترك مسافات بين الأسطر، وليس line-height. وبالتالي، تصبح الفواصل موحّدة بدلاً من أن تزداد مع حجم خط كل سطر.

إذا كانت بعض الأسطر فارغة، لا تستخدِم text-box: لأنّه يقتطع السطرَين الأول والأخير فقط، وبالتالي ستلتصق الأسطر الخارجية بالرموز بينما تحتفظ الفجوات الداخلية بتباعدها. السماح لـ "line-height" بالتحكّم في جميع المسافات

التصميم المرئي

  • تبدو مجموعات النصوص أفضل عندما يكون هناك تباين كبير في أحجام الخطوط بين الأسطر. تجنَّب إنشاء مجموعات من نصوص ذات أسطر موحّدة في الغالب، لأنّ ذلك سيؤدي إلى أحجام خطوط غير متطابقة أو غير مختلفة بما يكفي، ما ينتهك مبدأ التصميم المتعلّق بالتباين. يمكنك ضمان ذلك من خلال فرض أسطر قصيرة: التفاف الكلمات للتأكيد في كتلة والسماح للباقي بالالتفاف، أي قفل مختلط. وهذا مهم بشكل خاص عند دمجها مع text-wrap: balance.
  • يُفضَّل دمج هذا مع text-transform: uppercase عند استخدامه مع النصوص الغربية، لأنّ الحروف الصاعدة والهابطة تميل إلى إنشاء مساحة محصورة و/أو تداخل الأسطر المجاورة، ما يؤدي إلى نتيجة أقل جاذبية من الناحية الجمالية.
  • عند فرض أسطر قصيرة، اختَر الكلمات التي من شأنها تحسين الرسالة إذا تم التركيز عليها.
  • القيود: سيؤدي تكبير النص أيضًا إلى زيادة وزنه المرئي وستبدو خطوطه أقوى. لا تتوفّر حاليًا طريقة لموازنة ذلك، مثلاً من خلال تقليل font-weight للنصوص الأكبر حجمًا، لأنّه ما مِن وحدة يمكن استخدامها في عملية حسابية، ولأنّ تغيير الحجم لا يؤثر في الوحدات المرتبطة بالخط، مثل em.

استراتيجيات احتياطية

لـ "text-box"

لا يحتاج text-box إلى عنصر احتياطي منفصل: يجب الاحتفاظ بعنصر line-height الصغير في عمليات القفل الثابتة أيضًا. لا يتم تنفيذ أي عملية في text-box، ويتم الحفاظ على الفجوات ضيقة في حال عدم توفّر هذه السمة، وذلك على حساب الفجوات التي يتم تغيير حجمها مع حجم خط كل سطر.

لـ "text-wrap: balance"

لـ "text-fit"

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

@supports not (text-fit: grow) {
  .lockup > span {
    /* Shrink-wrap each line so its width is the text width */
    width: fit-content;
    /* --text-fit-scale is measured by the script; the cap mirrors the text-fit percentage */
    font-size: min(var(--text-fit-scale, 1) * 1em, 300%);
  }
}
if (!CSS.supports('text-fit', 'grow per-line-all')) {
  const fit = lockup => {
    const lines = [...lockup.querySelectorAll(':scope > span')];
    // Unscale first: on a refit, offsetWidth would otherwise include the previous scale
    for (const line of lines) line.style.removeProperty('--text-fit-scale');
    // MANDATORY: all reads, then all writes. Interleaving them (e.g. reading
    // lockup.clientWidth inside the write loop) forces one reflow per line.
    const scales = lines.map(line => lockup.clientWidth / line.offsetWidth);
    lines.forEach((line, i) => line.style.setProperty('--text-fit-scale', scales[i]));
  };
  // Refit on resize and font load
  for (const lockup of document.querySelectorAll('.lockup')) {
    new ResizeObserver(() => fit(lockup)).observe(lockup);
  }
}

لا تتوفّر بدائل موثوقة للأسطر الحرة (لا يمكن معرفة فواصل الأسطر إلا بعد التنسيق): تحسين تدريجي لعنوان متوازن بحجم أساسي مرن مثل clamp(2rem, 1rem + 5cqi, 5rem). في الشعار المختلط، لا يزال النص أعلاه يتناسب مع الأسطر المفروضة، حيث يتم قياس كتلة الالتفاف بعرض الحاوية، لذلك يحافظ على المقياس 1 ويحصل فقط على حجم القاعدة المرن.

إذا كان من الضروري ملاءمة النص، ننصحك باستخدام مكتبة JS (مثل fitty)، يتم تحميلها بشكل مشروط فقط في حال عدم توفّر السمة text-fit.