Formuliervelden passen automatisch bij de content

Webfuncties: field-sizing

Standaard hebben formulierbedieningselementen zoals <input>, <textarea> en <select> vaste afmetingen. De grootte blijft constant, ongeacht de hoeveelheid content die de gebruiker invoert of selecteert.

Gebruik de CSS-property field-sizing: content om deze bedieningselementen automatisch te verkleinen of te vergroten zodat ze passen bij de content (inclusief tijdelijke aanduidingen).

Formulierbedieningselementen met automatische grootte

Als je field-sizing: content instelt voor invoer, selecties of tekstgebieden, kunnen ze dynamisch worden aangepast terwijl de gebruiker typt of opties selecteert. Houd wel rekening met overgenomen stijlen, standaardinstellingen voor de vormgeving en minimale/maximale beperkingen om een goede gebruikerservaring te bieden.

We raden je aan zowel min-inline-size (of min-width) als max-inline-size (of max-width) naast field-sizing: content in te stellen voor tekstinvoer om opmaakproblemen te voorkomen. Een minimumgrootte voorkomt dat de invoer wordt samengevouwen tot een breedte van nul als deze leeg is (waardoor deze niet kan worden aangeklikt). Een maximumgrootte zorgt ervoor dat de invoer niet onbeperkt wordt uitgebreid en de pagina-indeling wordt verbroken.

Als je horizontaal automatisch aanpassen toestaat voor tekstgebieden, kan dit een schokkende gebruikerservaring veroorzaken (een tekstgebied met een lange tijdelijke aanduiding wordt bijvoorbeeld abrupt horizontaal verkleind als de gebruiker één teken typt). Pas een expliciete breedte (zoals width: 100%) toe op het tekstgebied om dit te voorkomen. Hierdoor behoudt het tekstgebied een stabiele horizontale breedte, terwijl de verticale grootte automatisch wordt aangepast als de content wordt afgebroken.

We raden u aan een max-inline-size (of max-width) in te stellen voor <select>-elementen met field-sizing: content om te zorgen dat extreem lange geselecteerde opties de paginalay-out niet verstoren.

/* 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;
}

BELANGRIJK: Expliciete width- en height-eigenschappen overschrijven field-sizing: content voor alle formulierbedieningselementen. Als de algemene CSS van je project invoer, selecties of tekstgebieden instelt op width: 100%, moet je deze expliciet resetten naar width: auto (of width: fit-content) voor de elementen die field-sizing: content gebruiken om automatisch aanpassen te laten werken. Omgekeerd moet je height: auto expliciet instellen voor tekstgebieden als er eerder een vaste hoogte is ingesteld.

BELANGRIJK: Grid- en Flexbox-indelingen rekken hun onderliggende elementen vaak impliciet uit om de beschikbare ruimte te vullen. Als een formulierbeheerder die field-sizing: content gebruikt, weigert te verkleinen, controleer je de uitlijningseigenschappen van de container en pas je align-self: start of justify-self: start toe op de formulierbeheerder om het uitrekken te overschrijven.

Reservestrategieën

field-sizing moet worden behandeld als een progressive enhancement. In browsers die de property niet ondersteunen, vallen formulierbedieningselementen terug op hun standaard, vaste formaatgedrag. Gebruikers scrollen dan op de standaardmanier door content die niet in de invoervelden en tekstgebieden met een vaste grootte past.

Als dynamisch groeiende velden absoluut vereist zijn voor oudere browsers, moet u functieherkenning en een complexe tijdelijke oplossing gebruiken. De meest robuuste fallback voor tekstgebieden maakt gebruik van een CSS Grid-truc waarbij een verborgen pseudo-element de invoer van de gebruiker in realtime spiegelt, waardoor de gridcontainer (en het tekstgebied daarin) wordt uitgebreid.

<!-- 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;
  }
}

Vanwege de complexiteit van het dupliceren van stijlen en het synchroniseren van de status tussen DOM-nodes voor elk formulierbeheer, is het aanbevolen om te vertrouwen op het standaard fallback-gedrag van vaste invoer voor de meeste apps, tenzij dynamische grootte essentieel is voor de gebruikerservaring.