양식 필드가 콘텐츠에 자동으로 맞춰짐

웹 기능: field-sizing

기본적으로 <input>, <textarea>, <select>와 같은 양식 컨트롤은 크기가 고정되어 있습니다. 사용자가 입력하거나 선택하는 콘텐츠의 양과 관계없이 크기가 일정하게 유지됩니다.

이러한 컨트롤이 콘텐츠 (자리표시자 포함)에 맞게 자동으로 축소되거나 확장되도록 하려면 field-sizing: content CSS 속성을 사용하세요.

양식 컨트롤 자동 크기 조절

입력, 선택 또는 텍스트 영역에 field-sizing: content를 설정하면 사용자가 입력하거나 옵션을 선택할 때 크기가 동적으로 조절됩니다. 하지만 강력한 사용자 환경을 보장하려면 상속된 스타일 지정, 레이아웃 기본값, 최소/최대 제약 조건을 고려해야 합니다.

레이아웃 문제를 방지하려면 텍스트 입력에서 field-sizing: content와 함께 min-inline-size (또는 min-width) 및 max-inline-size (또는 max-width)를 모두 설정하는 것이 좋습니다. 최소 크기는 입력란이 비어 있을 때 너비가 0으로 축소되어 클릭할 수 없게 되는 것을 방지하고, 최대 크기는 입력란이 무한정 확장되어 페이지 레이아웃이 깨지는 것을 방지합니다.

텍스트 영역의 경우 가로 자동 크기 조정을 허용하면 UX가 불편해질 수 있습니다 (예: 긴 플레이스홀더가 있는 텍스트 영역은 사용자가 한 글자를 입력하면 가로로 갑자기 축소됨). 이를 방지하려면 텍스트 영역에 명시적인 너비 (예: width: 100%)를 적용하세요. 이렇게 하면 텍스트 영역이 안정적인 가로 너비를 유지하면서 콘텐츠가 줄바꿈될 때 세로로 자동 크기 조절됩니다.

선택한 옵션이 너무 길어 페이지 레이아웃이 깨지지 않도록 field-sizing: content를 사용하여 <select> 요소에 max-inline-size (또는 max-width)를 설정하는 것이 좋습니다.

/* 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%로 설정하는 경우 자동 크기 조절이 작동하려면 field-sizing: content를 사용하여 요소에서 이를 width: auto (또는 width: fit-content)로 명시적으로 재설정해야 합니다. 반대로 이전에 고정 높이가 전역적으로 설정된 경우 텍스트 영역에 height: auto를 명시적으로 설정해야 합니다.

중요: 그리드 및 Flexbox 레이아웃은 사용 가능한 공간을 채우기 위해 하위 요소를 암시적으로 확장하는 경우가 많습니다. field-sizing: content를 사용하는 양식 컨트롤이 축소되지 않으면 컨테이너의 정렬 속성을 확인하고 양식 컨트롤에 align-self: start 또는 justify-self: start를 적용하여 확장을 재정의합니다.

대체 전략

field-sizing는 점진적 개선으로 취급해야 합니다. 이 속성을 지원하지 않는 브라우저에서는 양식 컨트롤이 기본 고정 크기 조절 동작으로 단계적으로 성능이 저하됩니다. 사용자는 고정 크기 입력 및 텍스트 영역 내에서 넘치는 콘텐츠에 대해 표준 스크롤을 경험하게 됩니다.

이전 브라우저에서 동적으로 확장되는 필드가 반드시 필요한 경우 기능 감지와 복잡한 해결 방법을 사용해야 합니다. 텍스트 영역에 가장 강력한 대체는 CSS 그리드 트릭을 사용하는 것입니다. 이 트릭에서는 숨겨진 가상 요소가 사용자의 입력을 실시간으로 미러링하여 그리드 컨테이너 (및 그 안의 텍스트 영역)를 강제로 확장합니다.

<!-- 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 노드 간에 스타일을 복제하고 상태를 동기화하는 복잡성을 고려할 때, 동적 크기 조절이 사용자 환경에 중요하지 않은 한 고정 입력의 기본 대체 동작을 사용하는 것이 대부분의 애플리케이션에 권장되는 접근 방식입니다.