ملاءمة حقول النموذج للمحتوى تلقائيًا

ميزات الويب: field-sizing

وفقًا للإعدادات التلقائية، تكون عناصر التحكّم في النماذج، مثل <input> و<textarea> و<select>، ذات أبعاد ثابتة. تظل أحجامها ثابتة، بغض النظر عن كمية المحتوى الذي يدخله المستخدم أو يختاره.

للسماح لعناصر التحكّم هذه بالتقلّص أو التوسّع تلقائيًا لتناسب محتواها (بما في ذلك العناصر النائبة)، استخدِم سمة CSS‏ field-sizing: content.

عناصر تحكّم في النماذج ذات حجم تلقائي

يؤدي ضبط السمة field-sizing: content على حقول الإدخال أو القوائم المنسدلة أو مربّعات النص إلى السماح بتغيير حجمها ديناميكيًا أثناء كتابة المستخدم أو تحديده للخيارات. ومع ذلك، يجب مراعاة الأنماط الموروثة والإعدادات التلقائية للتنسيق والقيود الدنيا/القصوى لضمان تجربة مستخدم قوية.

لتجنُّب حدوث مشاكل في التنسيق، ننصح بضبط كل من min-inline-size (أو min-width) وmax-inline-size (أو max-width) إلى جانب field-sizing: content في حقول إدخال النص. يمنع الحد الأدنى للحجم حقل الإدخال من الانكماش إلى عرض صفر عندما يكون فارغًا (مما يجعله غير قابل للنقر)، ويضمن الحد الأقصى للحجم عدم توسعه إلى أجل غير مسمى وكسر تخطيط الصفحة.

بالنسبة إلى حقول textarea، قد يؤدي السماح بتغيير الحجم تلقائيًا أفقيًا إلى تجربة مستخدم مزعجة (على سبيل المثال، سيتقلّص حقل textarea الذي يحتوي على نص نائب طويل فجأة أفقيًا عندما يكتب المستخدم حرفًا واحدًا). لتجنُّب ذلك، يمكنك تطبيق عرض صريح (مثل width: 100%) على textarea. يؤدي ذلك إلى فرض الحفاظ على عرض أفقي ثابت لمساحة النص مع تغيير حجمها عموديًا تلقائيًا أثناء التفاف المحتوى.

ننصح بضبط max-inline-size (أو max-width) على عناصر <select> باستخدام field-sizing: content لضمان عدم تداخل الخيارات المحدّدة الطويلة جدًا مع تنسيق الصفحة.

/* Applies horizontal auto-sizing to inputs */
input {
  /* Instructs the element to size itself to fit its content */
  field-sizing: content;

  /* Reset explicit width if inherited from global styles */
  width: auto;

  /* Prevents the input from collapsing and disappearing when empty */
  min-inline-size: 15ch;

  /* Prevents infinite horizontal growth */
  max-inline-size: 50ch;
}

textarea {
  /* Instructs the element to size itself to fit its content */
  field-sizing: content;

  /* Reset explicit height if inherited from global styles */
  height: auto;

  /* Use a fixed width to prevent jarring horizontal shifts when replacing a long placeholder */
  width: 50ch; /* or 100% depending on your layout */

  /* Sets a reasonable minimum height (e.g., 3 lines) for empty textareas */
  min-block-size: 3lh;

  /* Prevents infinite vertical growth. Once a textarea hits this */
  /* height, it will stop growing and show a vertical scrollbar. */
  max-block-size: 10lh;
}

select {
  /* Sizes the select element to fit the active option only */
  field-sizing: content;

  /* Prevents the dropdown from expanding infinitely and breaking the layout */
  max-inline-size: 50ch;
}

ملاحظة مهمة: تلغي السمتان الصريحتان width وheight السمة field-sizing: content في جميع عناصر التحكّم في النماذج. إذا كانت لغة CSS العامة لمشروعك تضبط حقول الإدخال أو القوائم المنسدلة أو مربّعات النص على width: 100%، يجب إعادة ضبطها بشكل صريح على width: auto (أو width: fit-content) في العناصر التي تستخدم field-sizing: content لكي يعمل تغيير الحجم التلقائي. في المقابل، يجب ضبط height: auto بشكل صريح على مربّعات النص إذا تم ضبط ارتفاع ثابت مسبقًا على مستوى الموقع الإلكتروني.

ملاحظة مهمة: غالبًا ما تعمل تنسيقات Grid وFlexbox على تمديد العناصر الفرعية بشكل ضمني لملء المساحة المتاحة. إذا رفض أي عنصر تحكّم في النموذج يستخدم field-sizing: content التصغير، تحقَّق من خصائص محاذاة الحاوية وطبِّق align-self: start أو justify-self: start على عنصر التحكّم في النموذج لتجاوز التمديد.

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

يجب التعامل مع field-sizing كتحسين تدريجي. في المتصفّحات التي لا تتيح استخدام هذه السمة، تعود عناصر التحكّم في النماذج إلى سلوكها التلقائي في تغيير الحجم الثابت. سيتمكّن المستخدمون ببساطة من التمرير بشكل عادي في المحتوى الفائض داخل حقول الإدخال ومربّعات النص ذات الحجم الثابت.

إذا كانت الحقول التي تنمو ديناميكيًا مطلوبة تمامًا للمتصفحات القديمة، فيجب عليك استخدام اكتشاف الميزات وحل بديل معقد. يستخدم الحل البديل الأكثر فعالية لمربّعات النص حيلة CSS Grid حيث يعكس عنصر زائف مخفي إدخال المستخدم في الوقت الفعلي، ما يجبر حاوية الشبكة (ومربّع النص داخلها) على التوسّع.

<!-- The textarea is wrapped in a container that will mirror its value -->
<div class="growable-textarea" data-replicated-value="">
  <textarea></textarea>
</div>
// Only attach the fallback event listeners if field-sizing is unsupported
if (!CSS.supports('field-sizing', 'content')) {
  document.querySelectorAll('.growable-textarea > textarea').forEach(textarea => {
    textarea.addEventListener('input', () => {
      textarea.parentNode.dataset.replicatedValue = textarea.value;
    });
  });
}
/* Only apply the fallback if field-sizing is NOT supported */
@supports not (field-sizing: content) {
  .growable-textarea {
    display: grid;
  }

  /* The pseudo-element and textarea must share the exact same cell, font, and padding */
  .growable-textarea::after,
  .growable-textarea > textarea {
    grid-area: 1 / 1 / 2 / 2;
    font: inherit;
    padding: 0.5rem;
    border: 1px solid #999;
  }

  /* The pseudo-element renders the copied text invisibly to stretch the grid */
  .growable-textarea::after {
    /* The space is necessary for trailing empty lines to be rendered */
    content: attr(data-replicated-value) " ";
    white-space: pre-wrap;
    visibility: hidden;
  }

  .growable-textarea > textarea {
    resize: none;
    overflow: hidden;
  }
}

نظرًا لتعقيد تكرار الأنماط ومزامنة الحالة على مستوى عُقد DOM لكل عنصر تحكّم في النموذج، فإنّ الاعتماد على السلوك الاحتياطي التلقائي للإدخالات الثابتة هو النهج المقترَح لمعظم التطبيقات ما لم يكن الحجم الديناميكي مهمًا لتجربة المستخدم.